[Test] public void IndexerAccess() { // Create a vertex array and slice VertexC1P3[] array = new VertexC1P3[10]; VertexSlice <VertexC1P3> slice = new VertexSlice <VertexC1P3>( array, 1, array.Length - 2); // Fill the vertex array with data for (int i = 0; i < array.Length; i++) { array[i].Color = new ColorRgba(i); } // Assert that we can access the vertex data via indexer for (int i = 0; i < slice.Length; i++) { Assert.AreEqual(array[i + 1].Color, slice[i].Color); } // Assert that we can change data via indexer for (int i = 0; i < slice.Length; i++) { ColorRgba newColor = new ColorRgba(1234); slice[i] = new VertexC1P3 { Color = newColor }; Assert.AreEqual(newColor, slice[i].Color); Assert.AreEqual(newColor, array[i + 1].Color); } }
private void DrawHorizontalGraph(Canvas canvas, float[] values, ColorRgba[] colors, ref VertexC1P3[] vertices, float x, float y, float w, float h) { if (h > 0.0f) { h--; } if (h < 0.0f) { h++; } IDrawDevice device = canvas.DrawDevice; ColorRgba baseColor = canvas.State.ColorTint * canvas.State.MaterialDirect.MainColor; float sampleXRatio = w / (float)(values.Length - 1); if (vertices == null) { vertices = new VertexC1P3[MathF.Max(values.Length, 16)]; } else if (vertices.Length < values.Length) { vertices = new VertexC1P3[MathF.Max(vertices.Length * 2, values.Length, 16)]; } for (int i = 0; i < values.Length; i++) { vertices[i].Pos.X = x + 0.5f + i * sampleXRatio; vertices[i].Pos.Y = y + 0.5f + (1.0f - values[i]) * h; vertices[i].Pos.Z = 0.0f; vertices[i].Color = baseColor * colors[i]; } device.AddVertices(canvas.State.MaterialDirect, VertexMode.LineStrip, vertices, values.Length); }
protected void DrawSelectionMarkers(Canvas canvas, IEnumerable<ObjectEditorSelObj> obj) { // Determine turned Camera axes for angle-independent drawing Vector2 catDotX, catDotY; float camAngle = this.CameraObj.Transform.Angle; MathF.GetTransformDotVec(camAngle, out catDotX, out catDotY); Vector3 right = new Vector3(1.0f, 0.0f, 0.0f); Vector3 down = new Vector3(0.0f, 1.0f, 0.0f); MathF.TransformDotVec(ref right, ref catDotX, ref catDotY); MathF.TransformDotVec(ref down, ref catDotX, ref catDotY); canvas.PushState(); canvas.State.ZOffset = -1.0f; foreach (ObjectEditorSelObj selObj in obj) { if (!selObj.HasTransform) continue; Vector3 posTemp = selObj.Pos; float scaleTemp = 1.0f; float radTemp = selObj.BoundRadius; if (!canvas.DrawDevice.IsCoordInView(posTemp, radTemp)) continue; // Draw selection marker if (selObj.ShowPos) { canvas.DrawDevice.PreprocessCoords(ref posTemp, ref scaleTemp); posTemp.Z = 0.0f; { ColorRgba color = canvas.State.ColorTint * canvas.State.Material.MainColor; VertexC1P3[] vertices = new VertexC1P3[4]; vertices[0].Pos = posTemp - right * 5.0f; vertices[1].Pos = posTemp + right * 5.0f; vertices[2].Pos = posTemp - down * 5.0f; vertices[3].Pos = posTemp + down * 5.0f; vertices[0].Color = color; vertices[1].Color = color; vertices[2].Color = color; vertices[3].Color = color; canvas.DrawDevice.AddVertices(canvas.State.Material, VertexMode.Lines, vertices); } } // Draw angle marker if (selObj.ShowAngle) { posTemp = selObj.Pos + radTemp * right * MathF.Sin(selObj.Angle - camAngle) - radTemp * down * MathF.Cos(selObj.Angle - camAngle); canvas.DrawLine(selObj.Pos.X, selObj.Pos.Y, selObj.Pos.Z, posTemp.X, posTemp.Y, posTemp.Z); } // Draw boundary if (selObj.ShowBoundRadius && radTemp > 0.0f) canvas.DrawCircle(selObj.Pos.X, selObj.Pos.Y, selObj.Pos.Z, radTemp); } canvas.PopState(); }
[Test] public void Constructor() { // Create a vertex array and slice VertexC1P3[] array = new VertexC1P3[10]; VertexSlice <VertexC1P3> slice = new VertexSlice <VertexC1P3>( array, 1, array.Length - 2); // Assert that all the slice parameters are set properly Assert.AreEqual(1, slice.Offset); Assert.AreEqual(array.Length - 2, slice.Length); }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; float scaleTemp = 1.0f; Vector3 posTemp = Vector3.Zero; device.PreprocessCoords(ref posTemp, ref scaleTemp); if (posTemp.Z <= canvas.DrawDevice.NearZ) { return; } float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((posTemp.Z - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) { return; } float stepTemp = 4.0f * this.gridSize * MathF.Max(0.25f, MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleTemp, 2.0f)))); float scaledStep = stepTemp * scaleTemp; float viewBoundRad = device.TargetSize.Length * 0.5f; int lineCount = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep)) * 4; ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); VertexC1P3[] vertices = new VertexC1P3[lineCount * 4]; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = posTemp.X % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCount; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = -viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; beginPos = posTemp.Y % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCount; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = -viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Lines, vertices); }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; float scaleTemp = 1.0f; Vector3 posTemp = Vector3.Zero; device.PreprocessCoords(ref posTemp, ref scaleTemp); if (posTemp.Z <= canvas.DrawDevice.NearZ) return; float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((posTemp.Z - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) return; float stepTemp = 4.0f * this.gridSize * MathF.Max(0.25f, MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleTemp, 2.0f)))); float scaledStep = stepTemp * scaleTemp; float viewBoundRad = device.TargetSize.Length * 0.5f; int lineCount = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep)) * 4; ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); VertexC1P3[] vertices = new VertexC1P3[lineCount * 4]; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = posTemp.X % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCount; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = -viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; beginPos = posTemp.Y % scaledStep - (lineCount / 8) * scaledStep; pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCount; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = -viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = posTemp.Z + 1; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = viewBoundRad; pos += scaledStep / 4; lineIndex++; } vertOff += lineCount * 2; device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Lines, vertices); }
private void DrawHorizontalGraph(Canvas canvas, float[] values, ColorRgba[] colors, ref VertexC1P3[] vertices, float x, float y, float w, float h) { if (h > 0.0f) h--; if (h < 0.0f) h++; IDrawDevice device = canvas.DrawDevice; ColorRgba baseColor = canvas.State.ColorTint * canvas.State.MaterialDirect.MainColor; float sampleXRatio = w / (float)(values.Length - 1); if (vertices == null) vertices = new VertexC1P3[MathF.Max(values.Length, 16)]; else if (vertices.Length < values.Length) vertices = new VertexC1P3[MathF.Max(vertices.Length * 2, values.Length, 16)]; for (int i = 0; i < values.Length; i++) { vertices[i].Pos.X = x + 0.5f + i * sampleXRatio; vertices[i].Pos.Y = y + 0.5f + (1.0f - values[i]) * h; vertices[i].Pos.Z = 0.0f; vertices[i].Color = baseColor * colors[i]; } device.AddVertices(canvas.State.MaterialDirect, VertexMode.LineStrip, vertices, values.Length); }
[Test] public void RentAndClear() { VertexBatchStore memory = new VertexBatchStore(); // Repeatedly rent slices of varying types from memory { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(4); slice[0] = new VertexC1P3 { Color = new ColorRgba(0) }; slice[1] = new VertexC1P3 { Color = new ColorRgba(1) }; slice[2] = new VertexC1P3 { Color = new ColorRgba(2) }; slice[3] = new VertexC1P3 { Color = new ColorRgba(3) }; } { VertexSlice <VertexC1P3T2> slice = memory.Rent <VertexC1P3T2>(3); slice[0] = new VertexC1P3T2 { Color = new ColorRgba(4) }; slice[1] = new VertexC1P3T2 { Color = new ColorRgba(5) }; slice[2] = new VertexC1P3T2 { Color = new ColorRgba(6) }; } { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(2); slice[0] = new VertexC1P3 { Color = new ColorRgba(7) }; slice[1] = new VertexC1P3 { Color = new ColorRgba(8) }; } { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(1); slice[0] = new VertexC1P3 { Color = new ColorRgba(9) }; } // Assert correct storage property values Assert.AreEqual( 1 + Math.Max( VertexDeclaration.Get <VertexC1P3>().TypeIndex, VertexDeclaration.Get <VertexC1P3T2>().TypeIndex), memory.TypeIndexCount); Assert.AreEqual(1, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(1, memory.GetBatchCount <VertexC1P3T2>()); // Retrieve specific internal vertex arrays VertexBatch <VertexC1P3> batchA = memory.GetBatch <VertexC1P3>(0); VertexBatch <VertexC1P3T2> batchB = memory.GetBatch <VertexC1P3T2>(0); RawList <VertexC1P3> verticesA = batchA.Vertices; RawList <VertexC1P3T2> verticesB = batchB.Vertices; // Assert that they contain all the data we submitted in the correct order Assert.AreEqual(7, batchA.Count); Assert.AreEqual(3, batchB.Count); Assert.AreEqual(7, verticesA.Count); Assert.AreEqual(3, verticesB.Count); Assert.AreEqual(new ColorRgba(0), verticesA[0].Color); Assert.AreEqual(new ColorRgba(1), verticesA[1].Color); Assert.AreEqual(new ColorRgba(2), verticesA[2].Color); Assert.AreEqual(new ColorRgba(3), verticesA[3].Color); Assert.AreEqual(new ColorRgba(4), verticesB[0].Color); Assert.AreEqual(new ColorRgba(5), verticesB[1].Color); Assert.AreEqual(new ColorRgba(6), verticesB[2].Color); Assert.AreEqual(new ColorRgba(7), verticesA[4].Color); Assert.AreEqual(new ColorRgba(8), verticesA[5].Color); Assert.AreEqual(new ColorRgba(9), verticesA[6].Color); // Clear all vertices memory.Clear(); // Assert correct storage property values Assert.AreEqual(0, memory.TypeIndexCount); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>()); // Assert that the vertices are gone, but capacity isn't Assert.AreEqual(0, batchA.Count); Assert.AreEqual(0, batchB.Count); Assert.AreEqual(0, verticesA.Count); Assert.AreEqual(0, verticesB.Count); Assert.GreaterOrEqual(verticesA.Capacity, 7); Assert.GreaterOrEqual(verticesB.Capacity, 3); }
[Test] public void MaxBatchSize() { VertexBatchStore memory = new VertexBatchStore(4); // Rent a few memory slices, but stay below the max batch size { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(2); slice[0] = new VertexC1P3 { Color = new ColorRgba(0) }; slice[1] = new VertexC1P3 { Color = new ColorRgba(1) }; } { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(1); slice[0] = new VertexC1P3 { Color = new ColorRgba(2) }; } // Assert that we only have one batch, with the correct contents Assert.AreEqual(1, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>()); VertexBatch <VertexC1P3> batchA = memory.GetBatch <VertexC1P3>(0); RawList <VertexC1P3> verticesA = batchA.Vertices; Assert.AreEqual(3, batchA.Count); Assert.AreEqual(new ColorRgba(0), verticesA[0].Color); Assert.AreEqual(new ColorRgba(1), verticesA[1].Color); Assert.AreEqual(new ColorRgba(2), verticesA[2].Color); // Rent a few more slices, this time exceeding max batch size { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(2); slice[0] = new VertexC1P3 { Color = new ColorRgba(3) }; slice[1] = new VertexC1P3 { Color = new ColorRgba(4) }; } { VertexSlice <VertexC1P3> slice = memory.Rent <VertexC1P3>(2); slice[0] = new VertexC1P3 { Color = new ColorRgba(5) }; slice[1] = new VertexC1P3 { Color = new ColorRgba(6) }; } // Assert that we now have two batches, each with the correct contents Assert.AreEqual(2, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>()); VertexBatch <VertexC1P3> batchB = memory.GetBatch <VertexC1P3>(1); RawList <VertexC1P3> verticesB = batchB.Vertices; Assert.AreEqual(3, batchA.Count); Assert.AreEqual(new ColorRgba(0), verticesA[0].Color); Assert.AreEqual(new ColorRgba(1), verticesA[1].Color); Assert.AreEqual(new ColorRgba(2), verticesA[2].Color); Assert.AreEqual(4, batchB.Count); Assert.AreEqual(new ColorRgba(3), verticesB[0].Color); Assert.AreEqual(new ColorRgba(4), verticesB[1].Color); Assert.AreEqual(new ColorRgba(5), verticesB[2].Color); Assert.AreEqual(new ColorRgba(6), verticesB[3].Color); // Clear all vertices memory.Clear(); // Assert that the vertices are gone, but capacity isn't Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>()); Assert.AreEqual(0, batchA.Count); Assert.AreEqual(0, batchB.Count); Assert.AreEqual(0, verticesA.Count); Assert.AreEqual(0, verticesB.Count); Assert.GreaterOrEqual(verticesA.Capacity, 3); Assert.GreaterOrEqual(verticesB.Capacity, 4); // Rent some vertices again memory.Rent <VertexC1P3>(3); memory.Rent <VertexC1P3>(4); // Assert that the same storage is re-used Assert.AreEqual(2, memory.GetBatchCount <VertexC1P3>()); Assert.AreEqual(0, memory.GetBatchCount <VertexC1P3T2>()); Assert.AreEqual(3, batchA.Count); Assert.AreEqual(4, batchB.Count); Assert.AreEqual(3, verticesA.Count); Assert.AreEqual(4, verticesB.Count); // Assert that we're getting an exception when attempting to rent a slice that is too large Assert.Throws <ArgumentException>(() => memory.Rent <VertexC1P3>(5)); }