From 939bafa214cd2e85d55c3494c031932f314e9d4b Mon Sep 17 00:00:00 2001 From: larsbrubaker Date: Wed, 6 May 2015 08:11:05 -0700 Subject: [PATCH] The perspective renderer is working better. --- CustomWidgets/PartThumbnailWidget.cs | 9 +- CustomWidgets/ThumbnailTracer.cs | 143 ++++++++++++++++++++++++++- 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/CustomWidgets/PartThumbnailWidget.cs b/CustomWidgets/PartThumbnailWidget.cs index 6cfa31324..14712917f 100644 --- a/CustomWidgets/PartThumbnailWidget.cs +++ b/CustomWidgets/PartThumbnailWidget.cs @@ -426,9 +426,16 @@ namespace MatterHackers.MatterControl foreach (MeshGroup meshGroup in loadedMeshGroups) { + double minZ = double.MaxValue; + double maxZ = double.MinValue; foreach (Mesh loadedMesh in meshGroup.Meshes) { - tracer.DrawTo(bigRender.NewGraphics2D(), loadedMesh, RGBA_Bytes.White); + tracer.GetMinMaxZ(loadedMesh, ref minZ, ref maxZ); + } + + foreach (Mesh loadedMesh in meshGroup.Meshes) + { + tracer.DrawTo(bigRender.NewGraphics2D(), loadedMesh, RGBA_Bytes.White, minZ, maxZ); } } diff --git a/CustomWidgets/ThumbnailTracer.cs b/CustomWidgets/ThumbnailTracer.cs index 89d1a473c..b7b5c7dd5 100644 --- a/CustomWidgets/ThumbnailTracer.cs +++ b/CustomWidgets/ThumbnailTracer.cs @@ -119,13 +119,15 @@ namespace MatterHackers.RayTracer static RGBA_Floats lightIllumination = new RGBA_Floats(1, 1, 1); static RGBA_Floats ambiantIllumination = new RGBA_Floats(.4, .4, .4); - public void DrawTo(Graphics2D graphics2D, Mesh meshToDraw, RGBA_Bytes partColorIn) + public void DrawTo(Graphics2D graphics2D, Mesh meshToDraw, RGBA_Bytes partColorIn, double minZ, double maxZ) { RGBA_Floats partColor = partColorIn.GetAsRGBA_Floats(); graphics2D.Rasterizer.gamma(new gamma_power(.3)); PathStorage polygonProjected = new PathStorage(); + foreach (Face face in meshToDraw.Faces) { + double averageZ = 0; Vector3 normal = Vector3.TransformVector(face.normal, trackballTumbleWidget.ModelviewMatrix).GetNormal(); if (normal.z > 0) { @@ -143,8 +145,13 @@ namespace MatterHackers.RayTracer { polygonProjected.LineTo(screenPosition.x, screenPosition.y); } + + Vector3 transsformedPosition = Vector3.TransformPosition(faceEdge.firstVertex.Position, trackballTumbleWidget.ModelviewMatrix); + averageZ += transsformedPosition.z; } + averageZ /= 3; + RGBA_Floats polyDrawColor = new RGBA_Floats(); double L = Vector3.Dot(lightNormal, normal); if (L > 0.0f) @@ -153,14 +160,133 @@ namespace MatterHackers.RayTracer } polyDrawColor = RGBA_Floats.ComponentMax(polyDrawColor, partColor * ambiantIllumination); + double ratio = (averageZ - minZ) / (maxZ - minZ); + int ratioInt16 = (int)(ratio * 65536); - polyDrawColor.Alpha0To1 = 1; - graphics2D.Render(polygonProjected, polyDrawColor.GetAsRGBA_Bytes()); + //RGBA_Bytes renderColor = new RGBA_Bytes(polyDrawColor.Red0To255, ratioInt16 >> 8, ratioInt16 & 256); + RGBA_Bytes renderColor = new RGBA_Bytes(ratioInt16 >> 8, ratioInt16 >> 8, ratioInt16 >> 8); + + //IRecieveBlenderByte oldBlender = graphics2D.DestImage.GetRecieveBlender(); + //graphics2D.DestImage.SetRecieveBlender(new BlenderZBuffer()); + graphics2D.Render(polygonProjected, renderColor); + //graphics2D.DestImage.SetRecieveBlender(oldBlender); + + byte[] buffer = graphics2D.DestImage.GetBuffer(); + int pixels = graphics2D.DestImage.Width * graphics2D.DestImage.Height; + for (int i = 0; i < pixels; i++) + { + //buffer[i * 4 + 0] = buffer[i * 4 + 2]; + //buffer[i * 4 + 1] = buffer[i * 4 + 2]; + } } } - graphics2D.Rasterizer.gamma(new gamma_none()); } + public sealed class BlenderZBuffer : BlenderBase8888, IRecieveBlenderByte + { + public RGBA_Bytes PixelToColorRGBA_Bytes(byte[] buffer, int bufferOffset) + { + return new RGBA_Bytes(buffer[bufferOffset + ImageBuffer.OrderR], buffer[bufferOffset + ImageBuffer.OrderG], buffer[bufferOffset + ImageBuffer.OrderB], buffer[bufferOffset + ImageBuffer.OrderA]); + } + + public void CopyPixels(byte[] buffer, int bufferOffset, RGBA_Bytes sourceColor, int count) + { + do + { + if (sourceColor.green > buffer[bufferOffset + ImageBuffer.OrderG]) + { + buffer[bufferOffset + ImageBuffer.OrderR] = sourceColor.red; + buffer[bufferOffset + ImageBuffer.OrderG] = sourceColor.green; + buffer[bufferOffset + ImageBuffer.OrderB] = sourceColor.blue; + buffer[bufferOffset + ImageBuffer.OrderA] = sourceColor.alpha; + } + bufferOffset += 4; + } + while (--count != 0); + } + + public void BlendPixel(byte[] buffer, int bufferOffset, RGBA_Bytes sourceColor) + { + //unsafe + { + unchecked + { + if (sourceColor.alpha == 255) + { + buffer[bufferOffset + ImageBuffer.OrderR] = (byte)(sourceColor.red); + buffer[bufferOffset + ImageBuffer.OrderG] = (byte)(sourceColor.green); + buffer[bufferOffset + ImageBuffer.OrderB] = (byte)(sourceColor.blue); + buffer[bufferOffset + ImageBuffer.OrderA] = (byte)(sourceColor.alpha); + } + else + { + int r = buffer[bufferOffset + ImageBuffer.OrderR]; + int g = buffer[bufferOffset + ImageBuffer.OrderG]; + int b = buffer[bufferOffset + ImageBuffer.OrderB]; + int a = buffer[bufferOffset + ImageBuffer.OrderA]; + if (sourceColor.green > g) + { + buffer[bufferOffset + ImageBuffer.OrderR] = (byte)(((sourceColor.red - r) * sourceColor.alpha + (r << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift); + buffer[bufferOffset + ImageBuffer.OrderG] = (byte)(((sourceColor.green - g) * sourceColor.alpha + (g << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift); + buffer[bufferOffset + ImageBuffer.OrderB] = (byte)(((sourceColor.blue - b) * sourceColor.alpha + (b << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift); + buffer[bufferOffset + ImageBuffer.OrderA] = (byte)((sourceColor.alpha + a) - ((sourceColor.alpha * a + base_mask) >> (int)RGBA_Bytes.base_shift)); + } + } + } + } + } + + public void BlendPixels(byte[] destBuffer, int bufferOffset, + RGBA_Bytes[] sourceColors, int sourceColorsOffset, + byte[] covers, int coversIndex, bool firstCoverForAll, int count) + { + if (firstCoverForAll) + { + int cover = covers[coversIndex]; + if (cover == 255) + { + do + { + BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset++]); + bufferOffset += 4; + } + while (--count != 0); + } + else + { + do + { + sourceColors[sourceColorsOffset].alpha = (byte)((sourceColors[sourceColorsOffset].alpha * cover + 255) >> 8); + BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset]); + bufferOffset += 4; + ++sourceColorsOffset; + } + while (--count != 0); + } + } + else + { + do + { + int cover = covers[coversIndex++]; + if (cover == 255) + { + BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset]); + } + else + { + RGBA_Bytes color = sourceColors[sourceColorsOffset]; + color.alpha = (byte)((color.alpha * (cover) + 255) >> 8); + BlendPixel(destBuffer, bufferOffset, color); + } + bufferOffset += 4; + ++sourceColorsOffset; + } + while (--count != 0); + } + } + } + AxisAlignedBoundingBox GetAxisAlignedBoundingBox(List meshGroups) { AxisAlignedBoundingBox totalMeshBounds = new AxisAlignedBoundingBox(Vector3.NegativeInfinity, Vector3.NegativeInfinity); @@ -182,6 +308,7 @@ namespace MatterHackers.RayTracer return totalMeshBounds; } + private void AddTestMesh(List meshGroups) { if (meshGroups != null) @@ -241,6 +368,14 @@ namespace MatterHackers.RayTracer return screenBounds; } + public void GetMinMaxZ(Mesh mesh, ref double minZ, ref double maxZ) + { + AxisAlignedBoundingBox meshBounds = mesh.GetAxisAlignedBoundingBox(trackballTumbleWidget.ModelviewMatrix); + + minZ = Math.Min(meshBounds.minXYZ.z, minZ); + maxZ = Math.Max(meshBounds.maxXYZ.z, maxZ); + } + private bool NeedsToBeSmaller(RectangleDouble partScreenBounds, RectangleDouble goalBounds) { if (partScreenBounds.Bottom < goalBounds.Bottom