public void CreateQuad(Entity e, float3 org, RectangleRenderState rectangleRenderState, RectTransformResult rRes) { var indices = EntityManager.GetBuffer <DynamicIndex>(e); var vertices = EntityManager.GetBuffer <DynamicSimpleVertex>(e); vertices.ResizeUninitialized(4); indices.ResizeUninitialized(6); float2 size = rRes.Size; float4 outer = rectangleRenderState.Outer; for (int j = 0; j < 2; ++j) { for (int i = 0; i < 2; ++i) { float x = size.x * i; float y = size.y * j; SimpleVertex sv = new SimpleVertex { Position = new float3(x, y, org.z), Color = new float4(1, 1, 1, 1), TexCoord0 = new float2(i == 0 ? outer.x : outer.z, j == 0 ? outer.w : outer.y) }; vertices[j * 2 + i] = new DynamicSimpleVertex() { Value = sv }; } } indices[0] = new DynamicIndex() { Value = 0 }; indices[1] = new DynamicIndex() { Value = 3 }; indices[2] = new DynamicIndex() { Value = 1 }; indices[3] = new DynamicIndex() { Value = 0 }; indices[4] = new DynamicIndex() { Value = 2 }; indices[5] = new DynamicIndex() { Value = 3 }; AddMeshRendererComponents(e, vertices.Length, indices.Length, vertices.AsNativeArray().Reinterpret <DynamicSimpleVertex, SimpleVertex>()); }
public static SimpleVertex <T, TEdge> AddVertex <T, TEdge>(this Graph <T, SimpleVertex <T, TEdge>, TEdge> graph, T value) where TEdge : Edge <T> { var v = new SimpleVertex <T, TEdge>(value); graph.AddVertex(v); return(v); }
public void DrawLineColored(Color4 color, Vector2 p0, Vector2 p1) { device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse; SimpleVertex[] verts = new SimpleVertex[] { new SimpleVertex(new Vector3(p0, 0), color.ToArgb()), new SimpleVertex(new Vector3(p1, 0), color.ToArgb()) }; SetupTexture(null); device.DrawUserPrimitives <SimpleVertex>(PrimitiveType.LineList, 1, verts); }
// NB: vertexColor needs to be as srgb when in gamma space, and in linear otherwise public static unsafe void LayoutString <T1, T2>(char *text, int textLength, float fontSize, HorizontalAlignment hAlign, VerticalAlignment vAlign, float4 vertexColor, ref FontData font, T1 mesh, T2 triangles, out AABB aabb) where T1 : INativeList <SimpleVertex> where T2 : INativeList <ushort> { // TODO -- unicode code points may map to 0..N glyphs. We just assume 1:1 right now because we're not shaping int *glyphIndices = stackalloc int[textLength]; // figure out the glyph indices int gi = 0; for (int ci = 0; ci < textLength; ci++) { var charUnicode = text[ci]; int glyphIndex = font.FindGlyphIndexForCodePoint(charUnicode); // TODO handle tofu if (glyphIndex == -1) { continue; } glyphIndices[gi++] = glyphIndex; } int numGlyphs = gi; // font base calcs bool isOrtho = false; // ??? float baseScale = fontSize / font.Face.PointSize * font.Face.Scale * (isOrtho ? 1 : 0.1f); float currentElementScale = baseScale; // allocate space in the mesh mesh.Length = numGlyphs * 4; int numLines = CountLines(text, textLength); float fontBaseLineOffset = font.Face.Baseline * currentElementScale; if (vAlign == VerticalAlignment.Top) { fontBaseLineOffset -= font.Face.Ascent * currentElementScale; } else if (vAlign == VerticalAlignment.Bottom) { fontBaseLineOffset += (-(font.Face.Descent) * currentElementScale); fontBaseLineOffset += (font.Face.Ascent + font.Face.Descent) * (numLines - 1); } else if (vAlign == VerticalAlignment.Center) { fontBaseLineOffset = (font.Face.Baseline - (font.Face.Ascent + font.Face.Descent) * 0.5f) * currentElementScale; fontBaseLineOffset += (font.Face.Ascent + font.Face.Descent) * (numLines - 1) * 0.5f; } // experimental multi line: wrap mesh generation into a while loop so we can change offset for each line bool keepGoing = true; int startIndex = 0; int meshIndex = 0; while (keepGoing) { int blockLength = StrTok('\n', text, textLength, out char *nextBlock, out int remainingTextLength); float xAdvance = 0.0f; float totalAdvance = 0.0f; if (hAlign != HorizontalAlignment.Left) { for (int i = startIndex; i < startIndex + blockLength; ++i) { int glyphIndex = glyphIndices[i]; var glyph = font.Glyphs[glyphIndex]; totalAdvance += glyph.HorizontalAdvance * currentElementScale; } if (hAlign == HorizontalAlignment.Center) { xAdvance = -(totalAdvance / 2.0f); } else if (hAlign == HorizontalAlignment.Right) { xAdvance = -totalAdvance; } } for (gi = startIndex; gi < startIndex + blockLength; ++gi) { int glyphIndex = glyphIndices[gi]; var glyph = font.Glyphs[glyphIndex]; var glyphRect = font.GlyphRects[glyphIndex]; SimpleVertex topLeft = new SimpleVertex(); SimpleVertex bottomLeft = new SimpleVertex(); SimpleVertex topRight = new SimpleVertex(); SimpleVertex bottomRight = new SimpleVertex(); // TODO store this in the asset data per glyph float2 tl = new float2(glyph.HorizontalBearing.x, glyph.HorizontalBearing.y); float2 br = new float2(glyph.HorizontalBearing.x + glyph.Size.x, glyph.HorizontalBearing.y - glyph.Size.y); float2 advance = new float2(xAdvance, fontBaseLineOffset); topLeft.Position = new float3(advance + tl * currentElementScale, 0.0f); bottomLeft.Position = new float3(advance + new float2(tl.x, br.y) * currentElementScale, 0.0f); topRight.Position = new float3(advance + new float2(br.x, tl.y) * currentElementScale, 0.0f); bottomRight.Position.x = topRight.Position.x; bottomRight.Position.y = bottomLeft.Position.y; bottomRight.Position.z = 0.0f; topLeft.TexCoord0 = glyphRect.TopLeftUV; bottomLeft.TexCoord0 = new float2(glyphRect.TopLeftUV.x, glyphRect.BottomRightUV.y); bottomRight.TexCoord0 = glyphRect.BottomRightUV; topRight.TexCoord0 = new float2(glyphRect.BottomRightUV.x, glyphRect.TopLeftUV.y); topLeft.Color = vertexColor; bottomLeft.Color = vertexColor; topRight.Color = vertexColor; bottomRight.Color = vertexColor; mesh[meshIndex + 0] = bottomLeft; mesh[meshIndex + 1] = topLeft; mesh[meshIndex + 2] = topRight; mesh[meshIndex + 3] = bottomRight; meshIndex += 4; xAdvance += glyph.HorizontalAdvance * currentElementScale; } keepGoing = remainingTextLength > 0; fontBaseLineOffset -= (font.Face.Ascent + font.Face.Descent); textLength = remainingTextLength; text = nextBlock; startIndex += blockLength; } // mesh bounds MinMaxAABB bounds = MinMaxAABB.Empty; for (int i = 0; i < numGlyphs * 4; ++i) { bounds.Encapsulate(mesh[i].Position); } aabb = bounds; // Then make the index buffer triangles.Length = numGlyphs * 6; int index4 = 0; int index6 = 0; for (int i = 0; i < numGlyphs; i++) { triangles[index6 + 0] = (ushort)(index4 + 0); triangles[index6 + 1] = (ushort)(index4 + 1); triangles[index6 + 2] = (ushort)(index4 + 2); triangles[index6 + 3] = (ushort)(index4 + 2); triangles[index6 + 4] = (ushort)(index4 + 3); triangles[index6 + 5] = (ushort)(index4 + 0); index4 += 4; index6 += 6; } }
public override void MeshChunk(ChunkData data) { int n = 0; int m = 0; int Corner, Vertex, VertexTest, Edge, Triangle, FlagIndex, EdgeFlags; float Offset; uint[] CubeValue = new uint[8]; SimpleVertex[] EdgeVertex = new SimpleVertex[12]; data.points.Clear(); data.colors.Clear(); data.normals.Clear(); data.triangles.Clear(); for (int i = 0; i < Constants.ChunkWidth; i++) { for (int j = 0; j < Constants.ChunkWidth; j++) { for (int k = 0; k < Constants.ChunkHeight; k++) { //unsigned int c = data.values.at(i * (Constants.ChunkWidth + 1) * (Constants.ChunkHeight + 1) + j * (Constants.ChunkHeight + 1) + k); //Make a local copy of the values at the cube's corners for (Vertex = 0; Vertex < 8; Vertex++) { uint point = data.values[(int)((i + VertexOffset[Vertex, 0]) * (Constants.ChunkWidth + 1) * (Constants.ChunkHeight + 1) + (j + VertexOffset[Vertex, 2]) * (Constants.ChunkHeight + 1) + (k + VertexOffset[Vertex, 1]))]; CubeValue[Vertex] = point; } //Find which vertices are inside of the surface and which are outside FlagIndex = 0; for (VertexTest = 0; VertexTest < 8; VertexTest++) { if (CubeValue[VertexTest] % 256 + (CubeValue[VertexTest] >> 8) % 256 + (CubeValue[VertexTest] >> 16) % 256 > 0) { FlagIndex |= 1 << VertexTest; } } //Find which edges are intersected by the surface EdgeFlags = CubeEdgeFlags[FlagIndex]; //If the cube is entirely inside or outside of the surface, then there will be no intersections if (EdgeFlags == 0) { continue; } //Find the point of intersection of the surface with each edge //Then find the normal to the surface at those points for (Edge = 0; Edge < 12; Edge++) { //if there is an intersection on this edge if ((EdgeFlags & (1 << Edge)) != 0) { Offset = 0.5f; EdgeVertex[Edge].x = i * Constants.BlockWidth + (VertexOffset[EdgeConnection[Edge, 0], 0] + Offset * EdgeDirection[Edge, 0]) * Constants.BlockWidth; EdgeVertex[Edge].y = k * Constants.BlockHeight + (VertexOffset[EdgeConnection[Edge, 0], 1] + Offset * EdgeDirection[Edge, 1]) * Constants.BlockHeight; EdgeVertex[Edge].z = j * Constants.BlockWidth + (VertexOffset[EdgeConnection[Edge, 0], 2] + Offset * EdgeDirection[Edge, 2]) * Constants.BlockWidth; short r1 = (short)((CubeValue[EdgeConnection[Edge, 0]] >> 24) & 255); short r2 = (short)((CubeValue[EdgeConnection[Edge, 1]] >> 24) & 255); short g1 = (short)((CubeValue[EdgeConnection[Edge, 0]] >> 16) & 255); short g2 = (short)((CubeValue[EdgeConnection[Edge, 1]] >> 16) & 255); short b1 = (short)((CubeValue[EdgeConnection[Edge, 0]] >> 8) & 255); short b2 = (short)((CubeValue[EdgeConnection[Edge, 1]] >> 8) & 255); short a1 = (short)((CubeValue[EdgeConnection[Edge, 0]]) & 255); short a2 = (short)((CubeValue[EdgeConnection[Edge, 1]]) & 255); EdgeVertex[Edge].r = (byte)((r1 + r2) / 2); EdgeVertex[Edge].g = (byte)((g1 + g2) / 2); EdgeVertex[Edge].b = (byte)((b1 + b2) / 2); EdgeVertex[Edge].a = (byte)((a1 + a2) / 2); } } //Draw the triangles that were found. There can be up to five per cube for (Triangle = 0; Triangle < 5; Triangle++) { if (TriangleConnectionTable[FlagIndex, 3 * Triangle] < 0) { break; } int VertexA = TriangleConnectionTable[FlagIndex, 3 * Triangle + 0]; Vector3 A = new Vector3(EdgeVertex[VertexA].x, EdgeVertex[VertexA].y, EdgeVertex[VertexA].z); int VertexB = TriangleConnectionTable[FlagIndex, 3 * Triangle + 1]; Vector3 B = new Vector3(EdgeVertex[VertexB].x, EdgeVertex[VertexB].y, EdgeVertex[VertexB].z); int VertexC = TriangleConnectionTable[FlagIndex, 3 * Triangle + 2]; Vector3 C = new Vector3(EdgeVertex[VertexC].x, EdgeVertex[VertexC].y, EdgeVertex[VertexC].z); Vector3 AB = B - A; Vector3 BC = C - B; Vector3 normal = Vector3.Cross(BC, AB); bool water = false; for (Corner = 2; Corner >= 0; Corner--) { Vertex = TriangleConnectionTable[FlagIndex, 3 * Triangle + Corner]; if (EdgeVertex[Vertex].b > 0 && EdgeVertex[Vertex].g == 0 && EdgeVertex[Vertex].r == 0) { water = true; } } for (Corner = 2; Corner >= 0; Corner--) { if (water) { Vertex = TriangleConnectionTable[FlagIndex, 3 * Triangle + Corner]; data.WaterColors.Add(new Color32(EdgeVertex[Vertex].r, EdgeVertex[Vertex].g, EdgeVertex[Vertex].b, EdgeVertex[Vertex].a)); data.WaterPoints.Add(new Vector3(EdgeVertex[Vertex].x, EdgeVertex[Vertex].y - 0.1f, EdgeVertex[Vertex].z)); data.WaterNormals.Add(normal); data.WaterTriangles.Add(m); m++; } else { Vertex = TriangleConnectionTable[FlagIndex, 3 * Triangle + Corner]; data.colors.Add(new Color32(EdgeVertex[Vertex].r, EdgeVertex[Vertex].g, EdgeVertex[Vertex].b, EdgeVertex[Vertex].a)); data.points.Add(new Vector3(EdgeVertex[Vertex].x, EdgeVertex[Vertex].y, EdgeVertex[Vertex].z)); data.normals.Add(normal); data.triangles.Add(n); n++; } } } } } } }
//public static void SetTimeProvider(ITimeProvider provider) //{ // Processor.TimeProvider = provider; //} public static void DumpGraph() { var sb = new StringBuilder(); sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\r" + "<gexf xmlns=\"http://www.gexf.net/1.2draft\" xmlns:viz=\"http://www.gexf.net/1.2draft/viz\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd\" version=\"1.2\">" + "<meta lastmodifieddate=\"2009-03-20\">" + "<creator>Gexf.net</creator><description>Dashx.CEP</description></meta><graph mode=\"static\" defaultedgetype=\"directed\">"); sb.Append("<attributes class=\"edge\"><attribute id=\"0\" title=\"LastData\" type=\"string\"/></attributes>"); sb.Append("<attributes class=\"node\"><attribute id=\"0\" title=\"LastData\" type=\"string\"/></attributes>"); sb.Append("<nodes>"); //ExprTree.Tree.Layout(); ExprTree.Tree.Vertices.ToList().ForEach(x => { var vert = new SimpleVertex(x); string vertString = String.Format("<node id=\"{0}\" label=\"{1}\">", vert.UniqID, vert.Name); if (ExprTree.Tree.Vertices.Any <AbstractBlock>(z => z.UniqID == x.UniqID)) { var pt = ExprTree.ViewModel.Layout.LayoutAlgorithm.VertexPositions[x]; vertString += string.Format("<viz:position x=\"{0}\" y=\"{1}\" z=\"0\" />", pt.X, pt.Y); } vertString += string.Format("<viz:size value=\"2\" />"); vertString += string.Format("<viz:shape value=\"disc\"/>"); if (x.LastException != null) { vertString += string.Format("<viz:color r=\"254\" g=\"0\" b=\"0\" a=\"0.6\"/>"); } else if (x.LastData != null) { vertString += string.Format("<viz:color r=\"0\" g=\"0\" b=\"254\" a=\"0.6\"/>"); } else { vertString += string.Format("<viz:color r=\"239\" g=\"173\" b=\"66\" a=\"0.6\"/>"); } vertString += String.Format("<attvalues><attvalue for=\"LastData\" value=\"{0}\" /><attvalue for=\"LastEx\" value=\"{1}\" /></attvalues>", x.LastData ?? "NULL", x.LastException ?? "NULL"); vertString += string.Format("</node>"); sb.Append(vertString); }); sb.Append("</nodes><edges>"); List <SimpleEdge> edges = new List <SimpleEdge>(); ExprTree.Tree.Edges.ToList().ForEach(x => { var edge = new SimpleEdge(x); edges.Add(edge); string edgeString = String.Format("<edge id=\"{0}\" source=\"{1}\" target=\"{2}\">", edge.UniqID, edge.Source, edge.Destination); if (x.IsActiveWithEvent) { edgeString += String.Format("<color r=\"0\" g=\"254\" b=\"0\" a=\"0.6\"/>"); } edgeString += String.Format("<attvalues><attvalue for=\"0\" value=\"{0}\" /></attvalues>", x.LastData ?? "NULL"); edgeString += String.Format("</edge>"); //Avoid parallel edges as GEXF/Gephi has no spec for that. if (edges.AsQueryable().Any(e2 => e2.Source == edge.Source && e2.Destination == edge.Destination)) { sb.Append(edgeString); } }); sb.Append("</edges></graph></gexf>"); System.IO.File.WriteAllText(@"web\test.gexf", sb.ToString()); }
public void Create9Slice(Entity e, float3 org, RectangleRenderState rectangleRenderState, RectTransformResult rRes) { var indices = EntityManager.GetBuffer <DynamicIndex>(e); var vertices = EntityManager.GetBuffer <DynamicSimpleVertex>(e); vertices.ResizeUninitialized(kMaxVertex); indices.ResizeUninitialized(kMaxIndex); float2 size = rectangleRenderState.BaseSize; size = size / (rectangleRenderState.PixelsPerUnit * rectangleRenderState.PixelsPerUnitMultiplier); float4 border = rectangleRenderState.Border; float4 outer = rectangleRenderState.Outer; float2 split0 = new float2(border.x, border.y); float2 split1 = new float2(border.z, border.w); float2[] xy = new float2[4]; xy[0] = new float2(0); xy[1] = size * split0; xy[2] = rRes.Size - split1 * size; xy[3] = rRes.Size; float2[] uv = new float2[4]; uv[0] = outer.xy; uv[1] = outer.xy + (outer.zw - outer.xy) * split0; uv[2] = outer.zw - (outer.zw - outer.xy) * split1; uv[3] = outer.zw; for (int j = 0; j < 4; ++j) { for (int i = 0; i < 4; ++i) { float x = org.x + xy[i].x; float y = org.y + xy[j].y; SimpleVertex sv = new SimpleVertex { Position = new float3(x, y, org.z), Color = new float4(1, 1, 1, 1), TexCoord0 = new float2(uv[i].x, 1.0f - uv[j].y) }; vertices[j * 4 + i] = new DynamicSimpleVertex() { Value = sv }; } } for (int j = 0; j < 3; ++j) { for (int i = 0; i < 3; ++i) { const int P0 = 0; const int P1 = 1; const int P2 = 5; const int P3 = 4; int iB = j * 18 + i * 6; int vB = j * 4 + i; indices[iB + 0] = new DynamicIndex() { Value = (ushort)(vB + P0) }; indices[iB + 1] = new DynamicIndex() { Value = (ushort)(vB + P2) }; indices[iB + 2] = new DynamicIndex() { Value = (ushort)(vB + P1) }; indices[iB + 3] = new DynamicIndex() { Value = (ushort)(vB + P3) }; indices[iB + 4] = new DynamicIndex() { Value = (ushort)(vB + P2) }; indices[iB + 5] = new DynamicIndex() { Value = (ushort)(vB + P0) }; } } AddMeshRendererComponents(e, vertices.Length, indices.Length, vertices.AsNativeArray().Reinterpret <DynamicSimpleVertex, SimpleVertex>()); }