public void Update(double x, double y, double z, string texture, double ambient, double intensity) { if (!bValid) return; try { if (this.texture != texture) { this.texture = texture; Type ImageListType = typeof(ImageList); Dictionary<string, BitmapSource> _savedImages; BitmapSource img; _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (_savedImages.TryGetValue(texture, out img)) { bTexture = FastPixel.GetBitmap(img); if (width != bTexture.Width || height != bTexture.Height) bTexture = null; if (bSaveTexture && null != bTexture) { if (null != fpTexture) fpTexture.Unlock(false); fpTexture = new FastPixel(bTexture); } } else { bTexture = null; } } double scale; byte rgb; Color c; Vec3D source = new Vec3D(x, -y, z); source.Normalize(); if (!bSaveTexture && null != bTexture) { fpTexture = new FastPixel(bTexture); } for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { scale = Vec3D.Dot(source, vectors[i, j]); if (null != bTexture) { scale = ambient + (intensity - ambient) * System.Math.Max(0, scale); c = fpTexture.GetPixel(i, j); fpNormal.SetPixel(i, j, Color.FromArgb(c.A, LDImage.range(c.R * scale), LDImage.range(c.G * scale), LDImage.range(c.B * scale))); } else { scale = 0.5 * (1.0 + scale); rgb = LDImage.range(255 * scale); fpNormal.SetPixel(i, j, Color.FromArgb(255, rgb, rgb, rgb)); } } } fpNormal.Update(); if (!bSaveTexture && null != bTexture) fpTexture.Unlock(false); FastThread.Invoke(Update_Delegate); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } }
/// <summary> /// Create a normal map image from a height map. The height is given by the brightness of each pixel. /// </summary> /// <param name="image">The height map ImageList image.</param> /// <param name="scale">A scale factor for the elevation (default 1).</param> /// <returns>A new ImageList image with the resulting normal map.</returns> public static Primitive HeightMap2NormalMap(Primitive image, Primitive scale) { lock (LockingVar) { Type ImageListType = typeof(ImageList); Type GraphicsWindowType = typeof(GraphicsWindow); Type ShapesType = typeof(Shapes); string normalMap = ""; BitmapSource img; try { _savedImages = (Dictionary<string, BitmapSource>)ImageListType.GetField("_savedImages", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase).GetValue(null); if (!_savedImages.TryGetValue(image, out img)) return normalMap; MethodInfo method = ShapesType.GetMethod("GenerateNewName", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.IgnoreCase); normalMap = method.Invoke(null, new object[] { "ImageList" }).ToString(); if (scale == "") scale = 1; Bitmap bm = FastPixel.GetBitmap(img); FastPixel fp = new FastPixel(bm); Vec3D n = new Vec3D(); double[,] height = new double[fp.Width, fp.Height]; double maxheight = 0; double minheight = 1; for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { height[i, j] = fp.GetPixel(i, j).GetBrightness(); maxheight = System.Math.Max(maxheight, height[i, j]); minheight = System.Math.Min(minheight, height[i, j]); } } if (maxheight > minheight) { for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { height[i, j] = (height[i, j] - minheight) / (maxheight - minheight); } } } for (int i = 0; i < fp.Width; i++) { for (int j = 0; j < fp.Height; j++) { int im = i - 1; int ip = i + 1; int jm = j - 1; int jp = j + 1; n.Z = 1; if (im < 0) { im = 0; n.Z = 0.5f; } else if (ip >= fp.Width) { ip = fp.Width - 1; n.Z = 0.5f; } if (jm < 0) { jm = 0; n.Z = 0.5f; } else if (jp >= fp.Height) { jp = fp.Height - 1; n.Z = 0.5f; } n.X = scale * -(height[ip, jm] - height[im, jm] + 2 * (height[ip, j] - height[im, j]) + height[ip, jp] - height[im, jp]); n.Y = scale * (height[im, jp] - height[im, jm] + 2 * (height[i, jp] - height[i, jm]) + height[ip, jp] - height[ip, jm]); n.Normalize(); fp.SetPixel(i, j, Color.FromArgb(255, range((1 + n.X) * 128), range((1 + n.Y) * 128), range((1 + n.Z) * 128))); } } fp.Unlock(true); FastThread.SaveBitmap(normalMap, bm); } catch (Exception ex) { Utilities.OnError(Utilities.GetCurrentMethod(), ex); } return normalMap; } }