/* * /// <summary> * /// Die Oberflächennormalen werden abgerundet. * /// </summary> * protected void CreateSmoothNormales() * { * _normalesSmooth1 = new FloatVec3[pData.Width, pData.Height]; * _normalesSmooth2 = new FloatVec3[pData.Width, pData.Height]; * * // Normieren * for (int i = 0; i < pData.Width; i++) * { * for (int j = 0; j < pData.Height; j++) * { * FloatPixelInfo pInfo = _pictureData.Points[i, j]; * if (pInfo != null) * { * // pInfo.Normal.Normalize(); * _normalesSmooth1[i, j] = pInfo.Normal; * _normalesSmooth1[i, j].Normalize(); * } * } * } * * FloatVec3[,] currentSmooth = _normalesSmooth1; * FloatVec3[,] nextSmooth = _normalesSmooth2; * FloatVec3[,] tempSmooth; * float maxDist = _maxPoint.Dist(_minPoint); * float dGlobal = maxDist; * dGlobal /= 1500; * * int smoothLevel = (int)_parameters.GetDouble("Renderer.SmoothNormalLevel"); * for (int currentSmoothLevel = 0; currentSmoothLevel < smoothLevel; currentSmoothLevel++) * { * * // create nextSmooth * for (int i = 0; i < pData.Width; i++) * { * for (int j = 0; j < pData.Height; j++) * { * FloatVec3 center = null; * center = currentSmooth[i, j]; * FloatPixelInfo pInfo = _pictureData.Points[i, j]; * // Test ohne smooth-Factor * // Nachbarelemente zusammenrechnen * FloatVec3 neighbors = new FloatVec3(); * int neighborFound = 0; * for (int k = -1; k <= 1; k++) * { * for (int l = -1; l <= 1; l++) * { * int posX = i + k; * int posY = j + l; * if (posX >= 0 && posX < pData.Width && posY >= 0 && posY < pData.Height) * { * FloatVec3 currentNormal = null; * currentNormal = currentSmooth[i + k, j + l]; * FloatPixelInfo pInfo2 = _pictureData.Points[i + k, j + l]; * * if (currentNormal != null) * { * float amount = 1; * if (pInfo != null && pInfo2 != null) * { * float dist = pInfo.Coord.Dist(pInfo2.Coord); * * if (dist < dGlobal) * amount = 1.0f; * else if (dist > dGlobal && dist < 5.0 * dGlobal) * amount = 1.0f - (dGlobal / dist / 5.0f); * else * amount = 0; * } * * neighbors.Add(currentNormal.Mult(amount)); * neighborFound++; * } * } * } * } * neighbors.Normalize(); * if (center != null) * { * nextSmooth[i, j] = center; * if (center != null || neighborFound > 1) * { * FloatVec3 center2 = center; * center2.Mult(200); * neighbors.Add(center2.Mult(4)); * neighbors.Normalize(); * nextSmooth[i, j] = neighbors; * } * } * else * { * if (neighborFound > 4) * { * nextSmooth[i, j] = neighbors; * } * } * } * } * * tempSmooth = currentSmooth; * currentSmooth = nextSmooth; * nextSmooth = tempSmooth; * * } * * * } */ /// <summary> /// Field _heightMap is created from _pictureData.Points. /// </summary> protected void CreateHeightMap() { _heightMap = new float[pData.Width, pData.Height]; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { FloatPixelInfo pInfo = _pictureData.Points[i, j]; if (pInfo != null) { _heightMap[i, j] = pInfo.Coord.Y; if (_minY > pInfo.Coord.Y && pInfo.Coord.Y != 0) { _minY = pInfo.Coord.Y; } if (_maxY < pInfo.Coord.Y) { _maxY = pInfo.Coord.Y; } } else { _heightMap[i, j] = float.MinValue; } } } }
/// <summary> /// Creates boundingbox infos. /// </summary> protected void CreateStatisticInfo() { _minPoint.X = float.MaxValue; _minPoint.Y = float.MaxValue; _minPoint.Z = float.MaxValue; _maxPoint.X = float.MinValue; _maxPoint.Y = float.MinValue; _maxPoint.Z = float.MinValue; for (int i = 0; i < _pictureData.Width; i++) { for (int j = 0; j < _pictureData.Height; j++) { FloatPixelInfo pInfo = _pictureData.Points[i, j]; if (pInfo != null) { FloatVec3 coord = pInfo.Coord; if (coord.X < _minPoint.X) { _minPoint.X = coord.X; } if (coord.Y < _minPoint.Y) { _minPoint.Y = coord.Y; } if (coord.Z < _minPoint.Z) { _minPoint.Z = coord.Z; } if (coord.X > _maxPoint.X) { _maxPoint.X = coord.X; } if (coord.Y > _maxPoint.Y) { _maxPoint.Y = coord.Y; } if (coord.Z > _maxPoint.Z) { _maxPoint.Z = coord.Z; } } } } }
/// <summary> /// Initialisation with formula is needed for computing original coordinates. /// </summary> public override void Init(Formulas formula) { base.Init(formula); // Original data has to scale such that values fits into float range. Vec3 minPoint = new Vec3(0, 0, 0); Vec3 maxPoint = new Vec3(0, 0, 0); minPoint.X = Double.MaxValue; minPoint.Y = Double.MaxValue; minPoint.Z = Double.MaxValue; maxPoint.X = Double.MinValue; maxPoint.Y = Double.MinValue; maxPoint.Z = Double.MinValue; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { PixelInfo pInfo = pData.Points[i, j]; if (pInfo != null) { Vec3 coord = formula.GetTransform(pInfo.Coord.X, pInfo.Coord.Y, pInfo.Coord.Z); if (coord.X < minPoint.X) { minPoint.X = coord.X; } if (coord.Y < minPoint.Y) { minPoint.Y = coord.Y; } if (coord.Z < minPoint.Z) { minPoint.Z = coord.Z; } if (coord.X > maxPoint.X) { maxPoint.X = coord.X; } if (coord.Y > maxPoint.Y) { maxPoint.Y = coord.Y; } if (coord.Z > maxPoint.Z) { maxPoint.Z = coord.Z; } } } } Vec3 center = new Vec3(0, 0, 0); center.X = (maxPoint.X + minPoint.X) / 2.0; center.Y = (maxPoint.Y + minPoint.Y) / 2.0; center.Z = (maxPoint.Z + minPoint.Z) / 2.0; double radius = maxPoint.X - minPoint.X + maxPoint.Y - minPoint.Y + maxPoint.Z - minPoint.Z; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { PixelInfo pInfo = pData.Points[i, j]; if (pInfo != null) { FloatPixelInfo floatPixelInfo = new FloatPixelInfo(); floatPixelInfo.Coord.X = (float)((pInfo.Coord.X - center.X) / radius); floatPixelInfo.Coord.Y = (float)((pInfo.Coord.Y - center.Y) / radius); floatPixelInfo.Coord.Z = (float)((pInfo.Coord.Z - center.Z) / radius); floatPixelInfo.AdditionalInfo = pInfo.AdditionalInfo; floatPixelInfo.IsInside = pInfo.IsInside; pInfo.Normal.Normalize(); floatPixelInfo.Normal.X = (float)pInfo.Normal.X; floatPixelInfo.Normal.Y = (float)pInfo.Normal.Y; floatPixelInfo.Normal.Z = (float)pInfo.Normal.Z; _pictureData.Points[i, j] = floatPixelInfo; } } } }
/// <summary> /// Compute field of view. /// </summary> protected void SmoothPlane() { _rgbSmoothPlane1 = new FloatVec3[pData.Width, pData.Height]; _rgbSmoothPlane2 = new FloatVec3[pData.Width, pData.Height]; int intRange = 3; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { _rgbSmoothPlane2[i, j] = _rgbPlane[i, j]; } } if (_ambientIntensity == 0) { // No field of view defined: return; } // starts with rgbSmoothPlane2 FloatVec3[,] currentPlane = _rgbSmoothPlane2; FloatVec3[,] nextPlane = _rgbSmoothPlane1; // contain the result colors FloatVec3[,] resultPlane = _rgbSmoothPlane1; for (int m = 0; m < _ambientIntensity; m++) { if (_stopRequest) { return; } for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { double neighborsFound = 0; FloatPixelInfo pInfo = _pictureData.Points[i, j]; FloatVec3 nColor = new FloatVec3(); float ydNormalized = (float)GetAmbientValue(_heightMap[i, j]); ydNormalized = (float)Math.Sqrt(ydNormalized); intRange = 1; if (intRange == 0) { nColor = currentPlane[i, j]; neighborsFound = 1; } float sumColor = 0; // if(pData.Points[i, j]!=null) { //if (true) { for (int k = -intRange; k <= intRange; k++) { for (int l = -intRange; l <= intRange; l++) { // Center Pixel is also allowed // if (k != 0 || l != 0) { int posX = i + k; int posY = j + l; if (posX >= 0 && posX < pData.Width && posY >= 0 && posY < pData.Height) { FloatVec3 nColor1 = new FloatVec3(); if (true) // if ( (ylocalDiff > 0) ||(i==posX && j==posY)) // if ((ylocalDiff < 0) || (i == posX && j == posY)) // if(false) { //double range = (k * k + l * l) / (intRange * intRange); int range = (k * k + l * l); float mult = 1; if (range == 0) { // mult = 0.6; mult = ydNormalized * 0.3f; //mult = 0.2; } if (range == 1) { //mult = 0.25; mult = (1.0f - ydNormalized) * 0.4f; //mult = 0.45; } if (range == 2) { //mult=0.15; mult = (1.0f - ydNormalized) * 0.3f; //mult = 0.35; } // mult += 0.00001; FloatPixelInfo pInfo2 = _pictureData.Points[posX, posY]; float amount = 1; if (pInfo != null && pInfo2 != null) { float dist = pInfo.Coord.Dist(pInfo2.Coord); float dGlobal = _maxPoint.Dist(_minPoint); dGlobal /= 1500; if (dist < dGlobal) { amount = 1.0f; } else { // else if (dist > dGlobal && dist < 10.0 * dGlobal) amount = 1.0f - (dGlobal / dist) / 10.0f; } // else // amount = 0.0; } mult *= amount; // mult *= 1.0/ydNormalized; sumColor += mult; FloatVec3 currentColor = currentPlane[posX, posY]; nColor1.X = currentColor.X; nColor1.Y = currentColor.Y; nColor1.Z = currentColor.Z; nColor1 = nColor1.Mult(mult); // Scaling; nColor.Add(nColor1); neighborsFound++; } } } } } if (neighborsFound > 1) { nColor = nColor.Mult(1 / sumColor); } else { nColor = currentPlane[i, j]; } nextPlane[i, j] = nColor; } } resultPlane = nextPlane; nextPlane = currentPlane; currentPlane = resultPlane; } for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { _rgbPlane[i, j] = resultPlane[i, j]; } } _rgbSmoothPlane1 = null; _rgbSmoothPlane2 = null; return; }
/// <summary> /// Get the color information of the bitmap at (x,y) /// </summary> protected Vec3 GetRgb(int x, int y) { FloatVec3 retVal = new FloatVec3(0, 0, 1); // blau FloatPixelInfo pInfo = _pictureData.Points[x, y]; if (pInfo == null) { return(new Vec3(_backColorRed, _backColorGreen, _backColorBlue)); } FloatVec3 light = new FloatVec3(0, 0, 0); FloatVec3 normal = null; normal = pInfo.Normal; if (normal == null) { return(new Vec3(0, 0, 0)); } normal.Normalize(); if (pInfo.Normal != null) { light = GetLightF(normal); } retVal.X = light.X; retVal.Y = light.Y; retVal.Z = light.Z; retVal.X = (float)(_lightIntensity * retVal.X + (1 - _lightIntensity) * (1 - _shadowPlane[x, y])); retVal.Y = (float)(_lightIntensity * retVal.Y + (1 - _lightIntensity) * (1 - _shadowPlane[x, y])); retVal.Z = (float)(_lightIntensity * retVal.Z + (1 - _lightIntensity) * (1 - _shadowPlane[x, y])); if (retVal.X < 0) { retVal.X = 0; } if (retVal.Y < 0) { retVal.Y = 0; } if (retVal.Z < 0) { retVal.Z = 0; } if (retVal.X > 1) { retVal.X = 1; } if (retVal.Y > 1) { retVal.Y = 1; } if (retVal.Z > 1) { retVal.Z = 1; } float brightLightLevel = (float)_parameters.GetDouble("Renderer.BrightLightLevel"); if (brightLightLevel > 0) { retVal.X = (1 - brightLightLevel) * retVal.X + brightLightLevel * light.X * (1 - _shadowPlane[x, y]); retVal.Y = (1 - brightLightLevel) * retVal.Y + brightLightLevel * light.Y * (1 - _shadowPlane[x, y]); retVal.Z = (1 - brightLightLevel) * retVal.Z + brightLightLevel * light.Z * (1 - _shadowPlane[x, y]); } if (retVal.X < 0) { retVal.X = 0; } if (retVal.Y < 0) { retVal.Y = 0; } if (retVal.Z < 0) { retVal.Z = 0; } if (retVal.X > 1) { retVal.X = 1; } if (retVal.Y > 1) { retVal.Y = 1; } if (retVal.Z > 1) { retVal.Z = 1; } // Add surface color bool useAdditionalColorinfo = true; if (_colorIntensity <= 0) { useAdditionalColorinfo = false; } if (useAdditionalColorinfo && ((pInfo.IsInside && _colorInside) || (!pInfo.IsInside && _colorOutside))) { if (pInfo != null && pInfo.AdditionalInfo != null) { if (double.IsNaN(pInfo.AdditionalInfo.red)) { pInfo.AdditionalInfo.red = 0; } if (double.IsNaN(pInfo.AdditionalInfo.green)) { pInfo.AdditionalInfo.green = 0; } if (double.IsNaN(pInfo.AdditionalInfo.blue)) { pInfo.AdditionalInfo.blue = 0; } if (pInfo.AdditionalInfo.red < 0) { pInfo.AdditionalInfo.green -= pInfo.AdditionalInfo.red; pInfo.AdditionalInfo.blue -= pInfo.AdditionalInfo.red; pInfo.AdditionalInfo.red = 0; } if (pInfo.AdditionalInfo.green < 0) { pInfo.AdditionalInfo.red -= pInfo.AdditionalInfo.green; pInfo.AdditionalInfo.blue -= pInfo.AdditionalInfo.green; pInfo.AdditionalInfo.green = 0; } if (pInfo.AdditionalInfo.blue < 0) { pInfo.AdditionalInfo.red -= pInfo.AdditionalInfo.blue; pInfo.AdditionalInfo.blue -= pInfo.AdditionalInfo.blue; pInfo.AdditionalInfo.blue = 0; } // Normalise; float r1 = (float)(_colorFactorRed * Math.Pow(pInfo.AdditionalInfo.red, _colorIntensity)); float g1 = (float)(_colorFactorGreen * Math.Pow(pInfo.AdditionalInfo.green, _colorIntensity)); float b1 = (float)(_colorFactorBlue * Math.Pow(pInfo.AdditionalInfo.blue, _colorIntensity)); if (r1 < 0) { r1 = -r1; } if (g1 < 0) { g1 = -g1; } if (b1 < 0) { b1 = -b1; } // Normalize: float norm = (float)(Math.Sqrt(r1 * r1 + g1 * g1 + b1 * b1) / Math.Sqrt(2.5)); if (norm > 0) { r1 = r1 / norm; g1 = g1 / norm; b1 = b1 / norm; if (_colorThreshold > 0) { double thresholdIndicator = Math.Max(Math.Abs(r1 - b1), Math.Max(Math.Abs(r1 - g1), Math.Abs(g1 - b1))); float lowerThresholdFactor = (float)0.7; if (thresholdIndicator < _colorThreshold * lowerThresholdFactor) { r1 = (float)1; g1 = (float)1; b1 = (float)1; } else if (thresholdIndicator < _colorThreshold) { r1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + r1; g1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + g1; b1 = (float)(_colorThreshold - thresholdIndicator) * (float)0.5 / lowerThresholdFactor + b1; } } } for (int i = 0; i < 5; i++) { if (r1 > 1) { b1 += (r1 - 1) / (float)2.0; g1 += (r1 - 1) / (float)2.0; r1 = 1; } if (b1 > 1) { r1 += (b1 - 1) / (float)2.0; g1 += (b1 - 1) / (float)2.0; b1 = 1; } if (g1 > 1) { r1 += (g1 - 1) / (float)2.0; b1 += (g1 - 1) / (float)2.0; g1 = 1; } } if (r1 > 1) { r1 = 1; } if (b1 > 1) { b1 = 1; } if (g1 > 1) { g1 = 1; } if (_colorGreyness > 0) { r1 = (float)(_colorGreyness + (1 - _colorGreyness) * r1); g1 = (float)(_colorGreyness + (1 - _colorGreyness) * g1); b1 = (float)(_colorGreyness + (1 - _colorGreyness) * b1); } if (r1 > 1) { r1 = 1; } if (b1 > 1) { b1 = 1; } if (g1 > 1) { g1 = 1; } if (norm != 0) { switch (_rgbType) { case 1: retVal.X *= r1; retVal.Y *= g1; retVal.Z *= b1; break; case 2: retVal.X *= r1; retVal.Y *= b1; retVal.Z *= g1; break; case 3: retVal.X *= g1; retVal.Y *= r1; retVal.Z *= b1; break; case 4: retVal.X *= g1; retVal.Y *= b1; retVal.Z *= r1; break; case 5: retVal.X *= b1; retVal.Y *= r1; retVal.Z *= g1; break; case 6: retVal.X *= b1; retVal.Y *= g1; retVal.Z *= r1; break; default: retVal.X *= r1; retVal.Y *= g1; retVal.Z *= b1; break; } } } } if (_contrast != 1) { retVal.X = (float)Math.Pow(retVal.X, _contrast); retVal.Y = (float)Math.Pow(retVal.Y, _contrast); retVal.Z = (float)Math.Pow(retVal.Z, _contrast); } if (_brightness > 1) { retVal.X *= _brightness; retVal.Y *= _brightness; retVal.Z *= _brightness; } if (retVal.X < 0) { retVal.X = 0; } if (retVal.X > 1) { retVal.X = 1; } if (retVal.Y < 0) { retVal.Y = 0; } if (retVal.Z < 0) { retVal.Z = 0; } if (retVal.Y > 1) { retVal.Y = 1; } if (retVal.Z > 1) { retVal.Z = 1; } if (pInfo != null && pInfo.AdditionalInfo != null) { pInfo.AdditionalInfo.red2 = retVal.X; pInfo.AdditionalInfo.green2 = retVal.Y; pInfo.AdditionalInfo.blue2 = retVal.Z; } return(new Vec3(retVal.X, retVal.Y, retVal.Z)); }
/// <summary> /// Initialisation with formula is needed for computing original coordinates. /// </summary> public override void Init(Formulas formula) { base.Init(formula); // Original data has to scale such that values fits into float range. Vec3 minPoint = new Vec3(0, 0, 0); Vec3 maxPoint = new Vec3(0, 0, 0); minPoint.X = Double.MaxValue; minPoint.Y = Double.MaxValue; minPoint.Z = Double.MaxValue; maxPoint.X = Double.MinValue; maxPoint.Y = Double.MinValue; maxPoint.Z = Double.MinValue; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { PixelInfo pInfo = pData.Points[i, j]; if (pInfo != null) { Vec3 coord = formula.GetTransform(pInfo.Coord.X, pInfo.Coord.Y, pInfo.Coord.Z); if (coord.X < minPoint.X) minPoint.X = coord.X; if (coord.Y < minPoint.Y) minPoint.Y = coord.Y; if (coord.Z < minPoint.Z) minPoint.Z = coord.Z; if (coord.X > maxPoint.X) maxPoint.X = coord.X; if (coord.Y > maxPoint.Y) maxPoint.Y = coord.Y; if (coord.Z > maxPoint.Z) maxPoint.Z = coord.Z; } } } Vec3 center = new Vec3(0, 0, 0); center.X = (maxPoint.X + minPoint.X) / 2.0; center.Y = (maxPoint.Y + minPoint.Y) / 2.0; center.Z = (maxPoint.Z + minPoint.Z) / 2.0; double radius = maxPoint.X - minPoint.X + maxPoint.Y - minPoint.Y + maxPoint.Z - minPoint.Z; for (int i = 0; i < pData.Width; i++) { for (int j = 0; j < pData.Height; j++) { PixelInfo pInfo = pData.Points[i, j]; if (pInfo != null) { FloatPixelInfo floatPixelInfo = new FloatPixelInfo(); floatPixelInfo.Coord.X = (float)((pInfo.Coord.X - center.X) / radius); floatPixelInfo.Coord.Y = (float)((pInfo.Coord.Y - center.Y) / radius); floatPixelInfo.Coord.Z = (float)((pInfo.Coord.Z - center.Z) / radius); floatPixelInfo.AdditionalInfo = pInfo.AdditionalInfo; floatPixelInfo.IsInside = pInfo.IsInside; pInfo.Normal.Normalize(); floatPixelInfo.Normal.X = (float)pInfo.Normal.X; floatPixelInfo.Normal.Y = (float)pInfo.Normal.Y; floatPixelInfo.Normal.Z = (float)pInfo.Normal.Z; _pictureData.Points[i, j] = floatPixelInfo; } } } }