private void UpdateTiles_Quadrant(AxisFor axisX, AxisFor axisY, Point center, double size) { foreach (int x in axisX.Iterate()) { foreach (int y in axisY.Iterate()) { if ((x + y) % 2 != 0) { continue; // skip every other, so that it's a checkerboard } VectorInt vect = new VectorInt(x, y); Rectangle rect; if (!_rectangles.TryGetValue(vect, out rect)) { rect = new Rectangle() { Fill = _brush, }; _rectangles.Add(vect, rect); _canvas.Children.Add(rect); } rect.Width = size; rect.Height = size; Canvas.SetLeft(rect, center.X + _initialOffset.X + (x * size)); Canvas.SetTop(rect, center.Y + _initialOffset.Y + (y * size)); } } }
private static void DrawFieldSprtDoIt(byte[] pixels, double[] ink, bool[] blocked, int size, byte[] colorZFront, byte[] colorZBack, AxisFor pixelX, AxisFor pixelY, AxisFor pixelZ) { List <Mapping_2D_1D> flattened = new List <Mapping_2D_1D>(); // Setup the pixel array //for (int y2D = pixelY.Start; pixelY.IsPos ? y2D <= pixelY.Stop : y2D >= pixelY.Stop; y2D += pixelY.Increment) foreach (int y2D in pixelY.Iterate()) { int offsetY = pixelY.GetValueForOffset(y2D) * size; //for (int x2D = pixelX.Start; pixelX.IsPos ? x2D <= pixelX.Stop : x2D >= pixelX.Stop; x2D += pixelX.Increment) foreach (int x2D in pixelX.Iterate()) { int offset = offsetY + pixelX.GetValueForOffset(x2D); flattened.Add(new Mapping_2D_1D(x2D, y2D, offset)); } } // Each pixel of the output bitmap can be added up independently, so employ some threading flattened.AsParallel().ForAll(o => { //TODO: Color is 6.5 times slower than byte array List <byte[]> colorColumn = new List <byte[]>(); for (int z2D = pixelZ.Start; pixelZ.IsPos?z2D <= pixelZ.Stop : z2D >= pixelZ.Stop; z2D += pixelZ.Increment) { int x = -1, y = -1, z = -1; pixelX.Set3DIndex(ref x, ref y, ref z, o.X); pixelY.Set3DIndex(ref x, ref y, ref z, o.Y); pixelZ.Set3DIndex(ref x, ref y, ref z, z2D); int index = FluidField3D.Get1DIndex(x, y, z, size); if (blocked[index]) { // Blocked cells are all white, so save the overlay method a bit of work, and throw out everything behind this colorColumn.Clear(); colorColumn.Add(new byte[] { 255, 255, 255, 255 }); continue; } double inkCell = ink[index]; if (Math1D.IsNearZero(inkCell)) { continue; } byte[] depthColor = UtilityWPF.AlphaBlend(colorZBack, colorZFront, UtilityCore.GetScaledValue_Capped(0, 1, 0, size - 1, z)); int alpha = Convert.ToInt32(Math.Round(inkCell * 255)); if (alpha < 0) { alpha = 0; } else if (alpha > 255) { alpha = 255; } colorColumn.Add(new byte[] { Convert.ToByte(alpha), depthColor[1], depthColor[2], depthColor[3] }); } byte[] color = colorColumn.Count > 0 ? UtilityWPF.OverlayColors(colorColumn) : new byte[] { 0, 0, 0, 0 }; pixels[o.Offset1D * 4 + 0] = color[3]; // Blue pixels[o.Offset1D * 4 + 1] = color[2]; // Green pixels[o.Offset1D * 4 + 2] = color[1]; // Red pixels[o.Offset1D * 4 + 3] = color[0]; // Alpha }); }
private void DrawLines_Plate(int numSamples, double half, double lineThickness, AxisFor axisX, AxisFor axisY, AxisFor axisZ) { const double ELAPSEDURATIONSECONDS = 1; // Figure out how wide to make the plate int totalSamples = numSamples * numSamples * numSamples; // numsamples is per axis, so cube it int cellsPerSlice = _field.Size * _field.Size; int numSlices = Convert.ToInt32(Math.Round(Convert.ToDouble(totalSamples) / Convert.ToDouble(cellsPerSlice))); if (numSlices == 0) { numSlices = 1; } int toOffset = numSlices / 2; int fromOffset = numSlices - toOffset - 1; DateTime now = DateTime.UtcNow; bool isOverField = false; if (_mousePoint != null) { #region Snap to mouse // Cast a ray (Copied this from ItemSelectDragLogic.ChangeDragPlane, DragItem) Point3D point = new Point3D(0, 0, 0); RayHitTestParameters cameraLookCenter = UtilityWPF.RayFromViewportPoint(_camera, _viewport, new Point(_viewport.ActualWidth * .5d, _viewport.ActualHeight * .5d)); // Come up with a snap plane Vector3D standard = Math3D.GetArbitraryOrhonganal(cameraLookCenter.Direction); Vector3D orth = Vector3D.CrossProduct(standard, cameraLookCenter.Direction); ITriangle plane = new Triangle(point, point + standard, point + orth); DragHitShape dragPlane = new DragHitShape(); dragPlane.SetShape_Plane(plane); // Cast a ray onto that plane from the current mouse position RayHitTestParameters mouseRay = UtilityWPF.RayFromViewportPoint(_camera, _viewport, _mousePoint.Value); Point3D?hitPoint = dragPlane.CastRay(mouseRay); if (hitPoint != null) { // Find the nearest Z cell double halfSize = (_field.Size * _sizeMult) / 2d; double cellSize = (_field.Size * _sizeMult) / _field.Size; int zIndex = Convert.ToInt32((halfSize - axisZ.GetValue(hitPoint.Value)) / cellSize); if (zIndex >= 0 && zIndex < _field.Size) { isOverField = true; // Cap to field _plateCurrentIndex = _field.Size - zIndex; // it's actually the opposite if (_plateCurrentIndex - fromOffset < 0) { _plateCurrentIndex = fromOffset; } else if (_plateCurrentIndex + toOffset > _field.Size - 1) { _plateCurrentIndex = _field.Size - toOffset - 1; } _sceneRemaining = now + TimeSpan.FromSeconds(ELAPSEDURATIONSECONDS); } } #endregion } if (!isOverField) { #region Shift the plate if (_plateCurrentIndex + toOffset > _field.Size - 1) { _plateCurrentIndex = _field.Size - toOffset - 1; _sceneRemaining = now + TimeSpan.FromSeconds(ELAPSEDURATIONSECONDS); } else if (now > _sceneRemaining) { _plateCurrentIndex--; if (_plateCurrentIndex - fromOffset <= 0) { _plateCurrentIndex = _field.Size - toOffset - 1; } _sceneRemaining = now + TimeSpan.FromSeconds(ELAPSEDURATIONSECONDS); } #endregion } double[] velX = _field.VelocityX; double[] velY = _field.VelocityY; double[] velZ = _field.VelocityZ; bool[] blocked = _field.Blocked; _velocityLines.BeginAddingLines(); for (int z = _plateCurrentIndex - fromOffset; z <= _plateCurrentIndex + toOffset; z++) { for (int x = 0; x < _field.Size; x++) { for (int y = 0; y < _field.Size; y++) { int xRef = -1; int yRef = -1; int zRef = -1; axisX.Set3DIndex(ref xRef, ref yRef, ref zRef, x); axisY.Set3DIndex(ref xRef, ref yRef, ref zRef, y); axisZ.Set3DIndex(ref xRef, ref yRef, ref zRef, z); int index1D = _field.Get1DIndex(xRef, yRef, zRef); if (blocked[index1D]) { continue; } DrawLinesSprtAddLine(xRef, yRef, zRef, index1D, half, lineThickness, velX, velY, velZ); } } } _velocityLines.EndAddingLines(); }