[Bug]World Origin Location min/max value warping?

Hi guys,

I am working on a project that involves “infinite” worlds. Well. At least very very large world…

For this purpose, I am using the World Origin Rebasing functions in Blueprint.

I, however, noticed a weird behavior from the values of this origin. So I have a few questions.

  • 1 - Is the World Origin Location a 32 ou 64 bits value on the engine side?
  • 2 - Is it normal that when we print the value of the World Origin Location, when we go up along an axis, when we reach about 2.1billion (int max value), it loops it back to -2.1 (int min value).
  • 2.1 - If this is normal and the real value is more than the printed value, everything is normal.
  • 2.2 - If this is normal but the real value is the one displayed, we have an issue.
  • 2.3 - If this is not normal. Well… :stuck_out_tongue:
  • 3 - Is it normal that when we print the value of the World Origin Location, when we go down along an axis, when we reach about -2.1billion units (int min value), it DOES NOT loops it back to 2.1 (int max value?)

I think that either the 2 or the 3 is a bug.

But I would tend to say that the 3 is just missing the looping back as it would make no sense to loop the value in a way and not in the other (it forbids you to go back).
I also noticed that, if you look on the x axis for example and go forward until it loops and gets back to world origin “0” on the axis. the “0” seems not to be the same.

How can I tell?

I have an octree that is placed on a grid based on the World Origin location.
Basically, when the world Origin location is near 0, it will snap it to the grid and put it at the 0 position of the world location.
It then uses this position to procedurally generate stars around it.
The thing is, we do not have the same result from the 0 before the shifting and after the shifting.

Proofs:

http://puu.sh/kjzvI/363ade9678.jpg

Original spawn generation

http://puu.sh/kjzDn/86686ff5e9.jpg

After Origin complete loop

You can really see that it’s not the same.

So, what is the real min/max value of the World Origin Location?
Is it meant to loop from max to min value but not from min to max?

Is it normal that after looping the 0 value is different when it’s being forcefully snapped to the grid? (precision loss?)

Those questions are quite important for the generation of our “infinite” universe. :slight_smile:

Thanks!

Erio

Hi Erio Hayaweh Maondial,

Do you have a sample project these errors are occurring in that i’d be able to take a look at or do you have a set of reproduction steps I can follow to reproduce this on my end? Does this occur in a clean, blank project with no additional content or is it limited to one project?

Hi Adam,

I will set up a small project that reproduces the issue with debug infos being displayed.

From what we experimented, the bug is not limited to our project but the global use of World Origin Rebasing for locations above/under the size of an int.

I come back at you with a clean basic project to demonstrate the issue asap (in the next hour most likely)

Reproduction Project

Hi Adam,

As “promised”, here is an almost empty and very simple project that will allow you to reproduce the bug.

Steps to reproduce:

  • Press the button play (and do not rotate the pawn to see the effect better)
  • Press “T” key twice to toggle the speed to Ultra Fast (500km/s)
  • Move forward, right or up. Any positive axis is working.
  • Wait for the displayed value of the axis you were moving on to overflow (should happen after ~30s-1min)
  • Come back to ~0 on the axis, you’ll notice that the big brush is not here anymore, meaning that the “0” we’re at is not the “0” we did start from
  • Go onto the same axis, but this time in negative (backward, right or down)
  • Wait for the value to reach minimal int value continuing to move in the same direction
  • Notice that the value does not loop back to max int value and that we are seeing the atmospheric fog going away (which does not happen for positive value)

This does apply to every axis and is behaving always in the same manner. :slight_smile:

Our current guess are that:

  • Either the WorldOriginLocation is handled as doubles on the engine side
  • Or the WorldOriginLocation is handled as floats value (although it asks for int values on the node) and we are only losing a lot of precision
  • The positive reset when reaching the max value is a normal behavior and the bug is that it does not reset when going into minimal values
  • The positive reset is a bug that should not be able and we are bound to be limited to an int box

I hope this can help.

Erio

Hi Erio,

I was able to reproduce this and have entered a bug report, UE-21410, to be assessed by the development staff. The positive value seems to be acting as intended. once you reach ~2.1 billion it is shifting the world origin to the new location, which would put you on the negative value because it is moving the origin and sky sphere to a new location ahead of the player, which is why you see the negative values but returning to 0 does not show your static mesh. 0 has become an entirely new location that is still heading in the positive direction. The negative, however, is not reacting as it should be.

Thanks a lot.

I am glad that this is a bug and that we can continue with our current system. :slight_smile:

I hope to see this fixed quite soon.

What would be the priority of this bug-fix?

Unfortunately I do not currently have that information available, it must first be assessed by the developers.

Hi,

I’ve looked at blueprint script in your project. One issue is you compute distance between world origin and pawn location. When pawn is too far away from world origin this distance will be very big and can’t be precisely enough stored in a FVector. Instead you should compute pawn distance from a local origin.
Like: distance = length(0 - pawnLocation);
and then when distnase is bigger than some value shift the global origin:
SetWorldOrigin(GetWorldOrigin() + distance);

World origin is stored as a FIntVector, so each axis should can be in range ~[-2.1b : 2.1b]. Before setting a new world origin you should clamp it to int32 limits.

Hi,

Thanks for your answer.
Well. Basically, that’s already what we are doing.

http://puu.sh/kzmhZ/9142f41894.png

As you can see, I have a local variable that is being used to check what the distance is to the origin.
When the distance of the pawn to the origin is greater than this value, we do rebase the world origin to the location of the pawn + the previous location of the world origin.

This works perfectly as intended.

The issue is that when we reached -2.1b, the value should have shifted to +2.1b for the world origin location in the same manner it does when you reach 2.1b it shifts the world origin location to -2.1b.

So clamping would not be a solution as it would most likely make this shifting impossible.

Adam Davis’s answer below made it clear that this was a bug. :slight_smile:
(there is no other problem with the world origin shift aside of these extreme boundaries)

The issue is that when we reached
-2.1b, the value should have shifted to +2.1b for the world origin location
in the same manner it does when you
reach 2.1b it shifts the world origin
location to -2.1b.

World origin does not support space wrapping, shifting origin beyond int32 range limit will produce unspecified behavior. You need to handle this case in your code. There are two ways to handle this:

  1. clamp origin and do not allow pawn movement beyond 2.1b

  2. add space wrapping, manually moving origin and pawn to a new position across the space when it reaches limit.

Well… Honestly it would be amazing if this unspecified behavior could work for negative values as well as it proved to be really useful. :stuck_out_tongue:

I am also confused with Adam Davis’s answer which indicates that this behavior was meant:

The positive value seems to be acting as intended. once you reach ~2.1 billion it is shifting the world origin to the new location, which would put you on the negative value because it is moving the origin and sky sphere to a new location ahead of the player, which is why you see the negative values but returning to 0 does not show your static mesh. 0 has become an entirely new location that is still heading in the positive direction.

Which is completely the behavior we are seeking as this int value is ridiculously small for what we need.

It also seemed to be a bug for the negative value:

The negative, however, is not reacting as it should be.

On the other hand, Adding space wrapping manually will be a “pain” as we have to divide the the space in virtual cubes and keep an array up to date to know in which cube we are… But this would not be enough as the 0 of each cube in this case would be exactly the same ans this is a behavior we do not want.

If we had to clamp this value, we would be in a case that would make our workspace ridiculously small… :confused:

So right now I am really confused between your answer and Adam Davis’s one…

Cheers

It would be best to go with his responses. He has significantly more knowledge of these systems than I do.

Alright, thanks Adam. :slight_smile:

Well… We’ll see now how we can do that. I really wish there would be support for 64b in this age tho but I don’t think that this is on the roadmap before long. :slight_smile: