private vertex_structure normalize(vertex_structure curvert) { curvert.X = curvert.X / curvert.elevation; curvert.Y = curvert.Y / curvert.elevation; curvert.Z = curvert.Z / curvert.elevation; return(curvert); }
private vertex_structure flattenvert(vertex_structure curvert) { //Map the X,Y corrdinates based on sphereical trig and the normalized verticie curvert.X = (float)(Math.Asin(curvert.X) / Math.PI + 0.5F) * 100F; curvert.Y = (float)(Math.Asin(curvert.Y) / Math.PI + 0.5F) * 100F; curvert.Z = 0; return(curvert); }
private vertex_structure findmidpoint(vertex_structure vert1, vertex_structure vert2) { vertex_structure tempvert = new vertex_structure(); tempvert.X = (vert1.X + vert2.X) / 2; tempvert.Y = (vert1.Y + vert2.Y) / 2; tempvert.Z = (vert1.Z + vert2.Z) / 2; // Find the midpoint given our two verticies return(tempvert); }
private vertex_structure displacemidpoint(vertex_structure vert1, vertex_structure vert2) { vertex_structure midpoint; radius = (float)((Math.Sqrt(Math.Pow(vert1.X, 2.0) + Math.Pow(vert1.Y, 2.0) + Math.Pow(vert1.Z, 2.0)) + Math.Sqrt(Math.Pow(vert2.X, 2.0) + Math.Pow(vert2.Y, 2.0) + Math.Pow(vert2.Z, 2.0))) / 2.0); //Fudge on the radius retrieval a little bit by averaging the distance from 0,0,0 of the two passed-in points. midpoint = findmidpoint(vert1, vert2); // first, find the midpoint. return(doOneMidpoint(midpoint)); // Pass it in to be fractally displaced. }
private vertex_structure rotatevertZ(vertex_structure curvert, int angle) { Single ang = (float)(angle * (Math.PI / 180.0F) * -1.0F); Vector4 tempvect = new Vector4(curvert.X, curvert.Y, curvert.Z, 0.0F); // Cheat and use the nice built in matrix transformations. //Used to be below in C#, will it work like this?!?! //tempvect = tempvect.Transform(tempvect, Matrix.RotationZ(ang)); // tempvect = Microsoft.DirectX.Vector4.Transform(tempvect, Matrix.RotationZ(ang)); curvert.X = tempvect.X; curvert.Y = tempvect.Y; curvert.Z = tempvect.Z; // Find the maximum X and maximum Y values for our flatt} geosphere so we can use them later when we scale everything // into a two dimmensional array in the maperize . if (curvert.X < flatmapXmin) { flatmapXmin = curvert.X; } if (curvert.X > flatmapXmax) { flatmapXmax = curvert.X; } if (curvert.Y < flatmapYmin) { flatmapXmin = curvert.Y; } if (curvert.Y > flatmapYmax) { flatmapXmax = curvert.Y; } return(curvert); }
private vertex_structure findmidpoint(vertex_structure vert1, vertex_structure vert2) { vertex_structure tempvert = new vertex_structure(); tempvert.X = (vert1.X + vert2.X) / 2.0F; tempvert.Y = (vert1.Y + vert2.Y) / 2.0F; tempvert.Z = (vert1.Z + vert2.Z) / 2.0F; // Find the midpoint given our two verticies return tempvert; }
private zobject[,] zobjectmap = new zobject[160, 160]; //Objects on the zoomed in map, viewable by the player. #endregion Fields #region Constructors public Geosphere(Single scale, Single sd, int rough, int displace, int icecap) { // Set up our inital geosphere. rnd = new Random((int)sd); iceCapRange = icecap; planetScaler = scale; displaceMag = displace; roughness = rough; seed = sd; int i; for (i = 0; i < 12; i++) verticies[i] = new vertex_structure(); for (i = 0; i < 11000; i++) { oldMidpoints[i] = new vertex_structure(); newMidpoints[i] = new vertex_structure(); } for (i = 0; i < 32400; i++) { triangles[i] = new triangles_structure(); } // The initial coorodinates of our geosphere. Prob could have done one real time. // Drew it in milkshap rather and copied the corodinates. #region INITAL COORDINATES verticies[0].X = -26.2865543F / planetScaler; verticies[0].Y = 0.0F / planetScaler; verticies[0].Z = -42.53254F / planetScaler; verticies[1].X = 26.2865543F / planetScaler; verticies[1].Y = 0.0F / planetScaler; verticies[1].Z = -42.53254F / planetScaler; verticies[2].X = 0.0F / planetScaler; verticies[2].Y = -42.53254F / planetScaler; verticies[2].Z = -26.2865543F / planetScaler; verticies[3].X = -42.53254F / planetScaler; verticies[3].Y = -26.2865543F / planetScaler; verticies[3].Z = 0.0F / planetScaler; verticies[4].X = 0.0F / planetScaler; verticies[4].Y = -42.53254F / planetScaler; verticies[4].Z = 26.2865543F / planetScaler; verticies[5].X = 42.53254F / planetScaler; verticies[5].Y = -26.2865543F / planetScaler; verticies[5].Z = 0.0F / planetScaler; verticies[6].X = 42.53254F / planetScaler; verticies[6].Y = 26.2865543F / planetScaler; verticies[6].Z = 0.0F / planetScaler; verticies[7].X = 26.2865543F / planetScaler; verticies[7].Y = 0.0F / planetScaler; verticies[7].Z = 42.53254F / planetScaler; verticies[8].X = -26.2865543F / planetScaler; verticies[8].Y = 0.0F / planetScaler; verticies[8].Z = 42.53254F / planetScaler; verticies[9].X = 0.0F / planetScaler; verticies[9].Y = 42.53254F / planetScaler; verticies[9].Z = 26.2865543F / planetScaler; verticies[10].X = 0.0F / planetScaler; verticies[10].Y = 42.53254F / planetScaler; verticies[10].Z = -26.2865543F / planetScaler; verticies[11].X = -42.53254F / planetScaler; verticies[11].Y = 26.2865543F / planetScaler; verticies[11].Z = 0.0F / planetScaler; // Assign each triangle 3 verticies. triangles[0].A = verticies[0]; triangles[0].B = verticies[2]; triangles[0].C = verticies[1]; triangles[1].A = verticies[9]; triangles[1].B = verticies[8]; triangles[1].C = verticies[11]; triangles[2].A = verticies[5]; triangles[2].B = verticies[2]; triangles[2].C = verticies[4]; triangles[3].A = verticies[10]; triangles[3].B = verticies[6]; triangles[3].C = verticies[9]; triangles[4].A = verticies[11]; triangles[4].B = verticies[0]; triangles[4].C = verticies[10]; triangles[5].A = verticies[6]; triangles[5].B = verticies[5]; triangles[5].C = verticies[7]; triangles[6].A = verticies[0]; triangles[6].B = verticies[3]; triangles[6].C = verticies[2]; triangles[7].A = verticies[7]; triangles[7].B = verticies[4]; triangles[7].C = verticies[8]; triangles[8].A = verticies[6]; triangles[8].B = verticies[1]; triangles[8].C = verticies[5]; triangles[9].A = verticies[8]; triangles[9].B = verticies[4]; triangles[9].C = verticies[3]; triangles[10].A = verticies[10]; triangles[10].B = verticies[1]; triangles[10].C = verticies[6]; triangles[11].A = verticies[8]; triangles[11].B = verticies[3]; triangles[11].C = verticies[11]; triangles[12].A = verticies[10]; triangles[12].B = verticies[0]; triangles[12].C = verticies[1]; triangles[13].A = verticies[6]; triangles[13].B = verticies[7]; triangles[13].C = verticies[9]; triangles[14].A = verticies[11]; triangles[14].B = verticies[3]; triangles[14].C = verticies[0]; triangles[15].A = verticies[7]; triangles[15].B = verticies[5]; triangles[15].C = verticies[4]; triangles[16].A = verticies[3]; triangles[16].B = verticies[4]; triangles[16].C = verticies[2]; triangles[17].A = verticies[9]; triangles[17].B = verticies[11]; triangles[17].C = verticies[10]; triangles[18].A = verticies[1]; triangles[18].B = verticies[2]; triangles[18].C = verticies[5]; triangles[19].A = verticies[9]; triangles[19].B = verticies[7]; triangles[19].C = verticies[8]; #endregion maxtriangles = 20; // We start with 20 triangles / 11 verticies maxElev = 50.0F / planetScaler; minElev = 50.0F / planetScaler; radius = 50.0F / planetScaler; for (i = 0; i < 11000; i++) { oldMidpoints[i].X = 99; newMidpoints[i].X = 98; } }
// Now, make sure we don't do the same midpoint twice below. private vertex_structure doOneMidpoint(vertex_structure midpoint) { Single lengMult; //Length scaler to ext} the vert to the outer imaginary sphere around the geosphere. int c = 0; double midpnt = 0.0; while (c != 10999) { if (oldMidpoints[c].X == 99) { //We've searched the array, we have not done this midpoint before. oldMidpoints[c] = midpoint; //Set oldmidpoint to the un-displaced midpoint for future refs midpnt = Math.Sqrt(Math.Pow(midpoint.X, 2.0F) + Math.Pow(midpoint.Y, 2.0F) + Math.Pow(midpoint.Z, 2.0F)); midpoint.elevation = (float)midpnt; // Calculate the distance of this midpoint from 0,0,0 lengMult = (radius / midpoint.elevation); // Calculate a multiplier, to ext} the midpoint to the edge of the sphere. if (rnd.NextDouble() < 0.5F || Math.Abs(midpoint.Y) > iceCapRange) { midpoint.X = (midpoint.X * lengMult); // Ext} the ray to edge of invisible sphere midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); lengMult = (Convert.ToSingle(displaceMag) / 1200.0F * Convert.ToSingle(rnd.NextDouble())) + 1.0F; //lengMult = 1 midpoint.X = (midpoint.X * lengMult); // Ext} a bit fractally. midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); } else { midpoint.X = (midpoint.X * lengMult); // Ext} the ray to edge of invisible sphere midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); lengMult = 1.0F - (Convert.ToSingle(displaceMag) / 1200.0F * Convert.ToSingle(rnd.NextDouble())); //lengMult = 1 midpoint.X = (midpoint.X * lengMult); // Shrink a bit fractally midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); } midpnt = Math.Sqrt(Math.Pow(midpoint.X, 2.0F) + Math.Pow(midpoint.Y, 2.0F) + Math.Pow(midpoint.Z, 2.0F)); midpoint.elevation = (float)midpnt; // test for our maximum and minimum distances from 0,0,0. if (midpoint.elevation > maxElev) maxElev = midpoint.elevation; if (midpoint.elevation < minElev) minElev = midpoint.elevation; newMidpoints[c] = midpoint; //Set the newmidpoint to the newly displaced midpoint. return midpoint; } if ((oldMidpoints[c].X == midpoint.X) && (oldMidpoints[c].Y == midpoint.Y) && (oldMidpoints[c].Z == midpoint.Z)) { //We may have done this midpoint before if ((oldMidpoints[c].X == newMidpoints[c].X) && (oldMidpoints[c].Y == newMidpoints[c].Y) && (oldMidpoints[c].Z == newMidpoints[c].Z)) { //Nope, we have not done this midpoint before, we need to update newmidpoints(c) // with a newly calculated value. midpnt = Math.Sqrt(Math.Pow(midpoint.X, 2.0F) + Math.Pow(midpoint.Y, 2.0F) + Math.Pow(midpoint.Z, 2.0F)); midpoint.elevation = (float)midpnt; lengMult = (radius / midpoint.elevation); if (rnd.NextDouble() < 0.5F || Math.Abs(midpoint.Y) > iceCapRange) { midpoint.X = (midpoint.X * lengMult); midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); lengMult = (Convert.ToSingle(displaceMag) / 1200.0F * Convert.ToSingle(rnd.NextDouble())) + 1.0F; midpoint.X = (midpoint.X * lengMult); midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); } else { midpoint.X = (midpoint.X * lengMult); midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); lengMult = 1.0F - (Convert.ToSingle(displaceMag) / 1200.0F * Convert.ToSingle(rnd.NextDouble())); midpoint.X = (midpoint.X * lengMult); midpoint.Y = (midpoint.Y * lengMult); midpoint.Z = (midpoint.Z * lengMult); } midpnt = Math.Sqrt(Math.Pow(midpoint.X, 2.0F) + Math.Pow(midpoint.Y, 2.0F) + Math.Pow(midpoint.Z, 2.0F)); midpoint.elevation = (float)midpnt; newMidpoints[c] = midpoint; if (midpoint.elevation > maxElev) maxElev = midpoint.elevation; if (midpoint.elevation < minElev) minElev = midpoint.elevation; return midpoint; } else { return newMidpoints[c]; // We//ve done this midpoint before, simply return previously updated value. } } c++; } return newMidpoints[1]; // We failed every condition above. Return something! }
private vertex_structure displacemidpoint(vertex_structure vert1, vertex_structure vert2) { vertex_structure midpoint; double rApprox1 = 0.0F; double rApprox2 = 0.0F; rApprox1 = Math.Sqrt((vert1.X * vert1.X) + (vert1.Y * vert1.Y) + (vert1.Z * vert1.Z)); rApprox2 = Math.Sqrt((vert2.X * vert2.X) + (vert2.Y * vert2.Y) + (vert2.Z * vert2.Z)); radius = Convert.ToSingle((rApprox1 + rApprox2) / 2.0F); //Fudge on the radius retrieval a little bit by averaging the distance from 0,0,0 of the two passed-in points. midpoint = findmidpoint(vert1, vert2); // first, find the midpoint. return doOneMidpoint(midpoint); // Pass it in to be fractally displaced. }
private vertex_structure rotatevertZ(vertex_structure curvert, int angle) { Single ang = (float)(angle * (Math.PI / 180.0F) * -1.0F); Vector4 tempvect = new Vector4(curvert.X, curvert.Y, curvert.Z, 0.0F); // Cheat and use the nice built in matrix transformations. //Used to be below in C#, will it work like this?!?! //tempvect = tempvect.Transform(tempvect, Matrix.RotationZ(ang)); // tempvect = Microsoft.DirectX.Vector4.Transform(tempvect, Matrix.RotationZ(ang)); curvert.X = tempvect.X; curvert.Y = tempvect.Y; curvert.Z = tempvect.Z; // Find the maximum X and maximum Y values for our flatt} geosphere so we can use them later when we scale everything // into a two dimmensional array in the maperize . if (curvert.X < flatmapXmin) flatmapXmin = curvert.X; if (curvert.X > flatmapXmax) flatmapXmax = curvert.X; if (curvert.Y < flatmapYmin) flatmapXmin = curvert.Y; if (curvert.Y > flatmapYmax) flatmapXmax = curvert.Y; return curvert; }
private vertex_structure normalize(vertex_structure curvert) { curvert.X = curvert.X / curvert.elevation; curvert.Y = curvert.Y / curvert.elevation; curvert.Z = curvert.Z / curvert.elevation; return curvert; }
private void maperize(int Maxtraingles) { Single sumcount; Single cellsum; //int lastnotnull; vertex_structure[] allpoints = new vertex_structure[61440]; int i, iY, iX; int tX; int ty; int txmid; int tymid; int txmidc; int tymidc; int deresoluter = 4; // Factor that we want to deresolute the master map by to get the mini-map. /////// Initialize the arrays int mapsizex = 140 * deresoluter - 1; int mapsizey = 70 * deresoluter - 1; Single maxXvert = 70.71051F; Single maxYvert = 35.35536F; for (i = 0; i < 61439; i++) { allpoints[i].color = 0.0F; } for (iY = 0; iY < mapsizey; iY++) { for (iX = 0; iX < mapsizex; iX++) { map[iX, iY].color = 0.0F; map[iX, iY].elevation = 0; //Well use the elevation member of the vertex_structure as a counter, // count the number of vertecies that have been added to this array element. } } iX = 0; // Stuff all vertcies into a one dimensional array for (i = 0; i < maxtriangles; i++) { allpoints[iX] = triangles[i].A; allpoints[iX + 1] = triangles[i].B; allpoints[iX + 2] = triangles[i].C; iX = iX + 3; } // Figure out the position of the current verticie on our map, and pop it//s elevation into that index. // Summing for each vertex popped into each element of the map array and using a counter to count how many // we've popped in there. Later well average the elevation of the midpoint by dividing by that counter. // First for/} loop, do all points of each triangle. // Second for/} Loop, do all the midpoints on each triangle. for (i = 0; i < (maxtriangles * 3); i++) { ///// //Scaled from 0 to 1 and multiplied by the appropriate dimension of the map array, and take Convert.ToInt32 tX = Convert.ToInt32(MathFunctions.scaleValue(allpoints[i].X, maxXvert, -maxXvert, 1.0F, 0.0F) * mapsizex); ty = Convert.ToInt32(MathFunctions.scaleValue(allpoints[i].Y, maxYvert, -maxYvert, 1.0F, 0.0F) * mapsizey); ///// sum the total value in each position. map[tX, ty].color = map[tX, ty].color + allpoints[i].color; ///// number of verticies that are in this element. map[tX, ty].elevation = map[tX, ty].elevation + 1; } for (i = 0; i < (maxtriangles * 3); i += 3) { ///// //Scaled from 0 to 1 and multiplied by the appropriate dimension of the map array, and take Convert.ToInt32 tX = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].X + allpoints[i + 1].X) / 2, maxXvert, -maxXvert, 1, 0) * mapsizex); ty = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].Y + allpoints[i + 1].Y) / 2, maxYvert, -maxYvert, 1, 0) * mapsizey); txmid = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i + 1].X + allpoints[i + 2].X) / 2, maxXvert, -maxXvert, 1, 0) * mapsizex); tymid = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i + 1].Y + allpoints[i + 2].Y) / 2, maxYvert, -maxYvert, 1, 0) * mapsizey); txmidc = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].X + allpoints[i + 2].X) / 2, maxXvert, -maxXvert, 1, 0) * mapsizex); tymidc = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].Y + allpoints[i + 2].Y) / 2, maxYvert, -maxYvert, 1, 0) * mapsizey); ///// sum the total value in each position. map[tX, ty].color = map[tX, ty].color + (allpoints[i].color + allpoints[i + 1].color) / 2; map[txmid, tymid].color = map[txmid, tymid].color + (allpoints[i + 1].color + allpoints[i + 2].color) / 2; map[txmidc, tymidc].color = map[txmidc, tymidc].color + (allpoints[i].color + allpoints[i + 2].color) / 2; ///// number of verticies that are in this element. map[tX, ty].elevation = map[tX, ty].elevation + 1; map[txmid, tymid].elevation = map[txmid, tymid].elevation + 1; map[txmidc, tymidc].elevation = map[txmidc, tymidc].elevation + 1; } ////// Center the map and figure out the color of each elevation point. for (iY = 0; iY < mapsizey; iY++) { for (iX = 0; iX < mapsizex; iX++) { ////centering map[iX, iY].X = iX - mapsizex / 2; map[iX, iY].Y = iY - mapsizey / 2; map[iX, iY].Z = 0.0F; if (map[iX, iY].color > 0.0) { // if more one vertex has been stuffed into this element, average them. map[iX, iY].color = map[iX, iY].color / map[iX, iY].elevation; } } } ///// Fill in all the empty cells (in the middle of two filled cells) with the average of the adjacent filled cells. ///// Fill in the blanks basically. int left, right; for (iY = 0; iY < mapsizey; iY++) { iX = 1; while (iX < mapsizex + 1) { cellsum = 0.0F; sumcount = 0.0F; if (map[iX, iY].color == 0.0) { left = iX; right = iX; // move to the right until we reach a filled cell or the "edge" do { right++; }while (map[right + 1, iY].color == 0.0 || right != mapsizex); // move to the left.... do { left--; } while (map[left - 1, iY].color == 0.0 || left != 1); // put the filled cell into the total, sum count. if (left > 0 && map[left - 1, iY].color != 0.0) { cellsum = cellsum + map[left - 1, iY].color; //Sum up the elevation. sumcount = sumcount + 1.0F; //Add 1 to the number of filled cells in this loop pass. } // put the filled cell into the total, sum count. if (right < mapsizex + 1 && map[right + 1, iY].color != 0.0) { cellsum = cellsum + map[right + 1, iY].color; sumcount = sumcount + 1.0F; } cellsum = cellsum / sumcount; // fill in the empty cells. if (left == 1) { left = 0; } for (i = left; i < right; i++) { map[i, iY].color = cellsum; } cellsum = 0.0F; sumcount = 0; } iX++; } } //////////// Single texcor = 0.0F; int flipper = 1; // To re-cycle through the texture map backwards once we reach the }. // Changes our dirrection. Random rnd = new Random(OuterSpace.thisPlanet.uSeed); for (iX = 0; iX < mapsizex; iX++) { texcor = (float)texcor + 0.01F * flipper + (float)rnd.NextDouble() / 200F; for (iY = 0; iY < mapsizey; iY++) { map[iX, iY].texcor = texcor; if (texcor > 1) { map[iX, iY].texcor = 1; texcor = 0; flipper = flipper * -1; } } } i = 0; for (iY = 0; iY < mapsizey; iY += deresoluter) { for (iX = 0; iX < mapsizex + 1; iX += deresoluter) { // Use the points organized in a deresoluter dimensional array to make a list of quads. triangles[i].A = map[iX, iY + deresoluter]; triangles[i].B = map[iX, iY]; triangles[i].C = map[iX + deresoluter, iY + deresoluter]; triangles[i + 1].A = map[iX, iY]; triangles[i + 1].B = map[iX + deresoluter, iY]; triangles[i + 1].C = map[iX + deresoluter, iY + deresoluter]; i += 2; } } maxtriangles = i; for (i = 0; i < maxtriangles; i++) { triangles[i].A.normal = new Vector3(0.0F, 0.0F, -1.0F); triangles[i].B.normal = new Vector3(0.0F, 0.0F, -1.0F); triangles[i].C.normal = new Vector3(0.0F, 0.0F, -1.0F); } OuterSpace.thisPlanet.PlanetMaps = new PlanetMap(mapsizex, mapsizey); //3-10-06 ... // Resize our life and mineral maps to represent the size of our terrian map, // and make the life and minerals. OuterSpace.thisPlanet.mineralmap = null; OuterSpace.thisPlanet.mineralmap = new bool[mapsizex, mapsizey]; if (OuterSpace.thisPlanet.MinDensity > 0) { makeminerals(); } //Redim OuterSpace.thisPlanet.lifemap[mapsizex, mapsizey]; OuterSpace.thisPlanet.lifemap = null; OuterSpace.thisPlanet.lifemap = new lifeforms[mapsizex, mapsizey]; makelife(); }
// Now, make sure we don't do the same midpoint twice below. private vertex_structure doOneMidpoint(vertex_structure midpoint) { Double lengMult; //Length scaler to ext} the vert to the outer imaginary sphere around the geosphere. Random rnd = new Random(OuterSpace.thisPlanet.uSeed); int c = 0; while (c != 10999) { seed = (float)(seed - 0.001); if (oldMidpoints[c].X == 99) { //We've searched the array, we have not done this midpoint before. oldMidpoints[c] = midpoint; //Set oldmidpoint to the un-displaced midpoint for future refs midpoint.elevation = (float)Math.Sqrt(Math.Pow(midpoint.X, 2.0) + Math.Pow(midpoint.Y, 2.0) + Math.Pow(midpoint.Z, 2.0)); // Calculate the distance of this midpoint from 0,0,0 lengMult = (radius / midpoint.elevation); // Calculate a multiplier, to ext} the midpoint to the edge of the sphere. if (rnd.NextDouble() < 0.5 || Math.Abs(midpoint.Y) > iceCapRange) { midpoint.X = (float)(midpoint.X * lengMult); // Ext} the ray to edge of invisible sphere midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); lengMult = (displaceMag / 1200 * rnd.NextDouble()) + 1; //lengMult = 1 midpoint.X = (float)(midpoint.X * lengMult); // Ext} a bit fractally. midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); } else { midpoint.X = (float)(midpoint.X * lengMult); // Ext} the ray to edge of invisible sphere midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); lengMult = 1 - (displaceMag / 1200 * rnd.NextDouble()); //lengMult = 1 midpoint.X = (float)(midpoint.X * lengMult); // Shrink a bit fractally midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); } midpoint.elevation = (float)Math.Sqrt(Math.Pow(midpoint.X, 2.0) + Math.Pow(midpoint.Y, 2.0) + Math.Pow(midpoint.Z, 2.0)); // test for our maximum and minimum distances from 0,0,0. if (midpoint.elevation > maxElev) { maxElev = midpoint.elevation; } if (midpoint.elevation < minElev) { minElev = midpoint.elevation; } newMidpoints[c] = midpoint; //Set the newmidpoint to the newly displaced midpoint. return(midpoint); } if ((oldMidpoints[c].X == midpoint.X) && (oldMidpoints[c].Y == midpoint.Y) && (oldMidpoints[c].Z == midpoint.Z)) { //We may have done this midpoint before if ((oldMidpoints[c].X == newMidpoints[c].X) && (oldMidpoints[c].Y == newMidpoints[c].Y) && (oldMidpoints[c].Z == newMidpoints[c].Z)) { //Nope, we have not done this midpoint before, we need to update newmidpoints(c) // with a newly calculated value. midpoint.elevation = (float)Math.Sqrt(Math.Pow(midpoint.X, 2.0) + Math.Pow(midpoint.Y, 2.0) + Math.Pow(midpoint.Z, 2.0)); lengMult = (radius / midpoint.elevation); if (rnd.NextDouble() < 0.5 || Math.Abs(midpoint.Y) > iceCapRange) { midpoint.X = (float)(midpoint.X * lengMult); midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); lengMult = (displaceMag / 1200 * rnd.NextDouble()) + 1; midpoint.X = (float)(midpoint.X * lengMult); midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); } else { midpoint.X = (float)(midpoint.X * lengMult); midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); lengMult = 1 - (displaceMag / 1200 * rnd.NextDouble()); midpoint.X = (float)(midpoint.X * lengMult); midpoint.Y = (float)(midpoint.Y * lengMult); midpoint.Z = (float)(midpoint.Z * lengMult); } midpoint.elevation = (float)Math.Sqrt(Math.Pow(midpoint.X, 2.0) + Math.Pow(midpoint.Y, 2.0) + Math.Pow(midpoint.Z, 2.0)); newMidpoints[c] = midpoint; if (midpoint.elevation > maxElev) { maxElev = midpoint.elevation; } if (midpoint.elevation < minElev) { minElev = midpoint.elevation; } return(midpoint); } else { return(newMidpoints[c]); // We//ve done this midpoint before, simply return previously updated value. } } c++; } return(newMidpoints[1]); // We failed every condition above. Return something! }
private vertex_structure flattenvert(vertex_structure curvert) { //Map the X,Y corrdinates based on sphereical trig and the normalized verticie curvert.X = (float)(Math.Asin(curvert.X) / Math.PI + 0.5F) * 100.0F; curvert.Y = (float)(Math.Asin(curvert.Y) / Math.PI + 0.5F) * 100.0F; curvert.Z = 0.0F; return curvert; }
public Geosphere(Single scale, Single sd, int rough, int displace, int icecap) { // Set up our inital geosphere. int i; iceCapRange = icecap; planetScaler = scale; displaceMag = displace; roughness = rough; seed = sd; for (i = 0; i < 11; i++) { verticies[i] = new vertex_structure(); } for (i = 0; i < 10999; i++) { oldMidpoints[i] = new vertex_structure(); newMidpoints[i] = new vertex_structure(); } for (i = 0; i < 32399; i++) { triangles[i] = new triangles_structure(); } // The initial coorodinates of our geosphere. Prob could have done one real time. // Drew it in milkshap rather and copied the corodinates. verticies[0].X = -26.2865543F / planetScaler; verticies[0].Y = 0.0F / planetScaler; verticies[0].Z = -42.53254F / planetScaler; verticies[1].X = 26.2865543F / planetScaler; verticies[1].Y = 0.0F / planetScaler; verticies[1].Z = -42.53254F / planetScaler; verticies[2].X = 0.0F / planetScaler; verticies[2].Y = -42.53254F / planetScaler; verticies[2].Z = -26.2865543F / planetScaler; verticies[3].X = -42.53254F / planetScaler; verticies[3].Y = -26.2865543F / planetScaler; verticies[3].Z = 0.0F / planetScaler; verticies[4].X = 0.0F / planetScaler; verticies[4].Y = -42.53254F / planetScaler; verticies[4].Z = 26.2865543F / planetScaler; verticies[5].X = 42.53254F / planetScaler; verticies[5].Y = -26.2865543F / planetScaler; verticies[5].Z = 0.0F / planetScaler; verticies[6].X = 42.53254F / planetScaler; verticies[6].Y = 26.2865543F / planetScaler; verticies[6].Z = 0.0F / planetScaler; verticies[7].X = 26.2865543F / planetScaler; verticies[7].Y = 0.0F / planetScaler; verticies[7].Z = 42.53254F / planetScaler; verticies[8].X = -26.2865543F / planetScaler; verticies[8].Y = 0.0F / planetScaler; verticies[8].Z = 42.53254F / planetScaler; verticies[9].X = 0.0F / planetScaler; verticies[9].Y = 42.53254F / planetScaler; verticies[9].Z = 26.2865543F / planetScaler; verticies[10].X = 0.0F / planetScaler; verticies[10].Y = 42.53254F / planetScaler; verticies[10].Z = -26.2865543F / planetScaler; verticies[11].X = -42.53254F / planetScaler; verticies[11].Y = 26.2865543F / planetScaler; verticies[11].Z = 0.0F / planetScaler; // Assign each triangle 3 verticies. triangles[0].A = verticies[0]; triangles[0].B = verticies[2]; triangles[0].C = verticies[1]; triangles[1].A = verticies[9]; triangles[1].B = verticies[8]; triangles[1].C = verticies[11]; triangles[2].A = verticies[5]; triangles[2].B = verticies[2]; triangles[2].C = verticies[4]; triangles[3].A = verticies[10]; triangles[3].B = verticies[6]; triangles[3].C = verticies[9]; triangles[4].A = verticies[11]; triangles[4].B = verticies[0]; triangles[4].C = verticies[10]; triangles[5].A = verticies[6]; triangles[5].B = verticies[5]; triangles[5].C = verticies[7]; triangles[6].A = verticies[0]; triangles[6].B = verticies[3]; triangles[6].C = verticies[2]; triangles[7].A = verticies[7]; triangles[7].B = verticies[4]; triangles[7].C = verticies[8]; triangles[8].A = verticies[6]; triangles[8].B = verticies[1]; triangles[8].C = verticies[5]; triangles[9].A = verticies[8]; triangles[9].B = verticies[4]; triangles[9].C = verticies[3]; triangles[10].A = verticies[10]; triangles[10].B = verticies[1]; triangles[10].C = verticies[6]; triangles[11].A = verticies[8]; triangles[11].B = verticies[3]; triangles[11].C = verticies[11]; triangles[12].A = verticies[10]; triangles[12].B = verticies[0]; triangles[12].C = verticies[1]; triangles[13].A = verticies[6]; triangles[13].B = verticies[7]; triangles[13].C = verticies[9]; triangles[14].A = verticies[11]; triangles[14].B = verticies[3]; triangles[14].C = verticies[0]; triangles[15].A = verticies[7]; triangles[15].B = verticies[5]; triangles[15].C = verticies[4]; triangles[16].A = verticies[3]; triangles[16].B = verticies[4]; triangles[16].C = verticies[2]; triangles[17].A = verticies[9]; triangles[17].B = verticies[11]; triangles[17].C = verticies[10]; triangles[18].A = verticies[1]; triangles[18].B = verticies[2]; triangles[18].C = verticies[5]; triangles[19].A = verticies[9]; triangles[19].B = verticies[7]; triangles[19].C = verticies[8]; maxtriangles = 20; // We start with 20 triangles / 11 verticies maxElev = 50.0F / planetScaler; minElev = 50.0F / planetScaler; radius = 50.0F / planetScaler; for (i = 0; i < 10999; i++) { oldMidpoints[i].X = 99; newMidpoints[i].X = 98; } }
private void maperize(int Maxtraingles) { Single sumcount; Single cellsum; //int lastnotnull; vertex_structure[] allpoints = new vertex_structure[61440]; int i, iY, iX; int tX; int ty; int txmid; int tymid; int txmidc; int tymidc; int deresoluter = 4; // Factor that we want to deresolute the master map by to get the mini-map. /////// Initialize the arrays int mapsizex = 140 * deresoluter - 1; int mapsizey = 70 * deresoluter - 1; Single maxXvert = 70.71051F; Single maxYvert = 35.35536F; for (i = 0; i < 61440; i++) allpoints[i].color = 0.0F; for (iY = 0; iY <= mapsizey; iY++) { for (iX = 0; iX <= mapsizex; iX++) { map[iX, iY].color = 0.0F; map[iX, iY].elevation = 0; //Well use the elevation member of the vertex_structure as a counter, // count the number of vertecies that have been added to this array element. } } iX = 0; // Stuff all vertcies into a one dimensional array for (i = 0; i < maxtriangles; i++) { allpoints[iX] = triangles[i].A; allpoints[iX + 1] = triangles[i].B; allpoints[iX + 2] = triangles[i].C; iX = iX + 3; } // Figure out the position of the current verticie on our map, and pop it//s elevation into that index. // Summing for each vertex popped into each element of the map array and using a counter to count how many // we've popped in there. Later well average the elevation of the midpoint by dividing by that counter. // First for/} loop, do all points of each triangle. // Second for/} Loop, do all the midpoints on each triangle. for (i = 0; i < (maxtriangles * 3); i++) { ///// //Scaled from 0 to 1 and multiplied by the appropriate dimension of the map array, and take Convert.ToInt32 tX = Convert.ToInt32(MathFunctions.scaleValue(allpoints[i].X, maxXvert, -maxXvert, 1.0F, 0.0F) * mapsizex); ty = Convert.ToInt32(MathFunctions.scaleValue(allpoints[i].Y, maxYvert, -maxYvert, 1.0F, 0.0F) * mapsizey); ///// sum the total value in each position. map[tX, ty].color = map[tX, ty].color + allpoints[i].color; ///// number of verticies that are in this element. map[tX, ty].elevation = map[tX, ty].elevation + 1; } for (i = 0; i < (maxtriangles * 3); i += 3) { ///// //Scaled from 0 to 1 and multiplied by the appropriate dimension of the map array, and take Convert.ToInt32 tX = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].X + allpoints[i + 1].X) / 2.0F, maxXvert, -maxXvert, 1.0F, 0.0F) * mapsizex); ty = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].Y + allpoints[i + 1].Y) / 2.0F, maxYvert, -maxYvert, 1.0F, 0.0F) * mapsizey); txmid = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i + 1].X + allpoints[i + 2].X) / 2.0F, maxXvert, -maxXvert, 1.0F, 0.0F) * mapsizex); tymid = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i + 1].Y + allpoints[i + 2].Y) / 2.0F, maxYvert, -maxYvert, 1.0F, 0.0F) * mapsizey); txmidc = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].X + allpoints[i + 2].X) / 2.0F, maxXvert, -maxXvert, 1.0F, 0.0F) * mapsizex); tymidc = Convert.ToInt32(MathFunctions.scaleValue((allpoints[i].Y + allpoints[i + 2].Y) / 2.0F, maxYvert, -maxYvert, 1.0F, 0.0F) * mapsizey); ///// sum the total value in each position. map[tX, ty].color = map[tX, ty].color + (allpoints[i].color + allpoints[i + 1].color) / 2.0F; map[txmid, tymid].color = map[txmid, tymid].color + (allpoints[i + 1].color + allpoints[i + 2].color) / 2.0F; map[txmidc, tymidc].color = map[txmidc, tymidc].color + (allpoints[i].color + allpoints[i + 2].color) / 2.0F; ///// number of verticies that are in this element. map[tX, ty].elevation = map[tX, ty].elevation + 1; map[txmid, tymid].elevation = map[txmid, tymid].elevation + 1; map[txmidc, tymidc].elevation = map[txmidc, tymidc].elevation + 1; } ////// Center the map and figure out the color of each elevation point. for (iY = 0; iY <= mapsizey; iY++) { for (iX = 0; iX <= mapsizex; iX++) { ////centering map[iX, iY].X = iX - mapsizex / 2; map[iX, iY].Y = iY - mapsizey / 2; map[iX, iY].Z = 0.0F; if (map[iX, iY].color > 0.0) { // if more one vertex has been stuffed into this element, average them. map[iX, iY].color = map[iX, iY].color / map[iX, iY].elevation; } } } ///// Fill in all the empty cells (in the middle of two filled cells) with the average of the adjacent filled cells. ///// Fill in the blanks basically. int left; int right; for (iY = 0; iY <= mapsizey; iY++) { iX = 1; while (iX < mapsizex + 1) { cellsum = 0.0F; sumcount = 0.0F; if (map[iX, iY].color == 0.0F) { left = iX; right = iX; // move to the right until we reach a filled cell or the "edge" while (!(map[right + 1, iY].color != 0.0F | right == mapsizex)) { right = right + 1; } // move to the left.... while (!(map[left - 1, iY].color != 0.0F | left == 1)) { left = left - 1; } // put the filled cell into the total, sum count. if (left > 0 & map[left - 1, iY].color != 0.0F) { cellsum = cellsum + map[left - 1, iY].color; //Sum up the elevation. sumcount = sumcount + 1.0F; //Add 1 to the number of filled cells in this loop pass. } // put the filled cell into the total, sum count. if (right < mapsizex + 1 & map[right + 1, iY].color != 0.0F) { cellsum = cellsum + map[right + 1, iY].color; sumcount = sumcount + 1.0F; } cellsum = cellsum / sumcount; // fill in the empty cells. if (left == 1) left = 0; for (i = left; i <= right; i++) { map[i, iY].color = cellsum; } cellsum = 0.0F; sumcount = 0.0F; } iX = iX + 1; } } //////////// Single texcor = 0.0F; int flipper = 1; // To re-cycle through the texture map backwards once we reach the end. // Changes our dirrection. Random rnd = new Random(OuterSpace.thisPlanet.uSeed); for (iX = 0; iX <= mapsizex; iX++) { texcor = (float)texcor + 0.01F * flipper + (float)rnd.NextDouble() / 200F; for (iY = 0; iY <= mapsizey; iY++) { map[iX, iY].texcor = texcor; if (texcor > 1) { map[iX, iY].texcor = 1; texcor = 0; flipper = flipper * -1; } } } i = 0; for (iY = 0; iY <= mapsizey; iY += deresoluter) { for (iX = 0; iX <= mapsizex + 1; iX += deresoluter) { // Use the points organized in a deresoluter dimensional array to make a list of quads. triangles[i].A = map[iX, iY + deresoluter]; triangles[i].B = map[iX, iY]; triangles[i].C = map[iX + deresoluter, iY + deresoluter]; triangles[i + 1].A = map[iX, iY]; triangles[i + 1].B = map[iX + deresoluter, iY]; triangles[i + 1].C = map[iX + deresoluter, iY + deresoluter]; i += 2; } } maxtriangles = i; for (i = 0; i <= maxtriangles; i++) { triangles[i].A.normal = new Vector3(0.0F, 0.0F, -1.0F); triangles[i].B.normal = new Vector3(0.0F, 0.0F, -1.0F); triangles[i].C.normal = new Vector3(0.0F, 0.0F, -1.0F); } OuterSpace.thisPlanet.PlanetMaps = new PlanetMap(mapsizex, mapsizey); //3-10-06 ... // Resize our life and mineral maps to represent the size of our terrian map, // and make the life and minerals. OuterSpace.thisPlanet.mineralmap = null; OuterSpace.thisPlanet.mineralmap = new bool[mapsizex, mapsizey]; if (OuterSpace.thisPlanet.MinDensity > 0) { makeminerals(); } //Redim OuterSpace.thisPlanet.lifemap[mapsizex, mapsizey]; OuterSpace.thisPlanet.lifemap = null; OuterSpace.thisPlanet.lifemap = new lifeforms[mapsizex, mapsizey]; makelife(); }
private vertex_structure displacemidpoint(vertex_structure vert1, vertex_structure vert2) { vertex_structure midpoint; radius = (float)((Math.Sqrt(Math.Pow(vert1.X, 2.0) + Math.Pow(vert1.Y, 2.0) + Math.Pow(vert1.Z, 2.0)) + Math.Sqrt(Math.Pow(vert2.X, 2.0) + Math.Pow(vert2.Y, 2.0) + Math.Pow(vert2.Z, 2.0))) / 2.0); //Fudge on the radius retrieval a little bit by averaging the distance from 0,0,0 of the two passed-in points. midpoint = findmidpoint(vert1, vert2); // first, find the midpoint. return doOneMidpoint(midpoint); // Pass it in to be fractally displaced. }