- Home /
areas(continents) on my spherical planet
Hey everyone, after messing around in unity for a while, i'v decided to start a real project..
For my new project i'm using a cube that is mapped to a sphere.
So far it's been ok, but now i'm stuck on getting 'areas' on the sphere.. How can i make a certain area of a specific size on a spherical surface? What i want to do once i can use areas on the sphere/cube, is make some sort of script that chooses what type of biome the area will be and on that area it will use noise to make a landscape relevant to the biome type.
But for now, i really would love to know, how do all of you calculate/define 'areas'... that's been my problem with quite a few things when i was still messing around in unity, and now....again.
Any help is very appreciated, thanks...
To make exactly i want to know more clear, i'm asking how something like this can work....
if (height == > radius * 1.0) // calculate the surface area, of the area higher than the radius*1
Question is how does one calculate the surface area and use it?
Answer by AlwaysSunny · Mar 18, 2015 at 03:24 PM
The Mesh class offers access to verticies. If your model origin is the sphere origin, you can iterate over your verts, collecting verts whose magnitude is greater-than N. Turning this into meaningful (useful) data about topology is not a trivial affair. Guess you could iterate over these collected "above sea level" points with an algorithm that builds "continent" objects from adjacent above-sea-level verts?
You can expect to become intimately familiar with this class if you want to analyze or affect meshes through scripting.
Ok thanks for the help, that makes sense and gives me a starting point of where to begin. I looked at the magnitude on the scripting api page. so basically this calculates the entire area??
"Returns the length of this vector (Read Only). The length of the vector is square root of (x*x+y*y+z*z)."
Or am I reading this wrong? Also, the "above sea level" approach was what i had in $$anonymous$$d.
Again, thanks for the reply!
I had something like this in $$anonymous$$d.. ][1]
So what would be the best ... or easiest to do? make noise, and above a certain point of noise, that area is a continent. or any other idea that is beter?
I implemented a noise function and added a hydrosphere... $$anonymous$$aking progress..
Now again, just to somehow get access to the parts above sea level...
If your noise generation function shares a 1:1 relationship with your verticies, you definitely can and should do this work using the raw noise data. It's waaaay cheaper to do the necessary work on an array of floats (noise heights) than an array of verts via magnitude calculation.
Exactly how you should get this data really depends on why you want it. In what format should it be returned? e.g. As a collection of verticies/faces (aka, making a sub mesh)? Will it be used as a way of establishing navigation for pathfinding? Establish what you want to do with this information to deter$$anonymous$$e the best format for storing and accessing it.
The algorithm which hands you this data in your preferred format will then be the cheapest method of deter$$anonymous$$ing that data.
Thanks! what you said about how to generate the noise was good for a performance boost, and is just a way better solution..
Now my only problem that remains is once again, to somehow make the areas that are above sea level into zones, where it would be easier to make noise and place objects on the continents... what i plan to do eventually is.. make different regions like a real world, desert,mountains, forest..... but only if i can somehow figure out how to use those that are above sea level......
$$anonymous$$aybe subdivide the areas above sea level to their own mesh?(its all 1 mesh right now...), then i will have more control of what i can do with those meshes above sea level?(each continent above sea level, has its own submesh..)
You really sound like you know how to work this kind of thing, so what in your opinion would be the best way to 'use/access' the continents through code?
also i can upload the project files if you want to have a look at the current situation...
And Finally, sorry for the long reply, again VERY $$anonymous$$UCH THAN$$anonymous$$S for the help!!
EDIT... Actually the part about mesh subdivision, sound like a great solution, any thoughts on this??
Full disclosure; I've never done anything quite like this, so any suggestions I give should be taken as peer brainstor$$anonymous$$g, not sage wisdom. Just a friendly warning! :)
Once you separate your world from six curved planes into arbitrary clusters of faces, you lose your 1:1 relationship to a 2D data set (your noise heights). Because they'll be of arbitrary size and shape, there'll be no cheap-n-easy way to access meaningful data about them. Suddenly you've got some chunks of faces floating in space and no real picture of how they relate to each other or your game world.
Note that this is not strictly important - it really depends on what ELSE you want to do. If literally all you want is different textures and vegetation per continent, none of this "record keeping" is necessary. Just make sub-meshes and retexture and use their faces and normals to establish flora positions. Raycasts against their colliders could give you limited info about topology if needed. If you need more than this, then you might wanna be clever about keeping your topology data accessible...
For more structured access, I'm thinking your Continent class could be a non-monobehavior object which has a vertex[] array which holds references to the verts it represents in your globe mesh. I'm thinking the dimensions of the vertex[] array should be a 1:1 match to globe$$anonymous$$esh.verticies. In other words, when you add a vertex to the array, you add it at the same index.
// adding vert #241, so in your loop, i = 241;
myContinent.verts[i] = globe$$anonymous$$esh.verts[i];
Your algorithm could look something like:
For all elements in the noise heights array: if the element hasn't already been exa$$anonymous$$ed by this function: add the index-pair to the list of exa$$anonymous$$ed index-pairs: if its value is above sea level: create a new continent object: add the corresponding mesh vertex to the continent's array, and...
Exa$$anonymous$$e all adjacent elements ...(x-1,y) ...(x+1,y) ...(x,y+1) ...etc. and add their index-pairs to the list of exa$$anonymous$$ed index-pairs. For each element you just exa$$anonymous$$ed, exa$$anonymous$$e their unexa$$anonymous$$ed neighbors, and so forth until all adjacent above-sea-level elements have their corresponding vertex added to the continent's array. Then you've got yourself a continent.
I don't know how your noise heights array works to achieve seamless planes (very slick btw), but you'll have to account for whatever weirdness will arise around the edges, e.g. can't exa$$anonymous$$e this direction beyond this edge, so your algorithm needs to "loop around" into the next array in a sensible manner to continue checking heights. Either that, or allow continents to ter$$anonymous$$ate at seams and "attach" adjacent ones together at their shared seam after the fact.
You have not picked a simple task, I'm afraid. And I should mention that there may be a better way to go about this task, especially if you need less information. This is just what I, with my limited grasp on this topic, would try first.
Your answer
Follow this Question
Related Questions
How to place objects from a 2d plane around a sphere? 1 Answer
planetary level of detail system (cubesphere) 0 Answers
Is it possible to generate a high-poly spherical model from a mercator-projection heightmap? 1 Answer
Angle between two vectors rotated by quaternion? 0 Answers
How to create a terrain in a sphere with Perlin Noise 0 Answers