So, been working on different things in this game engine, and one thing I always use is the X, Y, Z coordinates of an object.
This game has things defined in meters/centimeters, but in any game wherever something exists, it has a coordinate to place it in 3D space. When I first started, I ran across a problem with the numbers, namely they updated all the time because the game engine was simulating physics, so it introduced variations in the numbers out to nth-decimal places.
The raw data looked something like this:
When you play that, notice how Y seems to move no matter what, changing values constantly. The others do it too, but not as much.
The reason for this is that “Y” in the game is the axis that is perpendicular to the ground, so physics is always trying to figure out where that coordinate is for an object since there’s simulated gravity. At the same time, the ground plane is a colliding object, so it prevents the things on top of it from falling.
This results in a bunch of changing values, or “Jitter”. As you can see, the number of decimal places is staggering — 14 or so places! I don’t need that kind of precision for most things. In fact, I can get away with something like one or two decimal places.
Problem is, even if you round to the nearest decimal, one or two places, the numbers can change enough that you still get “Jitter”, even at that reduced resolution.
So what to do? Well, fortunately others have tackled this problem and I ran into a solution in a gaming forum for guys using custom controllers as inputs to flying simulators.
Here’s the code I came up with:
It looks more complicated than it is, because I’m doing it for all three axis — X, Y, Z at the same time.
The basic jist is, if I get a Jittery X input greater than an older stored X value OR its less than the stored value minus a threshold — then I store it and pass it on. If it fails any of those tests, I just keep the prior old stored value and don’t update it.
This has the effect of throwing out short-term fluctuations and results in a much smoother experience. (It essentially creates a band of values from oldX – threshold to oldX and chucks out any change that falls within it.) The variable is defined outside the function as —
threshold = 0.15 -- Jitter threshold
…and it gets referenced once we’re in there.
As I was working on the raycast part of my code, I noticed in-game I was getting some odd results. I was doing some spawning of objects, which looks like this:
Spawn("MOD/vox/SomeVoxModel.vox", Transform(Position, Rotation), true)
It just looks up something and spawns it in there. Easy-peasy, right? Sure.
I wanted to make something where you could spawn objects in an accurate way, which is where I ran into a problem using voxboxes. (A voxbox can have properties set in code, versus loading a static vox model.)
To do some of the things I wanted, I needed to be able to detect where the player was looking, so I knew where to put the next spawned object. This was easy enough using a function:
-- QueryRaycast: Origin, Direction, Maxdist, Radius, RejectTransparent true/false rayHit, shapeDistance, worldNormalList, shapeHandle = QueryRaycast(GetCameraTransform().pos, Direction, 10, 0, false)
It takes a bunch of arguments and then returns a bunch of data that gets stored in the variable names I have on the left side of the equals sign.
If it hit something, how far, the face “normal” which is just the direction of the face on an object, and the handle – which is a number that the game uses to track things. Each object gets one.
So I was humming along and things were working, but I needed to make sure that the “ray” would report the proper coordinates when needed. So I tested it using a voxbox. As I mentioned earlier, Its different than the regular models in the sense that you can change a lot of its properties, like color or material in code – which makes it more flexible than just importing a static model.
Determined to find the problem, I whipped up a test, but then things went wrong.
Here’s a video to show what I mean:
What you see there is me aiming at the object, but I only get data if I’m aiming at a specific corner of it. That is really weird/wrong, so I tested it with a shape that I loaded — which is different than the voxbox — and it worked for that one.
This made zero sense – it should work equally well for both.
So then I made ANOTHER test, this time documenting it in detail and making it as simple as possible. This time I used a function called:
This takes an object ‘handle’ number and returns two coordinates — one for the uppermost corner, and one for the lowermost corner. I put some debug cross things in there so I could see it visually when the game was running, and what I found out was — the cube had a ‘ghost’ that was connected at the lower ‘point’ of the cube and offset diagonally from it.
This shouldn’t be the case.
So I zipped up the demo and code, and posted it where the developer would see it.
I’m happy to say that I got a response – and they said “Yep, something’s wrong, gotta ask the guy that made the engine what is happening.” So, I found a bug and he’s gonna try to fix it. I’m sure he loves me right now, lol.
I did get a response not long ago and he indicated that it should be a simple fix. Which is awesome, and I got the nerd cred for finding an original bug in the engine itself!