private double FaceVariance(short v1, short v2, short v3) { double MaxVar = 0; if (Math.Abs(v1 - v2) == 1 || Math.Abs(v3 - v2) == 1) { MaxVar = 0; // minimal face, no variance } else { // find vertice in middle of hypothenuse short mid_hyp_indice = MidHypVerticeIndice(v1, v3); // find real elevation in middle of hypothenuse CustomVertex.PositionTextured vh = this._elevatedVertices[mid_hyp_indice]; Vector3 v = MathEngine.CartesianToSpherical(vh.X, vh.Y, vh.Z); double real = v.X - this._layerRadius; // find extrapolated elevation in middle hyp. float xe = (this._elevatedVertices[v1].X + this._elevatedVertices[v3].X) / 2; float ye = (this._elevatedVertices[v1].Y + this._elevatedVertices[v3].Y) / 2; float ze = (this._elevatedVertices[v1].Z + this._elevatedVertices[v3].Z) / 2; v = MathEngine.CartesianToSpherical(xe, ye, ze); double extrapolated = v.X - this._layerRadius; // variance Note: could be done w/out MathEngine by computing raw cartesian distance MaxVar = real - extrapolated; // recurse for potential childs until unit face MaxVar = Math.Max(MaxVar, FaceVariance(v2, mid_hyp_indice, v1)); MaxVar = Math.Max(MaxVar, FaceVariance(v3, mid_hyp_indice, v2)); } return(MaxVar); }
private void CreateMesh( double north, double south, double west, double east, int samples, string displacementFile, ref CustomVertex.PositionTextured[] vertices, ref short[] indices) { int upperBound = samples - 1; float scaleFactor = (float)1 / upperBound; double latrange = Math.Abs(north - south); double lonrange; if (west < east) { lonrange = east - west; } else { lonrange = 360.0f + east - west; } System.Drawing.Bitmap heightMap = null; try { heightMap = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(displacementFile); } catch {} vertices = new CustomVertex.PositionTextured[samples * samples]; for (int i = 0; i < samples; i++) { for (int j = 0; j < samples; j++) { double height = m_cloudBaseAltitude * World.Settings.VerticalExaggeration; if (heightMap != null) { double percentX = (double)j / (double)upperBound; double percentY = (double)i / (double)upperBound; if (percentX > 1) { percentX = 1; } if (percentY > 1) { percentY = 1; } int x = (int)(percentX * (heightMap.Width - 1)); int y = (int)(percentY * (heightMap.Height - 1)); height += m_displacementMultiplier * heightMap.GetPixel(x, y).R; } Vector3 pos = MathEngine.SphericalToCartesian( north - scaleFactor * latrange * i, west + scaleFactor * lonrange * j, this.World.EquatorialRadius + height); vertices[i * samples + j].X = pos.X; vertices[i * samples + j].Y = pos.Y; vertices[i * samples + j].Z = pos.Z; vertices[i * samples + j].Tu = j * scaleFactor; vertices[i * samples + j].Tv = i * scaleFactor; } } indices = new short[2 * upperBound * upperBound * 3]; for (int i = 0; i < upperBound; i++) { for (int j = 0; j < upperBound; j++) { indices[(2 * 3 * i * upperBound) + 6 * j] = (short)(i * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 1] = (short)((i + 1) * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 2] = (short)(i * samples + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 3] = (short)(i * samples + j + 1); indices[(2 * 3 * i * upperBound) + 6 * j + 4] = (short)((i + 1) * samples + j); indices[(2 * 3 * i * upperBound) + 6 * j + 5] = (short)((i + 1) * samples + j + 1); } } if (heightMap != null) { heightMap.Dispose(); } }