public static TriangleInfo[] GetTriangles(MeshFilter filter) { Mesh mesh = filter.sharedMesh; if (mesh == null) { return(null); } Vector3[] vertices = mesh.vertices; int[] tris = mesh.triangles; TriangleInfo[] triangles = new TriangleInfo[tris.Length / 3]; for (int i = 0; i < tris.Length; i += 3) { Vector3 v1 = filter.transform.TransformPoint(vertices[tris[i]]); Vector3 v2 = filter.transform.TransformPoint(vertices[tris[i + 1]]); Vector3 v3 = filter.transform.TransformPoint(vertices[tris[i + 2]]); AABBBoundBox box = new AABBBoundBox(Vector3.positiveInfinity, Vector3.negativeInfinity); box.Extend(v1); box.Extend(v2); box.Extend(v3); triangles[i / 3] = new TriangleInfo { p1 = v1, p2 = v2, p3 = v3, }; } return(triangles); }
private void CreatePlacementModeBlocksAtLocations(List <Vector2> locations, List <TriangleInfo> triangles) { int ti = 0; for (int i = 0; i < locations.Count && i < selectedBlockCount; i++) { if (locations[i].y > Water.DrownLine && LevelBoundsGenerator.LevelBounds.Contains(locations[i])) { GameObject placementBlock = Instantiate(blockPrefab, locations[i], Quaternion.identity); placementBlock.transform.parent = blockParent.transform; Block b = placementBlock.AddComponent(_actualBlockType) as Block; b.PlacementModeInit(); if (triangles != null && triangles.Count > ti && locations[i] == triangles[ti].ConnectingBlockLocation) { TriangleInfo tinfo = triangles[ti]; Triangle placementTriangle = Instantiate(tinfo.IsHalfSlope ? halfTrianglePrefab : quarterTrianglePrefab, tinfo.Location, Quaternion.identity).GetComponent <Triangle>(); placementTriangle.TriangleInit(tinfo, b, BlocksInPlacement.Last()); placementTriangle.transform.parent = blockParent.transform; TrianglesInPlacement.Add(placementTriangle); ti++; } BlocksInPlacement.Add(b); } } }
private void GetTriangles(object obj) { MeshInfo meshInfo = (MeshInfo)obj; Vector3[] vertices = meshInfo.vertices; int[] tris = meshInfo.tris; TriangleInfo[] triangles = new TriangleInfo[tris.Length / 3]; for (int i = 0; i < tris.Length; i += 3) { Vector3 v1 = GetVertexWorldPosition(vertices[tris[i]], meshInfo.matrix); Vector3 v2 = GetVertexWorldPosition(vertices[tris[i + 1]], meshInfo.matrix); Vector3 v3 = GetVertexWorldPosition(vertices[tris[i + 2]], meshInfo.matrix); triangles[i / 3] = new TriangleInfo { p1 = v1, p2 = v2, p3 = v3, }; } lock (_locker) { for (int i = 0; i < triangles.Length; i++) { _triangleList.Add(triangles[i]); } _completeCount++; } }
private void computeTriangleForces(TriangleInfo triangleInfo) { NodeInfo node1Info = triangleInfo.Node1; NodeInfo node2Info = triangleInfo.Node2; NodeInfo node3Info = triangleInfo.Node3; // apply aerodynamic forces Vector3 triangle_velocity = (node1Info.Velocity + node2Info.Velocity + node3Info.Velocity) / 3f; triangle_velocity -= air_velocity; // calulate triangle normal using positions (uses cross product) // (r2 - r1) X (r3 - r1) Vector3 r2r1crossr3r1 = Vector3.Cross((node2Info.WorldPosition - node1Info.WorldPosition), (node3Info.WorldPosition - node1Info.WorldPosition)); Vector3 normal = r2r1crossr3r1 / r2r1crossr3r1.magnitude; // Vector3 aeroForce = 0.5f * density * dragCoefficient * triangle_velocity.sqrMagnitude * 0.5f * r2r1crossr3r1.magnitude * normal; Vector3 aeroForce = -0.5f * dragCoefficient * density * ((0.5f * Vector3.Dot(triangle_velocity, normal) * triangle_velocity.magnitude) / r2r1crossr3r1.magnitude) * r2r1crossr3r1; aeroForce /= 3f; node1Info.Force += aeroForce; node2Info.Force += aeroForce; node3Info.Force += aeroForce; }
private void calculate_Click(object sender, RoutedEventArgs e) { TriangleInfo triangleInfo = getInfo(); statusBarText.Text = triangleInfo.hasEnoughInfo ? "Has enough data" : "Has not enough data"; if (!triangleInfo.hasEnoughInfo) { return; } skipDataChange = true; if (triangleInfo.a != null && triangleInfo.b != null && triangleInfo.C != null) { Triangle triangle = new Triangle(new Length(triangleInfo.a.Value), new Length(triangleInfo.b.Value), new Angle(triangleInfo.C.Value)); AAngle.Text = triangle.AAngle.angle.ToString(); BAngle.Text = triangle.BAngle.angle.ToString(); CLength.Text = triangle.CLength.length.ToString(); } else if (triangleInfo.a != null && triangleInfo.B != null & triangleInfo.c != null) { Triangle triangle = new Triangle(new Length(triangleInfo.a.Value), new Angle(triangleInfo.B.Value), new Length(triangleInfo.c.Value)); AAngle.Text = triangle.AAngle.angle.ToString(); BLength.Text = triangle.BLength.length.ToString(); CAngle.Text = triangle.CAngle.angle.ToString(); } }
private void CheckMedianCentre(TriangleInfo info) { Vector2 median = info.triangle.MedianCentre(); Assert.AreEqual(info.expectedMedianCentre.x, median.x, MathConstant.EPSYLON); Assert.AreEqual(info.expectedMedianCentre.y, median.y, MathConstant.EPSYLON); }
public void CheckTringleById(string row, int column, int sideLength, string expected) { TriangleInfo triangle = new TriangleInfo(row, column, sideLength); Assert.True(triangle.IsValid); Assert.Equal(triangle.SVG, expected); }
public void TriangleInit(TriangleInfo ti, Block b1, Block b2) { info = ti; ConnectingBlock1 = b1; ConnectingBlock2 = b2; transform.localScale = new Vector2(ti.Scale.x * ti.DirectionX, ti.Scale.y); GlowColor = Color.white; }
public float DistanceToTarget(PlanetTriangle from, TriangleInfo to) { float distance = Vector3.Distance(from.RotatedMiddlePointOfTriangle + transform.position, to.position); float angle3 = Mathf.Acos(1 - Mathf.Pow(distance, 2) / (2 * Mathf.Pow(radius, 2))); float factor2 = angle3 / (Mathf.PI * 2); float circumference = 2 * Mathf.PI * radius; return(circumference * factor2); }
public ActionResult <TriangleInfo> GetById(string id, int sideLenght = 100) { var rowId = id[0].ToString(); int columnId = Convert.ToInt32(id.Substring(1)); var result = new TriangleInfo(rowId, columnId, sideLenght); return(result); }
private static void AddMesh(Mesh mesh, Material[] mats, Matrix4x4 trans) { Vector3[] v = mesh.vertices; Vector2[] uv = mesh.uv; //Debug.Log(v.Length + ":" + uv.Length); if (v.Length == 0) { return; //no verts wtf? } if (v.Length != uv.Length) { uv = new Vector2[v.Length]; //no uv's, fix yo model! } for (int i = 0; i < mesh.subMeshCount; i++) { Texture2D tex = mats[i].mainTexture as Texture2D; if (tex == null) { //Build a small solid color texture tex = new Texture2D(16, 16, TextureFormat.ARGB32, false); tex.filterMode = FilterMode.Point; Color32[] pixs = new Color32[16 * 16]; for (int p = 0; p < pixs.Length; p++) { pixs[p] = mats[i].color; } tex.SetPixels32(pixs); tex.Apply(); } if (!meshes.ContainsKey(tex)) { meshes.Add(tex, new List <TriangleInfo>()); } int[] idxs = mesh.GetIndices(i); for (int idx = 0; idx < idxs.Length; idx += 3) { TriangleInfo ti = new TriangleInfo(); ti.p1 = trans.MultiplyPoint(v[idxs[idx + 0]]); ti.p2 = trans.MultiplyPoint(v[idxs[idx + 1]]); ti.p3 = trans.MultiplyPoint(v[idxs[idx + 2]]); ti.uv1 = FixUV(uv[idxs[idx + 0]]); ti.uv2 = FixUV(uv[idxs[idx + 1]]); ti.uv3 = FixUV(uv[idxs[idx + 2]]); meshes[tex].Add(ti); } } }
bool Intersects(ref Ray ray, TriangleInfo triangleInfo, ref Matrix world) { Triangle triangleWorld; triangleInfo.CreateTriangleWorld(ref world, out triangleWorld); float?distance; triangleWorld.Intersects(ref ray, out distance); return(distance != null); }
public Vector4 Vertex(TriangleInfo triangle, int vertexIndex) { var vertexInfo = triangle[vertexIndex]; var uv = vertexInfo.UV; _varyingUV[vertexIndex] = uv; var vertex = vertexInfo.Vertex.ToVector4(); return(Transform.Multiply(vertex)); }
void RemoveTriangle(TriangleInfo triangle) { foreach (int vIndex in triangle.vertices) { vertices[vIndex].belongToTriangleIndex.Remove(triangle.index); } foreach (string eIndex in triangle.edges) { edges[eIndex].belongToTriangleIndex.Remove(triangle.index); } triangles.Remove(triangle.index); }
public TriangleInfo getInfo() { TriangleInfo info = new TriangleInfo(); info.a = (ALength.Text == "") ? (double?)null : double.Parse(ALength.Text); info.b = (BLength.Text == "") ? (double?)null : double.Parse(BLength.Text); info.c = (CLength.Text == "") ? (double?)null : double.Parse(CLength.Text); info.A = (AAngle.Text == "") ? (double?)null : double.Parse(AAngle.Text); info.B = (BAngle.Text == "") ? (double?)null : double.Parse(BAngle.Text); info.C = (CAngle.Text == "") ? (double?)null : double.Parse(CAngle.Text); return(info); }
public ActionResult <TriangleInfo> GetTriangleByVertices(int v1x, int v1y, int v2x, int v2y, int v3x, int v3y, int sideLenght = 100) { var result = new TriangleInfo(v1x, v1y, v2x, v2y, v3x, v3y, sideLenght); var result2 = new TriangleInfo(result.DisplayName[0].ToString(), Convert.ToInt32(result.DisplayName.Substring(1)), sideLenght); if (!result.Vertices.OrderBy(a => a.X).ThenBy(a => a.Y).SequenceEqual(result2.Vertices.OrderBy(a => a.X).ThenBy(a => a.Y))) { return(BadRequest("Given coordinates do not form valid triangle")); } return(result); }
public Vector4 Vertex(TriangleInfo triangle, int vertexIndex) { var vertexInfo = triangle[vertexIndex]; var normal = vertexInfo.Normal; var intensity = normal.Dot(Light); Vector3Extensions.Set(ref _varyingIntensity, vertexIndex) = intensity; var vertex = vertexInfo.Vertex.ToVector4(); return(Transform.Multiply(vertex)); }
public IActionResult Get( [FromRoute] TriangleInfo triangle) { var triangleAPI = new Triangle(new Vector2(triangle.Ax, triangle.Ay), new Vector2(triangle.Bx, triangle.By), new Vector2(triangle.Cx, triangle.Cy)); return(Ok(new LocationInfo( _contSvc.GetContainer(triangle.ContainerIdx).GetTriangleLocation(triangleAPI) ) ) ); }
public StickyBrush(BrushManager manager, SceneNode node) : base(manager, node) { var mesh = manager.LoadAsset <Mesh>("title:Resources/Meshes/Cube.json"); brushMesh = new BrushMesh("BrushMesh", manager.GraphicsDevice, mesh); brushMesh.Color = new Vector3(1, 0, 0); brushMesh.Alpha = 0.5f; Node.Objects.Add(brushMesh); triangleInfos = new TriangleInfo[2 * 6]; // 原点中心の立方体をブロックのグリッドへ移動させるための行列。 var transform = Matrix.CreateTranslation(new Vector3(0.5f)); int i = 0; for (int j = 0; j < Side.Count; j++) { var side = Side.Items[j]; var normal = side.Direction.ToVector3(); var side1 = new Vector3(normal.Y, normal.Z, normal.X); var side2 = Vector3.Cross(normal, side1); // (0,0,0) を原点に頂点を算出。 var v0 = (normal - side1 - side2) * 0.5f; var v1 = (normal - side1 + side2) * 0.5f; var v2 = (normal + side1 + side2) * 0.5f; var v3 = (normal + side1 - side2) * 0.5f; // ブロックのグリッドに移動。 Vector3.Transform(ref v0, ref transform, out v0); Vector3.Transform(ref v1, ref transform, out v1); Vector3.Transform(ref v2, ref transform, out v2); Vector3.Transform(ref v3, ref transform, out v3); triangleInfos[i] = new TriangleInfo(side) { Triangle = new Triangle(v0, v1, v2) }; triangleInfos[i + 1] = new TriangleInfo(side) { Triangle = new Triangle(v0, v2, v3) }; i += 2; } }
public StickyBrush(BrushManager manager, SceneNode node) : base(manager, node) { var mesh = manager.LoadAsset<Mesh>("title:Resources/Meshes/Cube.json"); brushMesh = new BrushMesh("BrushMesh", manager.GraphicsDevice, mesh); brushMesh.Color = new Vector3(1, 0, 0); brushMesh.Alpha = 0.5f; Node.Objects.Add(brushMesh); triangleInfos = new TriangleInfo[2 * 6]; // 原点中心の立方体をブロックのグリッドへ移動させるための行列。 var transform = Matrix.CreateTranslation(new Vector3(0.5f)); int i = 0; for (int j = 0; j < Side.Count; j++) { var side = Side.Items[j]; var normal = side.Direction.ToVector3(); var side1 = new Vector3(normal.Y, normal.Z, normal.X); var side2 = Vector3.Cross(normal, side1); // (0,0,0) を原点に頂点を算出。 var v0 = (normal - side1 - side2) * 0.5f; var v1 = (normal - side1 + side2) * 0.5f; var v2 = (normal + side1 + side2) * 0.5f; var v3 = (normal + side1 - side2) * 0.5f; // ブロックのグリッドに移動。 Vector3.Transform(ref v0, ref transform, out v0); Vector3.Transform(ref v1, ref transform, out v1); Vector3.Transform(ref v2, ref transform, out v2); Vector3.Transform(ref v3, ref transform, out v3); triangleInfos[i] = new TriangleInfo(side) { Triangle = new Triangle(v0, v1, v2) }; triangleInfos[i + 1] = new TriangleInfo(side) { Triangle = new Triangle(v0, v2, v3) }; i += 2; } }
public void Rebuild(BlockTileRenderer renderer, Dictionary <int, int> occupiedCells, int chunk_x, int chunk_y, float z_offset, int chunkEdgeSize, List <Vector3> vertices, List <Vector2> uvs, List <Color> colours, List <int> indices, SimHashes element) { vertices.Clear(); uvs.Clear(); triangles.Clear(); colours.Clear(); indices.Clear(); for (int i = chunk_y * chunkEdgeSize; i < chunk_y * chunkEdgeSize + chunkEdgeSize; i++) { for (int j = chunk_x * chunkEdgeSize; j < chunk_x * chunkEdgeSize + chunkEdgeSize; j++) { int num = i * Grid.WidthInCells + j; if (occupiedCells.ContainsKey(num)) { Color cellColour = renderer.GetCellColour(num, element); Bits decorConnectionBits = renderer.GetDecorConnectionBits(j, i, queryLayer); AddDecor(j, i, z_offset, decorConnectionBits, cellColour, vertices, uvs, triangles, colours); } } } if (vertices.Count > 0) { Mesh mesh = meshChunks[chunk_x, chunk_y]; if ((UnityEngine.Object)mesh == (UnityEngine.Object)null) { mesh = new Mesh(); mesh.name = "DecorRender"; meshChunks[chunk_x, chunk_y] = mesh; } triangles.Sort((TriangleInfo a, TriangleInfo b) => a.sortOrder.CompareTo(b.sortOrder)); for (int k = 0; k < triangles.Count; k++) { TriangleInfo triangleInfo = triangles[k]; indices.Add(triangleInfo.i0); TriangleInfo triangleInfo2 = triangles[k]; indices.Add(triangleInfo2.i1); TriangleInfo triangleInfo3 = triangles[k]; indices.Add(triangleInfo3.i2); } mesh.Clear(); mesh.SetVertices(vertices); mesh.SetUVs(0, uvs); mesh.SetColors(colours); mesh.SetTriangles(indices, 0); } else { meshChunks[chunk_x, chunk_y] = null; } }
public void Height_ShouldAcceptValue_WhenPositiveNumber() { // Arrange var height = _fixture.Create <double>(); // Act var triangle = new TriangleInfo { Height = height }; // Assert Assert.Equal(height, triangle.Height); }
public void Height_ShouldThrowException_WhenZeroOrNegativeNumber(int sign) { // Arrange var height = _fixture.Create <double>() * sign; // Act var triangle = new TriangleInfo(); Exception exception = Record.Exception(() => triangle.Height = height); // Assert Assert.NotNull(exception); Assert.IsType <ArgumentOutOfRangeException>(exception); }
public Vector4 Vertex(TriangleInfo triangle, int vertexIndex) { var a = triangle.Vertex0.Vertex; var b = triangle.Vertex1.Vertex; var c = triangle.Vertex2.Vertex; var normal = (c - a).Cross(b - a).Normalize(); _varyingIntensity = normal.Dot(Light); var vertex = triangle[vertexIndex].Vertex.ToVector4(); return(Transform.Multiply(vertex)); }
public void Base_ShouldAcceptValue_WhenPositiveNumber() { // Arrange var baseValue = _fixture.Create <double>(); // Act var triangle = new TriangleInfo { Base = baseValue }; // Assert Assert.Equal(baseValue, triangle.Base); }
public static bool AABBTriangle(AABBBoundBox aabb, TriangleInfo triange) { // 转换三角形顶点至以aabb的中心为原点的坐标系下 Vector3 v0 = triange.p1 - aabb.center; Vector3 v1 = triange.p2 - aabb.center; Vector3 v2 = triange.p3 - aabb.center; // 三角形边的向量形式 Vector3 f0 = v1 - v0; Vector3 f1 = v2 - v1; Vector3 f2 = v0 - v2; // AABB的法线 Vector3 u0 = new Vector3(1.0f, 0f, 0f); Vector3 u1 = new Vector3(0, 1.0f, 0); Vector3 u2 = new Vector3(0, 0, 1.0f); Vector3[] axiArray = new Vector3[] { // 叉积轴 Vector3.Cross(u0, f0), Vector3.Cross(u0, f1), Vector3.Cross(u0, f2), Vector3.Cross(u1, f0), Vector3.Cross(u1, f1), Vector3.Cross(u1, f2), Vector3.Cross(u2, f0), Vector3.Cross(u2, f1), Vector3.Cross(u2, f2), // AABB面法线 u0, u1, u2, // 三角形面法线 Vector3.Cross(f0, f1) }; for (int i = 0; i < axiArray.Length; i++) { // 判定该轴是不是一个分离轴 如果是的话可判定不相交 if (IsSeparateAxi(axiArray[i], aabb.half, v0, v1, v2)) { return(false); } } return(true); }
private TriangleInfo GetTestTriangle1() { TriangleInfo info = new TriangleInfo(); info.triangle = new Triangle2(new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0)); info.expectedSquare = 0.5; info.expectedMedianCentre = new Vector2(1.0 / 3.0, 1.0 / 3.0); info.expectedAB = new Vector2(0, 1); info.expectedBC = new Vector2(1, -1); info.expectedCA = new Vector2(-1, 0); info.angleA = MathConstant.PId2; info.angleB = MathConstant.PI / 4.0; info.angleC = MathConstant.PI / 4.0; return(info); }
public PlanetTriangle GetTriangleWithData(TriangleInfo triInfo) { Vector3 localPosition = triInfo.position - transform.position; PlanetTriangle result; if (levelOfDetail == 1) { result = mainTriangles.Where(t => t.RotatedNormal == triInfo.normal).First(); } else { IEnumerable <PlanetTriangle> tris = mainTriangles; do { result = ClosestTriangleAtSphericalPosition(tris, localPosition); tris = result.Children; } while (!result.IsLastParent); result = result.Children.Where(t => t.RotatedNormal == triInfo.normal).FirstOrDefault(); if (result == null) { // Debug.LogWarning("Couldnt find triangle with same normal. Searched in neighbors of closest."); result = ClosestTriangleAtSphericalPosition(tris, localPosition); PlanetTriangle normalInNeighbor = result.neighbors.Where(t => t.RotatedNormal == triInfo.normal).FirstOrDefault(); if (normalInNeighbor == null) { throw new System.Exception("Couldnt find triangle with hit normal!"); } else { result = normalInNeighbor; } } } return(result); }
public Vector4 Vertex(TriangleInfo triangle, int vertexIndex) { var vertexInfo = triangle[vertexIndex]; var uv = vertexInfo.UV; _varyingUV[vertexIndex] = uv; var normal = vertexInfo.Normal; normal = MIT.Multiply(normal); _varyingNormal[vertexIndex] = normal; var vertex = vertexInfo.Vertex.ToVector4(); vertex = Transform.Multiply(vertex); _varyingTrinagle[vertexIndex] = vertex.ToVector3(); return(vertex); }
TriangleInfo AddTriangle(VertexInfo[] verticesToAdd) { if (!IsRightOfVector(verticesToAdd [0], verticesToAdd [1], verticesToAdd [2])) { VertexInfo tmp = verticesToAdd[2]; verticesToAdd[2] = verticesToAdd[1]; verticesToAdd[1] = tmp; } TriangleInfo triangle = new TriangleInfo(); triangle.vertices = new List <int> (); triangle.edges = new List <string> (); triangle.index = TriangleInfo.nextIndex++; for (int i = 0; i < 3; i++) { triangle.vertices.Add(verticesToAdd[i].index); EdgeInfo edge = _AddEdge(verticesToAdd[i], verticesToAdd[(i + 1) % 3]); triangle.edges.Add(edge.GetSelfEdgeString()); edge.belongToTriangleIndex.Add(triangle.index); } triangles.Add(triangle.index, triangle); return(triangle); }
private void makeTriangle(NodeInfo node1, NodeInfo node2, NodeInfo node3) { TriangleInfo newTriangleInfo = new TriangleInfo(); newTriangleInfo.Node1 = node1; newTriangleInfo.Node2 = node2; newTriangleInfo.Node3 = node3; triangles.Add(newTriangleInfo); if (initTriangleRenderers == true) { GameObject nodeRender1 = (GameObject)Instantiate(debugRenderer, Vector3.zero, Quaternion.identity); LineDraw nodeDraw1 = nodeRender1.GetComponent <LineDraw>(); nodeDraw1.vertices.Add(node1.WorldPosition); nodeDraw1.vertices.Add(node2.WorldPosition); nodeDraw1.vertices.Add(node3.WorldPosition); nodeDraw1.vertices.Add(node1.WorldPosition); nodeDraw1.colorStart = Color.white; nodeDraw1.colorEnd = Color.green; nodeRender1.transform.parent = transform; } }
TriangleInfo AddTriangle(VertexInfo[] verticesToAdd) { if (!IsRightOfVector (verticesToAdd [0], verticesToAdd [1], verticesToAdd [2])) { VertexInfo tmp = verticesToAdd[2]; verticesToAdd[2] = verticesToAdd[1]; verticesToAdd[1] = tmp; } TriangleInfo triangle = new TriangleInfo(); triangle.vertices = new List<int> (); triangle.edges = new List<string> (); triangle.index = TriangleInfo.nextIndex++; for (int i = 0; i<3; i++) { triangle.vertices.Add(verticesToAdd[i].index); EdgeInfo edge = _AddEdge (verticesToAdd[i], verticesToAdd[(i+1)%3]); triangle.edges.Add(edge.GetSelfEdgeString()); edge.belongToTriangleIndex.Add (triangle.index); } triangles.Add (triangle.index, triangle); return triangle; }
void RemoveTriangle(TriangleInfo triangle) { foreach (int vIndex in triangle.vertices) { vertices[vIndex].belongToTriangleIndex.Remove(triangle.index); } foreach (string eIndex in triangle.edges) { edges[eIndex].belongToTriangleIndex.Remove(triangle.index); } triangles.Remove (triangle.index); }
public virtual void ProcessTriangle(IndexedVector3[] triangle, int partId, int triangleIndex) { //skip self-collisions if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex)) { return; } //skip duplicates (disabled for now) //if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex)) // return; //search for shared vertices and edges int numshared = 0; int[] sharedVertsA = new int[] { -1, -1, -1 }; int[] sharedVertsB = new int[] { -1, -1, -1 }; ///skip degenerate triangles float crossBSqr = IndexedVector3.Cross((triangle[1] - triangle[0]), (triangle[2] - triangle[0])).LengthSquared(); if (crossBSqr < m_triangleInfoMap.m_equalVertexThreshold) { return; } float crossASqr = IndexedVector3.Cross((m_triangleVerticesA[1] - m_triangleVerticesA[0]), (m_triangleVerticesA[2] - m_triangleVerticesA[0])).LengthSquared(); ///skip degenerate triangles if (crossASqr < m_triangleInfoMap.m_equalVertexThreshold) { return; } #if false printf("triangle A[0] = (%f,%f,%f)\ntriangle A[1] = (%f,%f,%f)\ntriangle A[2] = (%f,%f,%f)\n", m_triangleVerticesA[0].GetX(),m_triangleVerticesA[0].GetY(),m_triangleVerticesA[0].GetZ(), m_triangleVerticesA[1].GetX(),m_triangleVerticesA[1].GetY(),m_triangleVerticesA[1].GetZ(), m_triangleVerticesA[2].GetX(),m_triangleVerticesA[2].GetY(),m_triangleVerticesA[2].GetZ()); printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex); printf("triangle B[0] = (%f,%f,%f)\ntriangle B[1] = (%f,%f,%f)\ntriangle B[2] = (%f,%f,%f)\n", triangle[0].GetX(),triangle[0].GetY(),triangle[0].GetZ(), triangle[1].GetX(),triangle[1].GetY(),triangle[1].GetZ(), triangle[2].GetX(),triangle[2].GetY(),triangle[2].GetZ()); #endif for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if ((m_triangleVerticesA[i] - triangle[j]).LengthSquared() < m_triangleInfoMap.m_equalVertexThreshold) { sharedVertsA[numshared] = i; sharedVertsB[numshared] = j; numshared++; ///degenerate case if (numshared >= 3) { return; } } } ///degenerate case if (numshared >= 3) { return; } } switch (numshared) { case 0: { break; } case 1: { //shared vertex break; } case 2: { //shared edge //we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2) { sharedVertsA[0] = 2; sharedVertsA[1] = 0; int tmp = sharedVertsB[1]; sharedVertsB[1] = sharedVertsB[0]; sharedVertsB[0] = tmp; } int hash = GetHash(m_partIdA, m_triangleIndexA); TriangleInfo info = null; if (m_triangleInfoMap.ContainsKey(hash)) { info = m_triangleInfoMap[hash]; } else { info = new TriangleInfo(); m_triangleInfoMap[hash] = info; } int sumvertsA = sharedVertsA[0] + sharedVertsA[1]; int otherIndexA = 3 - sumvertsA; IndexedVector3 edge = new IndexedVector3(m_triangleVerticesA[sharedVertsA[1]] - m_triangleVerticesA[sharedVertsA[0]]); TriangleShape tA = new TriangleShape(m_triangleVerticesA[0], m_triangleVerticesA[1], m_triangleVerticesA[2]); int otherIndexB = 3 - (sharedVertsB[0] + sharedVertsB[1]); TriangleShape tB = new TriangleShape(triangle[sharedVertsB[1]], triangle[sharedVertsB[0]], triangle[otherIndexB]); //btTriangleShape tB(triangle[0],triangle[1],triangle[2]); IndexedVector3 normalA; IndexedVector3 normalB; tA.CalcNormal(out normalA); tB.CalcNormal(out normalB); edge.Normalize(); IndexedVector3 edgeCrossA = IndexedVector3.Normalize(IndexedVector3.Cross(edge, normalA)); { IndexedVector3 tmp = m_triangleVerticesA[otherIndexA] - m_triangleVerticesA[sharedVertsA[0]]; if (IndexedVector3.Dot(edgeCrossA, tmp) < 0) { edgeCrossA *= -1; } } IndexedVector3 edgeCrossB = IndexedVector3.Cross(edge, normalB).Normalized(); { IndexedVector3 tmp = triangle[otherIndexB] - triangle[sharedVertsB[0]]; if (IndexedVector3.Dot(edgeCrossB, tmp) < 0) { edgeCrossB *= -1; } } float angle2 = 0; float ang4 = 0.0f; IndexedVector3 calculatedEdge = IndexedVector3.Cross(edgeCrossA, edgeCrossB); float len2 = calculatedEdge.LengthSquared(); float correctedAngle = 0f; IndexedVector3 calculatedNormalB = normalA; bool isConvex = false; if (len2 < m_triangleInfoMap.m_planarEpsilon) { angle2 = 0.0f; ang4 = 0.0f; } else { calculatedEdge.Normalize(); IndexedVector3 calculatedNormalA = IndexedVector3.Cross(calculatedEdge, edgeCrossA); calculatedNormalA.Normalize(); angle2 = GetAngle(ref calculatedNormalA, ref edgeCrossA, ref edgeCrossB); ang4 = MathUtil.SIMD_PI - angle2; float dotA = IndexedVector3.Dot(normalA, edgeCrossB); ///@todo: check if we need some epsilon, due to floating point imprecision isConvex = (dotA < 0f); correctedAngle = isConvex ? ang4 : -ang4; IndexedQuaternion orn2 = new IndexedQuaternion(calculatedEdge, -correctedAngle); IndexedMatrix rotateMatrix = IndexedMatrix.CreateFromQuaternion(orn2); calculatedNormalB = new IndexedBasisMatrix(orn2) * normalA; } //alternatively use //IndexedVector3 calculatedNormalB2 = quatRotate(orn,normalA); switch (sumvertsA) { case 1: { IndexedVector3 edge1 = m_triangleVerticesA[0] - m_triangleVerticesA[1]; IndexedQuaternion orn = new IndexedQuaternion(edge1, -correctedAngle); IndexedVector3 computedNormalB = MathUtil.QuatRotate(orn, normalA); float bla = IndexedVector3.Dot(computedNormalB, normalB); if (bla < 0) { computedNormalB *= -1; info.m_flags |= TriangleInfoMap.TRI_INFO_V0V1_SWAP_NORMALB; } #if DEBUG_INTERNAL_EDGE if ((computedNormalB - normalB).Length() > 0.0001f) { System.Console.WriteLine("warning: normals not identical"); } #endif//DEBUG_INTERNAL_EDGE info.m_edgeV0V1Angle = -correctedAngle; if (isConvex) { info.m_flags |= TriangleInfoMap.TRI_INFO_V0V1_CONVEX; } break; } case 2: { IndexedVector3 edge1 = m_triangleVerticesA[2] - m_triangleVerticesA[0]; IndexedQuaternion orn = new IndexedQuaternion(edge1, -correctedAngle); IndexedVector3 computedNormalB = MathUtil.QuatRotate(orn, normalA); if (IndexedVector3.Dot(computedNormalB, normalB) < 0) { computedNormalB *= -1; info.m_flags |= TriangleInfoMap.TRI_INFO_V2V0_SWAP_NORMALB; } #if DEBUG_INTERNAL_EDGE if ((computedNormalB - normalB).Length() > 0.0001) { System.Console.WriteLine("warning: normals not identical"); } #endif //DEBUG_INTERNAL_EDGE info.m_edgeV2V0Angle = -correctedAngle; if (isConvex) info.m_flags |= TriangleInfoMap.TRI_INFO_V2V0_CONVEX; break; } case 3: { IndexedVector3 edge1 = m_triangleVerticesA[1] - m_triangleVerticesA[2]; IndexedQuaternion orn = new IndexedQuaternion(edge1, -correctedAngle); IndexedVector3 computedNormalB = MathUtil.QuatRotate(orn, normalA); if (IndexedVector3.Dot(computedNormalB, normalB) < 0) { info.m_flags |= TriangleInfoMap.TRI_INFO_V1V2_SWAP_NORMALB; computedNormalB *= -1; } #if DEBUG_INTERNAL_EDGE if ((computedNormalB - normalB).Length() > 0.0001) { System.Console.WriteLine("warning: normals not identical"); } #endif //DEBUG_INTERNAL_EDGE info.m_edgeV1V2Angle = -correctedAngle; if (isConvex) { info.m_flags |= TriangleInfoMap.TRI_INFO_V1V2_CONVEX; } break; } } break; } default: { // printf("warning: duplicate triangle\n"); break; } } }
bool Intersects(ref Ray ray, TriangleInfo triangleInfo, ref Matrix world) { Triangle triangleWorld; triangleInfo.CreateTriangleWorld(ref world, out triangleWorld); float? distance; triangleWorld.Intersects(ref ray, out distance); return distance != null; }
public bool Compare(TriangleInfo p) { return p.Sum(ref vertices)[dim] < pMid; }