cubesphere coordinate for no man sky's blitzclone
Community Forums/General Help/cubesphere coordinate for no man sky's blitzclone
| ||
I translated this into blitz3D http://catlikecoding.com/unity/tutorials/cube-sphere/ to make a simplified game like no man's sky without voxel. I'm struggling to create terrain around the player, based on the player's position, by enumerating coordinate like I do for flat terrain. I wonder if anyone know how to do that? The procedure could be that, I use the vector from the center of the planet to the ship and normalize it to the radius of the planet, detect which cube face I sit on, then detect which grid position from the face I'm on, then create around grid terrain at the correct offset and bounded by the face. Ideally I should also create terrain that are on other faces, that happen in the vicinity of the player when its radius of influence overlap with other faces (basically finding the position out of bound and only drawing terrain within bound of the face). Problem is, I'm not sure how to map properly the position of the player to the grid in the cube sphere projection to find coherent coordinate :/ Basically I want to hash the player's position to a grid cell on the one face of the cube sphere. Anyone have an idea? |
| ||
That's something I've been wondering too. Maybe you could use a simplified cube-sphere mesh with proper UV then make a linepick from the ship to the center of the cube-sphere, and retrieve the UV from the picked triangle. It should be possible to retrieve the current grid cell this way. The other solution is probably to reverse the maths used to position your vertices. If you use the formula to limit corners deformation like in the link you posted then you have it, but good luck :x |
| ||
No idea, but i am curious to see what you will manage to do. |
| ||
@flanker - [uv picking] I thought of that but then I thought it would have major imprecision at planet scale - [Math] I tried and it got over my head quickly <:( I found a thread about it on stack exchange but then they use double and still had many meters of difference :/ I have translated the code but haven't use it. - [quadtree] Generally what I see done as a solution is quadtree, basically we pick the center of each quad and then split it in 4 smaller quads and do it until we hit the appropriate depth. BUT the reason I'm using blitz is to avoid complex data structure like list and co, to keep things simple and prevent feature creep by limitation :P. However I did implement a recursive function that do more or less that with rect as a prototype. Problem is that it seems to have a huge cost in reconstruction and updating of tile. - That said I realize I don't need to use the recursion to build mesh, I could exploit it to find the position, by generating point and finding the closest one once projected back to the sphere, then subdivide that region further and using the new closest point! THEN build the mesh by sampling neighbor, topology are independent from position, neighbor tile are still neighbor whatever the projection. I'm still not sure how to manage out of bound position for crossing edge of different cube face though. @RemiD is there a place where I can do a devlog in this forums? EDIT: I have also realized that I can cache data of terrain based on LOD, basically I can keep the low frequency data and only generate the more or less additive lower data for the high detail version and combine it with the lower frequency, doing so limit the impact of generation, so splitting tile mesh or replacing them with high density mesh (like in chunk lod), I can just generate the high frequency and reference the low frequency. That reduce the update cost by a margin. |
| ||
you can create a "worklog" (see the link in the menu or go here blitzbasic.com/logs/userlog.php?user=11315 ) |
| ||
Thanks :) |
| ||
I found a thread on stackoverflow wich deals with this problem, but I don't understand the explanation. I don't know if he is a native english speaker, but i'm not, and I don't know at all wich vectors he's talking about : - component of the sphere vector ? - remaining cube vector components ? remaining sphere vector components ? - checks for 0.0 and -0.0 ? http://stackoverflow.com/questions/2656899/mapping-a-sphere-to-a-cube I need this too for the cubesphere maze i'm working on, but I think i'll find a custom method as the only thread on internet that deals with that is very unclear. |
| ||
Yeah I already translated this code, they say it has precision problem at planet scale and they use double type! Though for a maze that must be easy: Function SphereToCube.point3D(px#,py#,pz#) ;http://stackoverflow.com/questions/2656899/mapping-a-sphere-to-a-cube x# = px y# = py z# = pz ;absolute value of coordinate fx# = Abs(x) fy# = Abs(y) fz# = Abs(z) inverseSQRT2# = 0.70710676908493042 If fy => fx And fy => fz Then a2# = x*x*2 b2# = z*z*2 inner# = -a2+b2-3 innerSQRT# = -Sqr((inner*inner) - 12*a2) If x = 0 Or x =-0 Then px = 0 Else px = Sqr(innerSQRT +a2 - b2 +3)* inverseSQRT2 EndIf If z = 0 Or z =-0 Then pz = 0 Else pz = Sqr(innerSQRT -a2 + b2 +3)* inverseSQRT2 EndIf If px > 1 Then px = 1 If pz > 1 Then pz = 1 If x < 0 Then px = -px If z < 0 Then pz = -pz If y > 0 Then py = 1;top face Else py = -1;bottom face EndIf ElseIf fx => fy And fx => fz Then a2# = y*y*2 b2# = z*z*2 inner# = -a2+b2-3 innerSQRT# = -Sqr((inner*inner) - 12*a2) If y = 0 Or y =-0 Then py = 0 Else py = Sqr(innerSQRT +a2 - b2 +3)* inverseSQRT2 EndIf If z = 0 Or z =-0 Then pz = 0 Else pz = Sqr(innerSQRT -a2 + b2 +3)* inverseSQRT2 EndIf If py > 1 Then py = 1 If pz > 1 Then pz = 1 If y < 0 Then py = -py If z < 0 Then pz = -pz If x > 0 Then px = 1;right face Else px = -1;left face EndIf Else a2# = x*x*2 b2# = y*y*2 inner# = -a2+b2-3 innerSQRT# = -Sqr((inner*inner) - 12*a2) If x = 0 Or x =-0 Then px = 0 Else px = Sqr(innerSQRT +a2 - b2 +3)* inverseSQRT2 EndIf If y = 0 Or y =-0 Then py = 0 Else py = Sqr(innerSQRT -a2 + b2 +3)* inverseSQRT2 EndIf If px > 1 Then px = 1 If py > 1 Then py = 1 If x < 0 Then px = -px If y < 0 Then py = -py If z > 0 Then pz = 1;front face Else pz = -1;back face EndIf EndIf position.point3d = New point3d position\x = px position\y = py position\z = pz Return position End Function I haven't checked the code yet and I don't expect the -0 to work, lol, I think it need to be replaced with a sign check. |
| ||
Yes I already translated this code and it works, -0 is just 0... But it uses an approximative value (0.70710676908493042), wich comes from trying to solve the equation system on a website called wolframalpha. I think someone with true mathematics skill (wich is not my case at all), can solve this with exact values. |
| ||
Blitz only uses single precision so the value of 1/Sqrt(2) is going to get truncated in that const value you use above. Secondly - you will only ever get an approximate value to the inverse square root of 2 because it is an irrational number - it has an infinite number of non recurring decimal places---computers can only do so much. |
| ||
What I meant is that you can (maybe, I don't know) solve the equation system using another method wich wouldn't involve approximate values. It looks like a trick instead of mathematics... |