cubesphere coordinate for no man sky's blitzclone

Community Forums/General Help/cubesphere coordinate for no man sky's blitzclone

neoshaman(Posted 2016) [#1]
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?


Flanker(Posted 2016) [#2]
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


RemiD(Posted 2016) [#3]
No idea, but i am curious to see what you will manage to do.


neoshaman(Posted 2016) [#4]
@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.


RemiD(Posted 2016) [#5]
you can create a "worklog" (see the link in the menu or go here blitzbasic.com/logs/userlog.php?user=11315 )


neoshaman(Posted 2016) [#6]
Thanks :)


Flanker(Posted 2016) [#7]
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.


neoshaman(Posted 2016) [#8]
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.


Flanker(Posted 2016) [#9]
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.


Matty(Posted 2016) [#10]
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.


Flanker(Posted 2016) [#11]
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...