• Advertisement

Archived

This topic is now archived and is closed to further replies.

Concepts on a cyclic 3D universe... (need insight)

This topic is 5099 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Given a cubic or spherical universe, how would one handle a wrap-around effect similar to asteroids? I''m not asking how to do the actual wrap around (that''s easy), but rather how to handle such cases as seeing object on the other side of the universe through the wrap around. Such that things don''t just appear/disappear out of thin air. Have there been any gaming relevant articles written about wrapping a 3D universe?

Share this post


Link to post
Share on other sites
Advertisement
quote:
Original post by Xorcist
I'm not asking how to do the actual wrap around (that's easy), but rather how to handle such cases as seeing object on the other side of the universe through the wrap around. Such that things don't just appear/disappear out of thin air.

What would you expect to see? If your universe would be very small then you would see any object many times. Like putting two mirrors in front of each other. How many times you would see an object depends on your view distance.
Lets say the universe is a cube with sides of 10 units. If your view distance is 50 then you would see each object 5 times.

[edited by - Rule on February 5, 2004 5:34:47 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
if (x>=SIZEX) x=0;
else if (x<0) x=SIZEX;

repeat for y,z, and any other dimensions you have in your universe.

Share this post


Link to post
Share on other sites
Well I'm not exactly sure how the wrap function would work on a sphere, but cubic is easy

simply render the universe repeatedly .

Think of a game that uses tiles. You render the same thing everywhere it's needed right? So pretend that this game just showed the same tile and nothing else. Moving through the universe would scroll some.

Now, instead of tiles, you're really rendering 'the universe'. and instead of 2d tiles, they're really cubes.

So, for the simplest version,

for (int x = me.x - me.vd ; x < me.x + me.vd ; x += univ.width) {
for ( int y = me.y - me.vd ; y < me.y + me.vd ; y += univ.height) {
for ( int z = me.z - me.vd ; z < me.z + me.vd ; z += univ.breadth) {
univ.renderOffset(x,y,z);
}
}
}


me.vd = me.viewdistance

add some fog to blur the effect of the disappearing past the viewdistance, add some code to not render the scene if x*x+y*y+z*z > me.vd*me.vd + leeway; (where xyz are in terms of me.xyz, and leeway depends on what points you're using... if the point you're checking is the center of the universe, the leeway = (univ.width/2)*(univ.width/2) + (univ.height/2)*(univ.height/2) + (univ.breadth/2) * (univ.breadth/2)

or something similar to that. That leeway number should be overkill, but you'd need to add some square roots in there for a better answer (aka, sqrt(xx+yy+zz) > me.vd + sqrt(leeway)).

I'm assuming the AP wanted to make things far away visible, assuming they got out of your z distance range. With the APs answer, well, you'll just get things cluttering up in the corners of the visible universe if they're far away. So like, nope, that's totally wrong. The method you'd want would be:

float dist2 = x*x+y*y+z*z;
if (dist2 > cd*cd) //too far away!!!
{
float dist = sqrt(dist2); //don't sqrt unless you have to...
x /= cd*dist;
y /= cd*dist;
z /= cd*dist;
}


where cd = clipping distance (to which if they're farther than, you'd bring up to).

The reason the AP's method dosn't work:

assume we have objects throughout the universe, with coordinates ranging from [-10..10]. Assume we're clipping to [-1..1]. Assuming even distribution of objects, only 10% of those objects would not be clipped on the x axis, 10% not to the y, and 10% not to the z.

0.1% wouldn't be clipped at all (they'd be inside the cube).
0.9% would be clipped once (aka, to a plane)
8.1% would be clipped twice (aka, to an edge)
72.9% (the remainder) would be clipped to a corner. That is, most of the universe would be rendered in one of 8 spots. a single direction would contain 9.1125% of the universe. Last I checked, there was an equal distribution more or less - and there being infinite directions, infinitly small ammounts of the universe are ever in a single direction by pure mathematics.

As the clip ratio increased (aka, universe ranges from [-100..100] and clipping to [-1..1]) the percentage of items clipped to a corner would increase. With an infinitly large universe clipped to any boundry, 100% of the universe would be in a corner.

-Mike

edit: bad typo, no biscut.

[edited by - MaulingMonkey on February 5, 2004 7:21:50 PM]

Share this post


Link to post
Share on other sites
Thanks for the info.

Well obviously I'd make the universe large enough and the clipping distance adequately relative so that inifinite mirror imaging didn't occur. And there will most likely be an outlying buffer on the universe that will be devoid of objects other than active ships so that the physical wrap around would be clean.

P.S. If anyone has any other ideas or comments, please add. The more info I have on this topic the better.

[edited by - Xorcist on February 6, 2004 1:51:22 PM]

Share this post


Link to post
Share on other sites
So, what you really have is 27 identical universes arranged as a Rubik's Cube, and each object has 27 logical positions... mathematically, i think this equates to a hypertorus. Anyway, for rendering, the brute force approach would be something like:


for(int i = 0; i < 27; i++)
{
glPushMatrix();
glTranslatefv(universe[i].offset); // this function doesn't actually exist.

RenderObjects();
glPopMatrix();
}

But you really don't want to do that Note that each universe is just a offset, not a complete copy of the universe... The next step is to do a camera frustum / aabb test with each universe, and if the universe lies in the frustum, then render all the objects.
          
for(int i = 0; i < 27; i++)
{
if( intersectFrustumAABB(camera.Frustum, universe[i].AABB) )
// Transform and Render.

}

Now, say you've smartly arranged your universe in an octree to cut way down on rendering ops. Now, you can use this by transforming the Frustum into the given Universe coordinate system, and searching the octree. Here the math is as simple as subtracting the Universe's offset from the Camera's position.

You should note, however, that you may want to do something really cool with this in the future, say when you fly off of the right side of the universe, you would come up out of the bottom... Now using these offsets, that would be completely impossible. If you make the realization that the offset represents a transformation from local universe space to rubik's cube space, then it becomes trivial.

So, say universe i in the Rubik's Cube is represented as a 4x4 Matrix Ui, when you fly into that universe, you're transforming the ship's coordinates into that local coordinate system. In the simple system this is represented as:

if(ship.x > universe.xmax) ship.x -= universe.xmax;

But what it really means is if the ship's position and orientation are represented by matrix Ms, then Ms = Ui(-1) * Ms; (where Ui(-1) means the inverse of Ui, the space the ship is flying into).

This has a lot of implications... for example, in the frustum-AABB test, the AABB is actually the AABB in local coordinates, transformed into Rubik's Cube coordinates (shifted over)... to do that check in Whacky World, you'd want to either transform the frustum into universe coordinates:
   
IntersectFrustumAABB(camera.Frustum.Apply(universe.Transform.inverse()), AABB);

//or transform the AABB into Rubik's Cube coordinates:

IntersectFrustumAABB(camera.Frustum, AABB.Apply(universe[i].Transform));

// It also means that when you're rendering:


for(int i = 0; i < 27; i++)
{
if(IntersectFrustumAABB(camera.Frustum, AABB.Apply(universe[i].Transform))
{
glPushMatrix();
glMultMatrix4f(universe[i].Transform); // RenderObjects will render into local universe coordinates...

// So that's where we put the camera also.

RenderObjects(Universe.octree.GetObjectsInFrustum(camera.Frustum.Apply(universe[i].Transform.inverse()));
glPopMatrix();
}
}

So if you do the Whacky transform out right -> in bottom, when you look out the right side of the universe, you'll see objects in the bottom, and when you look out the bottom, you'll see objects in the top AND right You can even mirror the universe, so you fly into yourself, or shoot yourself, etc...


EDIT: formatting (argh!)


[edited by - ajas95 on February 6, 2004 4:12:03 PM]

Share this post


Link to post
Share on other sites
if you have a fixed universe size, inside a box, think of the box's rectangles as portals to the other side of the universe. So, if a 'portal' is visible from the current viewpoint, render the world by by moving the camera viewpoint opposite face of the portal, and rendering the world again, from there. That works if the camera's draw distance is less than 1/2 the size of the box.



// /

// +-------------/-+

// | / |

// | / | \

// | C *--------'

// | |

// | |

// | |

// +---------------+

//

//

//

//

//

//

// /\ /

// / +\------------/-+

// / | \ / |

// / | \ / |

// C1*--------' C0*--------'

// | |

// | |

// | /

// +-------------/-+

// /

// /

// C2*--------'





well, I think this should work.


[edited by - oliii on February 6, 2004 4:12:47 PM]

Share this post


Link to post
Share on other sites
If you really want to see what it would look like in both cases, I would suggest finding/writing the source for a bare-bones ray-tracer and make the single addition that when a light-ray pierces the edge of the universe it wraps back around according to some particular pattern.

I would definitely cap the number of wraps to some maximum or it will never terminate. But in any case it shouldn't be too hard. Just set up a simple scene with a few spheres and a cube or two (or if you want, load a mesh, but that sounds more complex to me), and then start shooting rays and storing pixels in a bitmap. You'll know in no-time which should help with the theory (and be darn cool). Besides, why stop at cubic and spherical? Surely there are other possibilities! Basically any kind of 3-dimensional geometry could be applied including polar functions and even functions of time (although THAT would be both processor-intensive AND disorienting! ).

By the way, if you do implent the ray-trace, post some screenshots; I'd love to see it!

[edited by - bob_the_third on February 6, 2004 4:33:19 PM]

Share this post


Link to post
Share on other sites

  • Advertisement