Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 18, 2024, 08:28:26 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Cube sphere coordinate
Pages: [1] 2
Print
Author Topic: Cube sphere coordinate  (Read 3180 times)
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« on: December 04, 2016, 02:21:18 PM »

I coded this cube to sphere to make a planet terrain
http://catlikecoding.com/unity/tutorials/cube-sphere/

I want to make a simplified game like no man's sky without the voxel. I'm struggling to create terrain around the player base 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 should 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 face that happen in the vicinity of the player when it's radius of influence overlap with other faces (basically finding the position out of bound and only drawing terrain within bound of teh 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 :/

Anyone have an idea?
Logged

Sik
Level 10
*****


View Profile WWW
« Reply #1 on: December 05, 2016, 11:04:21 AM »

You would use the same calculations you used to generate the sphere, right? (or the reverse ones, if you want to map from real to grid instead) I mean ultimately it's the same thing.

Although the biggest problem is that the grid is not even remotely linear anymore, the distance between two consecutive points in the grid can be completely different depending on the location. Nearly everything like this I've seen either just used the real 3D coordinates on everything or they did a flat surface with extremely heavy fisheye to make it look like a sphere. The last one is what I did with Miniplanets, exploiting integer overflow to get wraparound for free also helped me =P

If you only care about snapping things to the grid, your best option may be to have an array of the 3D positions for each point and then just scan for the closest one (there aren't that many, so just check them all =P).
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #2 on: December 05, 2016, 12:27:49 PM »

- [Math] I tried and it got over my head quickly <Sad 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 Tongue. 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.

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.
Logged

Polly
Level 6
*



View Profile
« Reply #3 on: December 05, 2016, 12:32:15 PM »

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.

Here you go Smiley

Code:
float x, y, z, ax, ay, az, u, v;

ax = abs(x);
ay = abs(y);
az = abs(z);

int a = ax > ay ? ax > az ? 0 : 2 : ay > az ? 1 : 2;

switch(a)
{
  case 0:
    u = 0.5f-(z/x)*0.5f;
    v = 0.5f-(y/x)*0.5f;
    break;

  case 1:
    u = (x/y)*0.5f+0.5f;
    v = (z/y)*0.5f+0.5f;
    break;

  case 2:
    u = (x/z)*0.5f+0.5f;
    v = 0.5f-(y/z)*0.5f;
    break;
}

+ A quick demonstration ..

Logged
mtarini
Level 1
*


View Profile WWW
« Reply #4 on: December 05, 2016, 12:43:59 PM »

In short, you need to parametrize a sphere.
Many possible solutions, among which I can recommend what in Computer Graphics is called a cube map.

Here is how it would work:
You have six faces, of the cube, which I will call the +X, -X, +Y, -Y, +Z, -Z face.
Let's agree that each face spans a square ranged from -1 to +1.

Now say you have a (x,y,z) anywhere on the planet (its radius doens't matter, as long as it is centered on 0,0,0).
Normalize that position to the a corresponding position on the unit sphere (if you want to bore people, specify that's is called a Gnonomic projection).
Now, which is biggest: |x|, |y| or |z| (absolute values)?
That identifies the cube face you landed in.
For example, the biggest is |x| than you are either on the +X face if x positive or -X face if x negative.
Divide the other two coords by the biggest abs and you get the position on the selected face.
For example, if the biggest is |x|, then the coords on the face are y/|x| and z/|x|.


If you want to iterate neighboring points, there are several options. One is to forget about 3D and check the neighbors in space.
A point in the interior of a face have no problem, but the one on boundary require a bit of care (nothing too difficult). The other is to travel in 3D, find neighbors in 3D on the tangent plane, and for each of them repeat the above 3D-to-cube-face procedure. If I'm on the right direction helping you, let me know, I can go on.
Logged

Warballs! · spherical fierceness · 1P · free · arena fighter · challenging
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #5 on: December 05, 2016, 05:18:38 PM »

That's impressive, but I don't use this normalization of sphere!

I have conservation of area of the square to have uniform grid, and I'm trying to find the equivalent hashing.

This is your sphere mapping
Code:
;naive method with deformation around pole
;sx = normalizeX3D(x,y,z)*radius/2
;sy = normalizeY3D(x,y,z)*radius/2
;sz = normalizeZ3D(x,y,z)*radius/2


this is mine!


Code:
	x2# = x*x
y2# = y*y
z2# = z*z

a# = (x2 / 2.0)
b# = (y2 / 2.0)
c# = (z2 / 2.0)

sx# =  Sqr(1.0 - b - c + ( (y2 * z2) / 3.0 ) ) * x / 2
sy# =  Sqr(1.0 - c - a + ( (x2 * z2) / 3.0 ) ) * y / 2
sz# =  Sqr(1.0 - a - b + ( (x2 * y2) / 3.0 ) ) * z / 2
   


Notice I don't have the pinching at the pole?
Logged

Sik
Level 10
*****


View Profile WWW
« Reply #6 on: December 05, 2016, 10:18:17 PM »

Wait now that I see it like that:

1) Determine the angle from the center of the sphere for each axis-aligned plane (XY, XZ, YZ, atan2 will do the job)
2) Determine which of the six "faces" the coordinate you want is on (literally just compare which coordinate axis is largest)

The angle of the sphere (#1) would map directly to coordinates because of that normalization, just change the scaling accordingly. Then simply use the face (#2) to know which way to read the angles.
Logged
mtarini
Level 1
*


View Profile WWW
« Reply #7 on: December 08, 2016, 04:32:40 PM »

ohhh now I see what you mean.

You have a function going from the position on the unit cube C to the unit sphere S and you would like a function going the other way round. I got it that far, what I didn't understand is that, since the parameterization of the sphere you use is not the standard "gnomonic" one (the standard the cubemap), you cannot use the standard inverse function, which both me and Polly discussed.

I can see three practical solutions.

Way 1) Go back to the default "vanilla" cubemap.

I.e. keep things simple. It is true that the parameterization you use is more isometric (preserves better both angles and areas, meaning the squares are more regularly sized and shaped on the sphere), but ask yourself, is it worth it. A terrain would probably look very similar.

Way 2) Only ever use cube->sphere (never sphere->cube directly).

Like this: you have a point p = (x,y,z) on the cube and with your function you can find s = (sx,sy,sz) on the sphere. If you want to find neighboring points, move p over the cube, get p'=(x',y',z'), and project it on the sphere, funding s' = (sx',sy',sz') which will be close enough to s.

Way 3) Do the math and compute sphere->cube

I think you'll like this one more, but it takes a little more effort...
I did the math for you (initial, and not tested, but it should be close).

So you have a point (sx, sy, sz) on the sphere and you want to find
first, the face of the cube (one of -X, +X, -Y, +Y, -Z, +Z) and then a position on that face.
So basically you want to find (x,y,z) on the cube, i.e. such that one of x,y,z is -1 or +1, and the other two coords are between -1 and +1 (included). Ok?

Ok, first of all: in your math above, your sphere seems to have unit DIAMETER (i.e. 0.5 radius). This is a bit of an useless complication. It is easier if you remove that "/2" at the end of sx = ... (this is valid both in your parametrization and in standard parametrization). Once you have your position on the radius-one sphere, just multiply by planet radius.

So your formulas look like this:

Code:
sx =  Sqrt(1.0 - yy/2 - zz/2 + ( (yy * zz) / 3.0 ) ) * x    (1)
sy =  Sqrt(1.0 - zz/2 - xx/2 + ( (xx * zz) / 3.0 ) ) * y    (2)
sz =  Sqrt(1.0 - xx/2 - yy/2 + ( (xx * yy) / 3.0 ) ) * z    (3)
(I numbered the three formulas)

Where
(sx,sy,sz) = position on the UNIT sphere (zero centered, diameter two)
(x,y,z) = position on the UNIT cube (zero centered, side two)
and naturally xx = x*x

Now, given (sx,sy,sz) you'll find (x,y,z) on the cube.
I.e. which face and position on that face.
It is not difficult.

Step 1: determine the face. I.e. determine which of x,y,z is +1 or -1.
This is the same as before. Grab the biggest between |sx|, |sy|, |sz|, and see the sign before the abs:
For example, if |sx| is then biggest then: if sx<0 then x=-1, if sx>0 then x=+1.
Ok? Probably your code will have 6 cases, x=+1, x=-1, y=+1... etc.

Say it was x=+1 (i.e. is the +X face).
The other cases will be similar.

Next, you need to determine y and z (which will be the position inside that face).
Here is how to do so.
Just take (2) an (3) (you don't care for 1, because you know x already) and substitute x=+1:
you get

sy =  Sqrt(0.5 - zz/6 ) * y
sz =  Sqrt(0.5 - yy/6 ) * z

(this will not be your code just yet, it is just a way to get there)

That's a lot simpler already, right?
Now let's invert it. You get (after a few passages):

syy = (0.5 - zz/6) * yy
szz = (0.5 - yy/6) * zz

where syy = sy*sy and szz = sz*sz.

Going further, we get

yy = syy/(0.5-zz/6) = 6*syy/(3-zz)
and
0.5*zz*zz + zz*(syy-szz-1.5) + 3*szz = 0

That is degree 4 in z (zz*zz is z^4) but fear not.
We will just solve it for zz (i.e. our unkown is zz, not z)

Now, just rename :
a = 0.5
b = (syy-szz-1.5)
c = 3*szz

that becomes
a*zz*zz + b*zz + c = 0

Which is solved by zz = -b +sqrt( b*b-2*c).    // because a = 0.5
(you'll need the +sqrt solution, although the solution with -sqrt is also a solution of the equation).

Now you have zz and you can find yy, as
yy = 6*syy/(3-zz)

Last passage. Now you have yy and zz, the squares of the z and y you are looking for.
So, should you take y = sqrt(yy) or y = -sqrt(yy)?
Luckily, that is easy to determine: if you think about it,
the sign of y is the same as the sign of sy  (and same for z).

So in total the final computation for this case is:

Code:
function find_pos_on_cube( float sx, sy, sz )
{

// case |sx| is biggest, and sx>0.
// Face is: +X.
// Position on the cube: x = +1.
//

float syy = sy*sy;
float szz = sz*sz;

float b = (syy-szz-1.5);
float c = 3*szz;

float zz = -b + sqrt( b*b - 2*c);
float yy = 6*syy/(3-zz);

float x,y,z; // pos on cube
x = +1;
z = (sz>0)? sqrt(zz) : -sqrt(zz);
y = (sy>0)? sqrt(yy) : -sqrt(yy);

}





Logged

Warballs! · spherical fierceness · 1P · free · arena fighter · challenging
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #8 on: December 09, 2016, 02:27:31 PM »

Gameplay metric
Quote
I.e. keep things simple. It is true that the parameterization you use is more isometric (preserves better both angles and areas, meaning the squares are more regularly sized and shaped on the sphere), but ask yourself, is it worth it. A terrain would probably look very similar.

I need minimizing impact on gameplay, if the grid is not the same it screw the gameplay, I would say it's not only worth it, it's necessary the amount of deformation really cause problem, else I would have cared!

It's also a space game, I must do all sort of things with spatial placement of planet, approach from space with progressive procedural placement, and trade route from one planet A area to another planet B area

Quote
Ok, first of all: in your math above, your sphere seems to have unit DIAMETER (i.e. 0.5 radius)

Not it's necessary for a unit sphere since you would obtain that:

Not quite a sphere


I had made this:
Code:
Function SphereToCube.point3D(px#,py#,pz#)

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
http://stackoverflow.com/questions/2656899/mapping-a-sphere-to-a-cube
But the original article say it's having precision problem at planet scales, even though they use double to compute it!

I'm trying to see if it match your calculus now
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #9 on: December 09, 2016, 10:37:57 PM »

Quote
int a = ax > ay ? ax > az ? 0 : 2 : ay > az ? 1 : 2;

This is quite savage, is there a readable version of it  Who, Me?
Logged

Sik
Level 10
*****


View Profile WWW
« Reply #10 on: December 09, 2016, 11:15:17 PM »

Quick translation:
Code:
int a;
if (ax > ay)
   a = ax > az ? 0 : 2;
else
   a = ay > az ? 1 : 2;

Better way to put it:
Code:
int a;
if (ax > ay && ax > az)
   a = 0;
else if (ay > az)
   a = 1;
else
   a = 2;

Essentially: a = 0 when ax is largest, 1 when ay is largest, 2 when az is largest.

And seriously people, don't use the ternary operator like that, if you have to nest then it's too hard to read.
Logged
Krux
Level 2
**



View Profile
« Reply #11 on: December 10, 2016, 09:52:17 AM »

When I was little I always wondered how Populous 3 made the spherical maps. Now I know they didn't. The map was just a flat 2D grid that was wrapping around in both x and y direction. The round appearance of the horizon was just fake, and those 6 areas where three quads meet in one vertex didn't exist. They really fooled me there.


Logged
mtarini
Level 1
*


View Profile WWW
« Reply #12 on: December 11, 2016, 02:35:15 AM »

Quote
Ok, first of all: in your math above, your sphere seems to have unit DIAMETER (i.e. 0.5 radius)

Not it's necessary for a unit sphere since you would obtain that:
<img>
Not quite a sphere

You must have removed some other "/2".
I meant removing the three "/2" at the end of last three lines, when you compute sx sy and sz. That will give you a convenient radius 1 sphere (ready to be scaled by planet radius).

As for the precision, it depends what you do with it but suspect it won't be a problem for you. You just use that to store the orography (mountains, as height fields), on a relatively small res, right?

« Last Edit: December 13, 2016, 05:45:53 AM by mtarini » Logged

Warballs! · spherical fierceness · 1P · free · arena fighter · challenging
Polly
Level 6
*



View Profile
« Reply #13 on: December 11, 2016, 04:48:01 AM »

And seriously people, don't use the ternary operator like that, if you have to nest then it's too hard to read.

Sorry, force of habit Smiley This might be easier to read for some / most indeed ...

Code:
if(ax > ay && ax > az)
{
  u = 0.5f-(z/x)*0.5f;
  v = 0.5f-(y/x)*0.5f;
}
else if(ay > az)
{
  u = (x/y)*0.5f+0.5f;
  v = (z/y)*0.5f+0.5f;
}
else
{
  u = (x/z)*0.5f+0.5f;
  v = 0.5f-(y/z)*0.5f;
}
Logged
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #14 on: December 11, 2016, 09:53:38 AM »

Quote
Ok, first of all: in your math above, your sphere seems to have unit DIAMETER (i.e. 0.5 radius)

Not it's necessary for a unit sphere since you would obtain that:
Quote
Not quite a sphere
[\quote]

You must have removed some other "/2".
I meant removing the three "/2" at the end of last three lines, when you compute sx sy and sz. That will give you a convenient radius 1 sphere (ready to be scaled by planet radius).

As for the precision, it depends what you do with it but suspect it won't be a problem for you. You just use that to store the orography (mountains, as height fields), on a relatively small res, right?



I agree that it "should" but it didn't, infact the whole process is to scale the input by two, then divide the operation by 2. I shouldn't need the "2", they should cancel each other, but the end result after processing don't agree, so I stuck with them! I didn't find them by math, I find them with trial and error, I don't know why it doesn't works as it should!
Logged

mtarini
Level 1
*


View Profile WWW
« Reply #15 on: December 13, 2016, 05:53:53 AM »

Ok this is too small a detail and probably not worth it, but, I think there might be a misunderstanding.
What I'm saying is that you should remove ONLY the three "/2" at right end of the last three lines of your computation and no-where else.

Code:
x2# = x*x
y2# = y*y
z2# = z*z
 
a# = (x2 / 2.0)
b# = (y2 / 2.0)
c# = (z2 / 2.0)
 
sx# =  Sqr(1.0 - b - c + ( (y2 * z2) / 3.0 ) ) * x / 2   <== those
sy# =  Sqr(1.0 - c - a + ( (x2 * z2) / 3.0 ) ) * y / 2   <== three
sz# =  Sqr(1.0 - a - b + ( (x2 * y2) / 3.0 ) ) * z / 2   <== ones

and nothing else, and you are golden. You'll start from the unit cube (or actually anywhere in 3D) and land in the unit radius sphere.

But this is a minor detail.
Point is, you can go back from unit-radius sphere to unit-sided cube, and, from there, to face index + position inside that face.
Would that solve your problem?
It is true that precision can be a bitch, but it all depends on what you need to do with it.
Most probably, it won't be a problem.
Logged

Warballs! · spherical fierceness · 1P · free · arena fighter · challenging
gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #16 on: December 13, 2016, 10:17:24 AM »

That's the one I added, that's the one I'm talking about :D

Anyway I'm working on implementation of all ideas, so we will see result soon!
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #17 on: November 28, 2017, 08:13:49 PM »

One year later  Facepalm

lol, I'm on valve time full time ...  Who, Me?

So much for soon! Big Laff

Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #18 on: November 28, 2017, 08:39:33 PM »

What happen is that I started the prototype on blitz3D and then hit a an inherent blitz3D bug, so I move on to other task before porting the entire project on unity. Which I just did as part of a whole task about porting basic pcg routine, some unity bugs later I have finally implemented the code suggested above and it doesn't work! It's quite mathy so I don't know if I made a mistake or if it is bogus ...

I have this code in a class meshgenerator, then use it to project back the spherized vertices to the cube as a way to verify the code works. As you can see teh code is a bit funky but it shouldn't be the problem at this step. I mean, orientation isn't guarantee to be good and there is only one side of teh cube (opposite side aren't checked) but the behavior should be at list a regular array of visual, not this result:

Code:
//_____________________________________________________________________________
static Vector3 SQRsphereToCubeHelper(float xi, float yi)
{
float x2, y2,
b, c,
x,y,z; // pos on cube

float xxi = xi * xi;
float yyi = yi * yi;

b = ( xxi - yyi - 1.5f);
c = 3f * yyi;

y2 = -b + Mathf.Sqrt( b*b - 2f*c );
x2 = 6f * xxi / ( 3f - y2 );

x = (xi > 0f) ? Mathf.Sqrt( x2 ) : -Mathf.Sqrt( x2 );
y = (yi > 0f) ? Mathf.Sqrt( y2 ) : -Mathf.Sqrt( y2 );
z = +1f;

return new Vector3 (x, y, z);
}

//_____________________________________________________________________________
public static Vector3 SQRsphereToCube(Vector3 v)
{
float asx = Mathf.Abs (v.x);
float asy = Mathf.Abs (v.y);
float asz = Mathf.Abs (v.z);

Vector3 result;

if (asx > asy && asx > asz) {
// case |sx| is biggest, and sx>0.
// Face is: +X.
// Position on the cube: x = +1.

result = SQRsphereToCubeHelper(v.y, v.z);//x
result = new Vector3 (result.z, result.x, result.y);
return result;

} else if (asy > asz) {//+Y

result = SQRsphereToCubeHelper(v.x,v.z);//y
result = new Vector3 (result.x, result.z, result.y);
return result;

} else {//+Z

result = SQRsphereToCubeHelper(v.x,v.y);//z
result = new Vector3 (result.x, result.y, result.z);
return result;

}
}


Image below


It's not grid align  Sad
Logged

bateleur
Level 10
*****



View Profile
« Reply #19 on: November 29, 2017, 12:24:09 AM »

Trying out your SQRsphereToCube function, it maps sphere <0,0.6,0.8> to "cube" <-1.6,-1.7,1>... so it looks like the face detection part is correct but your on-face maths is wrong.

I don't have time to go through debugging the equations, but I have to ask: do you really need a particular projection for your project? Because I'd just do this:

Code:
private Vector3 cubeToSphere(Vector3 v) {
 return(v.normalized);
}

private Vector3 sphereToCube(Vector3 v) {
 float asx = Mathf.Abs (v.x);
 float asy = Mathf.Abs (v.y);
 float asz = Mathf.Abs (v.z);
 float amax = Mathf.Max(asx,Mathf.Max(asy,asz));
 return(v/amax);
}

...which is far easier to work with!
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic