public BitmapSource Shadow(GradientDef gradient)
{
if (gradient == null) return null;
if (pixelData == null) return null;
double cosAzimuth = Math.Cos(azimuth * 0.0174532925);
double sinAzimuth = Math.Sin(azimuth * 0.0174532925);
double cosElev = Math.Cos(elevation * 0.0174532925);
double sinElev = Math.Sin(elevation * 0.0174532925);
// draw the pixels scaled to color range - we need to know min max
double xInc = (double)Boundary.Object.W / (double)width;
double yInc = (double)Boundary.Object.H / (double)height;
double x = Boundary.Object.X;
double y = Boundary.Object.Y;
System.Windows.Media.PixelFormat pf = System.Windows.Media.PixelFormats.Rgb24;
int rawStride = width * 3;
Color c = new Color();
// n is the index into noiseData
// i,j are indexes into the bitmap data - range of the widow size
// x,y are indexes into the noise module to get the value - range of teh bounds
// int n = 0;
for (int j = 0; j < height; ++j)
{
int yIndex = j * rawStride;
int ii = 0;
for (int i = 0; i < rawStride; i += 3)
{
// Calculate the positions of the current point's four-neighbors.
int xLeftOffset, xRightOffset;
int yUpOffset, yDownOffset;
{
if (ii == 0)
{
xLeftOffset = 0;
xRightOffset = 1;
}
else if (ii == (int)width - 1)
{
xLeftOffset = -1;
xRightOffset = 0;
}
else
{
xLeftOffset = -1;
xRightOffset = 1;
}
if (j == 0)
{
yDownOffset = 0;
yUpOffset = 1;
}
else if (j == (int)height - 1)
{
yDownOffset = -1;
yUpOffset = 0;
}
else
{
yDownOffset = -1;
yUpOffset = 1;
}
}
yDownOffset *= width;
yUpOffset *= width;
// Get the noise value of the current point in the source noise map
// and the noise values of its four-neighbors.
double nc = noiseData[j * width + ii];
double nl = noiseData[j * width + ii + xLeftOffset];
double nr = noiseData[j * width + ii + xRightOffset];
double nd = noiseData[j * width + ii + yDownOffset];
double nu = noiseData[j * width + ii + yUpOffset];
if (mNormal)
{
nc = (nc - min) / (max - min);
nl = (nl - min) / (max - min);
nr = (nr - min) / (max - min);
nd = (nd - min) / (max - min);
nu = (nu - min) / (max - min);
}
// Now do the lighting calculations.
double lightIntensity;
{
double io = 1.0 * 1.41421356 * sinElev / 2.0;
double ix = (1.0 - io) * contrast * 1.41421356 * cosElev * cosAzimuth;
double iy = (1.0 - io) * contrast * 1.41421356 * cosElev * sinAzimuth;
lightIntensity = (ix * (nl - nr) + iy * (nd - nu) + io);
if (lightIntensity < 0.0) { lightIntensity = 0.0; }
lightIntensity *= intensity;
}
gradient.GetColor(nc, ref c);
pixelData[i + yIndex] = (byte)NMath.ClampValue((int)(c.R * lightIntensity), 0, 255);
pixelData[i + yIndex + 1] = (byte)NMath.ClampValue((int)(c.G * lightIntensity), 0, 255);
pixelData[i + yIndex + 2] = (byte)NMath.ClampValue((int)(c.B * lightIntensity), 0, 255);
x += xInc;
ii += 1;
}
y += yInc;
x = Boundary.Object.X;
}
BitmapSource bitmap = null;
if (noDispatch)
bitmap = BitmapSource.Create(width, height, 96, 96, pf, null, pixelData, rawStride);
else
Application.Current.Dispatcher.Invoke((Action)(() => { bitmap = BitmapSource.Create(width, height, 96, 96, pf, null, pixelData, rawStride); }));
return bitmap;
}