public void GenerateAt(int x, int y) { int corners = 0; for (int i = 0; i < 4; i++) { if (Sampler.Sample(new Vector2(x + i % 2, y + i / 2)) < 0) corners |= 1 << i; } if (corners == 0 || corners == 15) return; int v_count = MarchingSquaresTableGenerator.CaseTable[corners].Count; for (int i = 0; i < v_count; i++) { int e1 = MarchingSquaresTableGenerator.CaseTable[corners].Edges[i].First; int e2 = MarchingSquaresTableGenerator.CaseTable[corners].Edges[i].Second; Vector2 e1p = new Vector2((x + e1 / 2) * Size, (y + e1 % 2) * Size); Vector2 e2p = new Vector2((x + e2 / 2) * Size, (y + e2 % 2) * Size); Vector2 v1p = Sampler.GetIntersection(e1p, e2p, Sampler.Sample(e1p), Sampler.Sample(e2p)); } cells[x, y].VertexCount = v_count; GenerateGrid(x, y); }
public Vector3 GetIntersection() { return(Sampler.GetIntersection(A, B, ValueA, ValueB)); }
public void GenerateAt(int x, int y) { int corners = 0; for (int i = 0; i < 4; i++) { if (map[x + i / 2, y + i % 2] < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 15) { return; } VertexPositionColor[] vs = new VertexPositionColor[10]; Color c = Color.LightSteelBlue; vs[0] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 0) * Size, 0), c); vs[1] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 0) * Size, 0), c); vs[2] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 0) * Size, 0), c); vs[3] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 1) * Size, 0), c); vs[4] = new VertexPositionColor(new Vector3((x + 1) * Size, (y + 1) * Size, 0), c); vs[5] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 1) * Size, 0), c); vs[6] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 1) * Size, 0), c); vs[7] = new VertexPositionColor(new Vector3((x + 0) * Size, (y + 0) * Size, 0), c); OutlineBuffer.SetData <VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 8, VertexPositionColor.VertexDeclaration.VertexStride); OutlineLocation += 8; QEF qef = new QEF(); Vector3 average_normal = new Vector3(); for (int i = 0; i < 4; i++) { int c1 = edges[i, 0]; int c2 = edges[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = map[x + c1 / 2, y + c1 % 2]; float d2 = map[x + c2 / 2, y + c2 % 2]; Vector2 p1 = new Vector2((float)((c1 / 2)), (float)((c1 % 2))); Vector2 p2 = new Vector2((float)((c2 / 2)), (float)((c2 % 2))); Vector2 intersection = Sampler.GetIntersection(p1, p2, d1, d2); Vector2 normal = Sampler.GetNormal(intersection + new Vector2(x, y)); //GetNormal(x, y); average_normal += new Vector3(normal, 0); qef.Add(intersection, normal); } average_normal /= (float)qef.Intersections.Count; average_normal.Normalize(); vertices[x, y] = qef.Solve2(0, 16, 0); Vector2 p = vertices[x, y]; Color n_c = new Color(average_normal * 0.5f + Vector3.One * 0.5f); VertexPositionColorNormal v = new VertexPositionColorNormal(new Vector3((p.X + x) * Size, (p.Y + y) * Size, 0), n_c, average_normal); Vertices.Add(v); vertex_indexes[x, y] = VertexCount; VertexCount++; }
public void GenerateAt(int x, int y, int z) { int corners = 0; for (int i = 0; i < 8; i++) { if (map[x + i / 4, y + i % 4 / 2, z + i % 2] < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 255) { return; } VertexPositionColor[] vs = new VertexPositionColor[24]; Color c = Color.LightSteelBlue; vs[0] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[1] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[2] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[3] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[4] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[5] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[6] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[7] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[8] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[9] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[10] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[11] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); vs[12] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); vs[13] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[14] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[15] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[16] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 0)), c); vs[17] = new VertexPositionColor(new Vector3((x + 0), (y + 0), (z + 1)), c); vs[18] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 0)), c); vs[19] = new VertexPositionColor(new Vector3((x + 0), (y + 1), (z + 1)), c); vs[20] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 0)), c); vs[21] = new VertexPositionColor(new Vector3((x + 1), (y + 0), (z + 1)), c); vs[22] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 0)), c); vs[23] = new VertexPositionColor(new Vector3((x + 1), (y + 1), (z + 1)), c); OutlineBuffer.SetData <VertexPositionColor>(OutlineLocation * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, 24, VertexPositionColor.VertexDeclaration.VertexStride); OutlineLocation += 24; QEF3D qef = new QEF3D(); Vector3 average_normal = new Vector3(); for (int i = 0; i < 12; i++) { int c1 = edges[i, 0]; int c2 = edges[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = map[x + c1 / 4, y + c1 % 4 / 2, z + c1 % 2]; float d2 = map[x + c2 / 4, y + c2 % 4 / 2, z + c2 % 2]; Vector3 p1 = new Vector3((float)((c1 / 4)), (float)((c1 % 4 / 2)), (float)((c1 % 2))); Vector3 p2 = new Vector3((float)((c2 / 4)), (float)((c2 % 4 / 2)), (float)((c2 % 2))); Vector3 intersection = Sampler.GetIntersection(p1, p2, d1, d2); Vector3 normal = Sampler.GetNormal(intersection + new Vector3(x, y, z)); //GetNormal(x, y); average_normal += normal; qef.Add(intersection, normal); } Vector3 p = qef.Solve2(0, 16, 0); Vector3 n = average_normal / (float)qef.Intersections.Count; VertexPositionColorNormal[] v2 = new VertexPositionColorNormal[1]; Vector3 c_v = n * 0.5f + Vector3.One * 0.5f; c_v.Normalize(); Color clr = new Color(c_v); v2[0] = new VertexPositionColorNormal(new Vector3((p.X + x), (p.Y + y), (p.Z + z)), clr, n); VertexBuffer.SetData <VertexPositionColorNormal>(VertexCount * VertexPositionColorNormal.VertexDeclaration.VertexStride, v2, 0, 1, VertexPositionColorNormal.VertexDeclaration.VertexStride); vertex_indexes[x, y, z] = VertexCount; VertexCount++; /*vs[0] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black); * vs[1] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black); * vs[2] = new VertexPositionColor(new Vector3((x + 1) , (y + 0) , 0), Color.Black); * vs[3] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black); * vs[4] = new VertexPositionColor(new Vector3((x + 1) , (y + 1) , 0), Color.Black); * vs[5] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black); * vs[6] = new VertexPositionColor(new Vector3((x + 0) , (y + 1) , 0), Color.Black); * vs[7] = new VertexPositionColor(new Vector3((x + 0) , (y + 0) , 0), Color.Black); * * vs[8] = new VertexPositionColor(new Vector3((p.X + x) , (p.Y + y) , 0), Color.Black); * vs[9] = new VertexPositionColor(new Vector3((p.X + x + .1f) , (p.Y + y + .1f) , 0), Color.Black); * index = 10; * * VertexBuffer.SetData<VertexPositionColor>(VertexCount * VertexPositionColor.VertexDeclaration.VertexStride, vs, 0, index, VertexPositionColor.VertexDeclaration.VertexStride); * VertexCount += index;*/ }
public bool ConstructLeaf(ref List <VertexPositionColorNormalNormal> vertices, ref int index) { if (size != 1) { return(false); } this.index = index++; type = NodeType.Leaf; int corners = 0; float[] samples = new float[8]; for (int i = 0; i < 8; i++) { if ((samples[i] = Sampler.Sample(position + Utilities.TCornerDeltas[i])) < 0) { corners |= 1 << i; } } this.corners = (byte)corners; if (corners == 0 || corners == 255) { return(false); } int[][] v_edges = new int[Utilities.TransformedVerticesNumberTable[corners]][]; this.vertices = new Vertex[Utilities.TransformedVerticesNumberTable[corners]]; int v_index = 0; int e_index = 0; v_edges[0] = new int[] { -1, -1, -1, -1, -1, -1, -1, -1 }; for (int e = 0; e < 16; e++) { int code = Utilities.TransformedEdgesTable[corners, e]; if (code == -2) { v_index++; break; } if (code == -1) { v_index++; e_index = 0; v_edges[v_index] = new int[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; continue; } v_edges[v_index][e_index++] = code; } if (v_index > 1) { } for (int i = 0; i < v_index; i++) { int k = 0; this.vertices[i] = new Vertex(); this.vertices[i].qef = new QEFProper.QEFSolver(); Vector3 normal = Vector3.Zero; int[] ei = new int[12]; if (this.position.X == 6 && this.position.Y == 0 && this.position.Z == 3) { } while (v_edges[i][k] != -1) { ei[v_edges[i][k]] = 1; Vector3 a = position + Utilities.TCornerDeltas[Utilities.TEdgePairs[v_edges[i][k], 0]] * size; Vector3 b = position + Utilities.TCornerDeltas[Utilities.TEdgePairs[v_edges[i][k], 1]] * size; Vector3 intersection = Sampler.GetIntersection(a, b, samples[Utilities.TEdgePairs[v_edges[i][k], 0]], samples[Utilities.TEdgePairs[v_edges[i][k], 1]]); Vector3 n = Sampler.GetNormal(intersection); normal += n; this.vertices[i].qef.Add(intersection, n); k++; } normal /= (float)k; normal.Normalize(); this.vertices[i].index = vertices.Count; this.vertices[i].parent = null; this.vertices[i].collapsible = true; this.vertices[i].normal = normal; this.vertices[i].euler = 1; this.vertices[i].eis = ei; this.vertices[i].in_cell = this.child_index; this.vertices[i].face_prop2 = true; if (this.index == 1028) { } this.vertices[i].qef.Solve(1e-6f, 4, 1e-6f); this.vertices[i].error = this.vertices[i].qef.GetError(); //VertexPositionColorNormalNormal vert = new VertexPositionColorNormalNormal(); //vert.Position = this.vertices[i].qef.Solve(1e-6f, 4, 1e-6f) + position; //vert.Normal = Sampler.GetNormal(vert.Position); //vert.Color = new Color(vert.Normal * 0.5f + Vector3.One * 0.5f); //vertices.Add(vert); } for (int i = 0; i < this.vertices.Length; i++) { if (this.vertices[i] == null) { } } return(true); }
/* The following code is more or less a copy/paste cleanup of the C++ implementation * It's not clean, or efficient, but it works and is fairly straightforward */ public bool ConstructLeaf(List <VertexPositionColorNormal> vertices, int grid_size) { if (size != 1) { return(false); } int corners = 0; float[, ,] samples = new float[2, 2, 2]; for (int i = 0; i < 8; i++) { if ((samples[i / 4, i % 4 / 2, i % 2] = Sampler.Sample(position + new Vector3(i / 4, i % 4 / 2, i % 2))) < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 255) { return(false); } //type = OctreeNodeType.Leaf; //return true; QEF3D qef = new QEF3D(); QEFProper.QEFSolver qefp = new QEFProper.QEFSolver(); Vector3 average_normal = Vector3.Zero; for (int i = 0; i < 12; i++) { int c1 = edgevmap[i, 0]; int c2 = edgevmap[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = samples[c1 / 4, c1 % 4 / 2, c1 % 2]; float d2 = samples[c2 / 4, c2 % 4 / 2, c2 % 2]; Vector3 p1 = new Vector3((float)((c1 / 4)), (float)((c1 % 4 / 2)), (float)((c1 % 2))); Vector3 p2 = new Vector3((float)((c2 / 4)), (float)((c2 % 4 / 2)), (float)((c2 % 2))); Vector3 intersection = Sampler.GetIntersection(p1, p2, d1, d2) + position; Vector3 normal = Sampler.GetNormal(intersection); //GetNormal(x, y); average_normal += normal; qef.Add(intersection, normal); qefp.Add(intersection, normal); } Vector3 n = average_normal / (float)qef.Intersections.Count; n.Normalize(); draw_info = new OctreeDrawInfo(); //draw_info.position = position + qef.Solve2(0, 0, 0); draw_info.position = qefp.Solve(1e-6f, 4, 1e-6f); draw_info.corners = corners; draw_info.averageNormal = n; draw_info.qef = qefp; //vertices.Add(new VertexPositionColorNormal(position + draw_info.position, Color.LightGreen, n)); type = OctreeNodeType.Leaf; return(true); }
/* TODO: Use the cached sampled value once it's properly calculated! */ private Vector2 GetPosition(int a, int b) { return(Sampler.GetIntersection(Positions[a], Positions[b], Sampler.Sample(Positions[a]), Sampler.Sample(Positions[b]), 0)); }
public bool ConstructLeaf(ref int v_index, List <VertexPositionColorNormal> vertices, int grid_size) { int corners = 0; float[,] samples = new float[2, 2]; for (int i = 0; i < 4; i++) { if ((samples[i / 2, i % 2] = Sampler.Sample(position + new Vector2(i / 2, i % 2))) < 0) { corners |= 1 << i; } } if (corners == 0 || corners == 15) { return(false); } QEF qef = new QEF(); Vector3 average_normal = new Vector3(); for (int i = 0; i < 4; i++) { int c1 = Sampler.Edges[i, 0]; int c2 = Sampler.Edges[i, 1]; int m1 = (corners >> c1) & 1; int m2 = (corners >> c2) & 1; if (m1 == m2) { continue; } float d1 = samples[c1 / 2, c1 % 2]; float d2 = samples[c2 / 2, c2 % 2]; Vector2 p1 = new Vector2((float)((c1 / 2)), (float)((c1 % 2))); Vector2 p2 = new Vector2((float)((c2 / 2)), (float)((c2 % 2))); Vector2 intersection = Sampler.GetIntersection(p1, p2, d1, d2); Vector2 normal = Sampler.GetNormal(intersection + position); //GetNormal(x, y); average_normal += new Vector3(normal, 0); qef.Add(intersection, normal); } average_normal /= (float)qef.Intersections.Count; average_normal.Normalize(); draw_info = new QuadtreeDrawInfo(); draw_info.position = qef.Solve2(0, 0, 0); draw_info.averageNormal = average_normal; draw_info.corners = corners; draw_info.index = v_index++; Color n_c = new Color(average_normal * 0.5f + Vector3.One * 0.5f); vertices.Add(new VertexPositionColorNormal(new Vector3(position * grid_size + draw_info.position * size * grid_size, 0), n_c, average_normal)); type = QuadtreeNodeType.Leaf; return(true); }