Voxel Planet
Ok, complicated question... I am trying to create a smooth voxel sphere shaped "planet," which can be edited in runtime, and have different materials, which have different names, so when you destroy a piece of material, it puts the same material into your inventory, so you can have mineral veins deep inside the planet to dig, somewhat like Empyrion Galactic Survival, or space engineers. I have basic knowledge of how minecraft style voxels work, but the smooth terrain system doesn't seem to work this way. Any help would be greatly appreciated. Thanks in advance!
Code it in the saem way you would a $$anonymous$$ecraft style system, except make the 'map' as close to a sphere as possible. i.e. only include a block if it is less than some radius distance. Once you have all that, use marching cubes algorithm ins$$anonymous$$d of a cubic algorithm to make the mesh. Fin.
How would I make the map a sphere, and how would I also implement the marching cubes algorithm? @Scribe
Set up some 3D array of points:
Point[,,] voxels = new Point[size, size, size];
then run through it and only make blocks in a circular radius:
for(x){
for(y){
for(z){
float distSq = x*x+y*y+z*z;
if(distSq < radius){
voxels[x, y, z] = new Point(ground);
}else{
voxels[x, y, z] = new Point(air);
}
}
}
}
As for marching cubes, just google it to get the algorithm to make the mesh based on yuor voxel points.
Sorry @Scribe , I am still confused as how this script you gave me works, and how to put it into the script I made following a tutorial:Planet TXT I am also confused as how to put the marching cubes algorithm in, although i did find this plugin: $$anonymous$$arching Cubes Plugin , but I don't understand it :(
Answer by Scribe · Sep 02, 2015 at 09:36 AM
So first we find your World class. Here I make so assumtions as I don't know what this class actually looks like, but I guess it starts something along these lines:
public class World {
...
public static World currentWorld;
public int chunkWidth;
public int chunkHeight;
...
}
We want to leave as much as we can the same, so we don't have to change to much other stuff, so I will leave chunkHeight in there, though it would be sensible to set chunkWidth and chunkHeight to the same value.
I will add a value 'radius' which will be the radius of the world we create.
public class World {
...
public static World currentWorld;
public int chunkWidth;
public int chunkHeight;
public float radius;
...
}
Then in the script you attached as a text file, we need to make some changes, so it doesn't just build the bottom layer of blocks as it is doing atm. Here I have changed the for loops in start, and the byte array 'map' is now a float array to be compatible with the project you found:
void Start () {
meshRenderer = GetComponent<MeshRenderer>();
meshCollider = GetComponent<MeshCollider>();
meshFilter = GetComponent<MeshFilter>();
map = new float[World.currentWorld.chunkWidth, World.currentWorld.chunkHeight, World.currentWorld.chunkWidth];
int centreXZ = World.currentWorld.chunkWidth/2;
int centreY = World.currentWorld.chunkHeight/2;
int distSqr;
for (int x = 0; x < World.currentWorld.chunkWidth; x++)
{
for (int y = 0; y < World.currentWorld.chunkHeight; y++)
{
for (int z = 0; z < World.currentWorld.chunkWidth; z++)
{
distSqr = ((x-centreXZ)*(x-centreXZ) + (y-centreY)*(y-centreY) + (z-centreXZ)*(z-centreXZ));
distSqr -= World.currentWorld.radius*World.currentWorld.radius;
if(distSqr >= 0) continue; //skip it if ouside our radius
//otherwise set it to 1 if completely contained, or a float value if on edge
distSqr = World.currentWorld.radius-Mathf.Sqrt(distSqr);
float val = Mathf.Lerp(0, 1, -distSqr);
map[x, y, z] = val;
}
}
}
}
the last bit to change is using the project you found, we should simply be able to do:
void Start () {
//...
//other stuff
//...
MarchingCubes.SetTarget(0.5f);
MarchingCubes.SetModeToCubes();
visualMesh = MarchingCubes.CreateMesh(map);
meshFilter.mesh = visualMesh;
meshCollider.sharedMesh = visualMesh;
}
Make sure you remove the 'CreateVisualMesh();' call!
I haven't tested this, so it's likely there is some problem (sorry) but feel free to ask more in the comments!
Scribe
@Scribe , if I were to put this into a new script, would it generate the visual mesh? Because there are no tris/faces being generated, for that we need to CreateVisual$$anonymous$$esh(); . I thought about replacing the stuff in Start() with what you suggested, and at the end of CreateVisual$$anonymous$$esh() add the $$anonymous$$arching cubes bit.
$$anonymous$$archingCubes.Create$$anonymous$$esh(map);
returns a mesh, with the tris and verts it decides upon. Have you tested it, I cannot vouch for it working as I am unable to test without downloading all your project files and things, which I don't want to spend time doing I'm afraid.
If you are not seeing anything you can try lowering the value you give to $$anonymous$$archingCubes.SetTarget();
sorry @Scribe , but would you know how, based on the script I attached, to make a big sphere of cubes without the marching cubes bit?
What have you tried? Its a very simple step backwards from what I have already posted.
Follow this Question
Related Questions
Smooth Voxel Terrain 0 Answers
How to fill a cube sphere with volume data? 0 Answers
SmoothDamp bug? 0 Answers
Custom touch control stops abruptly! 0 Answers
Please Explain the Code 0 Answers