1
\$\begingroup\$

I have this problem where I split my big world into chunks and I don't know how to draw it into my game camera's view. Each world chunk has its own coordinate system, so when object reaches border of one chunk and steps into another - coordinate system resets to zero. For example from world_x = 1440 into world_x = 0.

To draw only those objects that are in the camera's view, I use code:

int screenX, screenY; //screen position of the object being drawn

screenX = object.x-camera.x;
screenY = object.y-camera.y;

The problem appears when camera sees two different chunks. Lets say camera's coordinates are:

screenX = 567
screenY = 0

My drawable object is at

world_x = 1266
world_y = 0

In this case object's screen coordinates are (x)699, because screenX = object.x-camera.x. But what if camera stays in the same place and object finally reaches different chunk. Object's coordinates are reset to zero. That means that its screen coordinates becomes (x)-567.

That screen coordinates conversion would work if I would be doing non partitioned game world, but now it don't. Any ideas?

\$\endgroup\$
  • \$\begingroup\$ Do you have enough space in a typical 32 bits integer for any absolute coordinates to fit without overflow ? \$\endgroup\$ – v.oddou Oct 15 '14 at 5:03
  • \$\begingroup\$ Don't know if I understood your question correctly, but for object movement I really need float variables. \$\endgroup\$ – thomas_the_train Oct 15 '14 at 11:56
  • \$\begingroup\$ I ask because your obvious fix is just to create absolute coordinates, you have them for your camera, with these you chose the chunk(s) to display, so just make all objects position absolute by adding the corner position of their chunk to their chunk-local coordinates and boom problem solved. Just in general, if a world has infinite streaming, this is something we don't want to do because of integer overflow. If you use float its even worse because of precision lost after some distance. \$\endgroup\$ – v.oddou Oct 16 '14 at 2:08
3
\$\begingroup\$

Invert your thinking. Don't convert objects to camera space, convert the camera to object space.

  • Start by clearing the output buffer including the stencil buffer.

  • Sort the chunks in painterly order from back to front. Subdivide per usual transparency-drawing rules if needed.

  • For each chunk:

    • Clear the z-buffer and set the stencil buffer to mask anything already stenciled.

    • Create a camera transformation matrix that positions the camera relative to the chunk. Keep your projection the same, but ideally move the front and back planes of the z-buffer to be max and minimum values of the nearest and farthest edge of the chunk along the camera look vector. This gives you the most z-buffer resolution.

    • Draw all the visible objects in that chunk and only in that chunk.

    • Draw the chunk to the stencil buffer.

  • Continue until all the chunks have been rendered.

Do your transforms once per chunk, not once per object. This is the most efficient way and it preserves your numeric precision. Done correctly, it will also prevent polygon flimmering.

If you try to render a very large world with absolute coordinates in floating point, a number of bad things will happen... besides being difficult to get your head around. As you run out of numeric precision you will start to get object "drift". The further you get from the origin the distance between two objects that are X units apart will appear larger even though they are the same. This is because the last digits are being truncated. -You're trading precision for range, it's not really a larger number!-

You also risk exceeding the precision of the z-buffer. What will happen is that the polygons will "fight" for z-order and will appear to sparkle. By tight-fitting the z-buffer as much as possible, the objects will sort better and the whole scene will look nicer when rendered.

\$\endgroup\$
0
\$\begingroup\$

I would say to make each chunk continuous. Don't reset the world co-ords. As the old chunk scrolls off (into fog etc) write it to file or store to memory. New chunks scrolling in would do so only under fog (way at screen edge). Let your x,y, z go to 2000000000 both ways that's more than large enough for anyone.

\$\endgroup\$
  • 3
    \$\begingroup\$ Have you ever heard about float precision? \$\endgroup\$ – thomas_the_train Oct 15 '14 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.