AIPlayer - broken rotation - RESOLVED (THREED-2482)
by Ivan Mandzhukov · in Torque 3D Professional · 01/08/2011 (1:35 pm) · 32 replies
I am working with the AIPlayer these days.
I was trying to implement a chase logic with continious setMoveDestination() calls.
The positioning works correct,but there is a bug in the rotation stuff.
When move->yaw is arround 0 and 6,28(M_2PI_F),the rotation works in a reverse order,some sort of extrapolation instead of interpolation.
How to repreduce it:
1. spawn a bot.
2. schedule setAimLocation(%player.position) for each 30ms
3. go arround the bot
Do you see a jerk rotation?
I was trying to implement a chase logic with continious setMoveDestination() calls.
The positioning works correct,but there is a bug in the rotation stuff.
When move->yaw is arround 0 and 6,28(M_2PI_F),the rotation works in a reverse order,some sort of extrapolation instead of interpolation.
How to repreduce it:
1. spawn a bot.
2. schedule setAimLocation(%player.position) for each 30ms
3. go arround the bot
Do you see a jerk rotation?
#2
before the return at the end of AIPlayer::getAIMove help? Player and AIPlayer have a fair few ancient issues in there.
01/08/2011 (5:30 pm)
does adding movePtr->clamp();before the return at the end of AIPlayer::getAIMove help? Player and AIPlayer have a fair few ancient issues in there.
#3
It seems the move data in getAIMove() is correct,when I remove the warping all works well.
The extrapolation is wrong,I mean the logic that deals with delta.warpTicks
I think something wrong happens arround delta.warpOffset and delta.rotOffset.
01/08/2011 (5:43 pm)
Nope,I have just tried that.It seems the move data in getAIMove() is correct,when I remove the warping all works well.
The extrapolation is wrong,I mean the logic that deals with delta.warpTicks
I think something wrong happens arround delta.warpOffset and delta.rotOffset.
#4
Problem #1 and #2:
In Player::processTick(),go to the block where the warping is moved and replace the whole fragment.
The render position is wrong to be set here, interpolateTick() is the correct place for render transforms.
The rotation was also moved is a wrong way where we get incredibly wrong values (11,-5,..)
With this fix the transform bug is solved.
Problem #3
I saw that sometimes the rotation offsets generated from getAIMove() are really small,a mean they are quite complex real numbers, very close to zero (left and right from it).Since these values are not part of complex operations,they are safe.But according to the IEEE standard,their arithmetic operations can be really slow.They can take up to 850 cpu cycles.Just imagine if we have hundreds of AIs with bad rotations,the whole engine will lag for sure.So:
In unpackUpdate() locate this code:
This is it.I am testing this for two days,no problems at all.
01/10/2011 (2:07 pm)
Well,the problem is fixed.It took me a lot of time to investigate this bug.Here is a quick observation of the problem:Problem #1 and #2:
In Player::processTick(),go to the block where the warping is moved and replace the whole fragment.
if (delta.warpTicks > 0) {
delta.warpTicks--;
Point3F rotation = delta.rot + delta.rotOffset;
if(rotation.z < - M_PI_F)
rotation.z += M_2PI_F;
else if(rotation.z > M_PI_F)
rotation.z -= M_2PI_F;
// Set new pos.
getTransform().getColumn(3,&delta.pos);
delta.pos += delta.warpOffset;
delta.rot = rotation;
setPosition(delta.pos,delta.rot);
updateDeathOffsets();
updateLookAnimation();
// Backstepping
delta.posVec.x = -delta.warpOffset.x;
delta.posVec.y = -delta.warpOffset.y;
delta.posVec.z = -delta.warpOffset.z;
delta.rotVec.x = -delta.rotOffset.x;
delta.rotVec.y = -delta.rotOffset.y;
delta.rotVec.z = -delta.rotOffset.z;
}The render position is wrong to be set here, interpolateTick() is the correct place for render transforms.
The rotation was also moved is a wrong way where we get incredibly wrong values (11,-5,..)
With this fix the transform bug is solved.
Problem #3
I saw that sometimes the rotation offsets generated from getAIMove() are really small,a mean they are quite complex real numbers, very close to zero (left and right from it).Since these values are not part of complex operations,they are safe.But according to the IEEE standard,their arithmetic operations can be really slow.They can take up to 850 cpu cycles.Just imagine if we have hundreds of AIs with bad rotations,the whole engine will lag for sure.So:
In unpackUpdate() locate this code:
if (delta.warpTicks)
{
// Setup the warp to start on the next tick.
if (delta.warpTicks > sMaxWarpTicks)
delta.warpTicks = sMaxWarpTicks;
delta.warpOffset /= (F32)delta.warpTicks;
delta.rotOffset = rot - delta.rot;and below it add this one:// ignore small offsets if(delta.rotOffset.z>0 && delta.rotOffset.z<0.001f) delta.rotOffset.z = 0; if(delta.rotOffset.z<0 && delta.rotOffset.z>-0.001f) delta.rotOffset.z = 0;
This is it.I am testing this for two days,no problems at all.
#5
01/10/2011 (3:35 pm)
Just to check Ivan, should that last piece of code be added directly underdelta.rotOffset = rot - delta.rot; //here?or at the end of that block under
delta.rotOffset = rot - delta.rot;
if(delta.rotOffset.z < - M_PI_F)
delta.rotOffset.z += M_2PI_F;
else if(delta.rotOffset.z > M_PI_F)
delta.rotOffset.z -= M_2PI_F;
delta.rotOffset /= (F32)delta.warpTicks;
//here?
#6
this is my warping block in unpackUpdate():
01/10/2011 (3:52 pm)
Steve,this is my warping block in unpackUpdate():
if (delta.warpTicks)
{
// Setup the warp to start on the next tick.
if (delta.warpTicks > sMaxWarpTicks)
delta.warpTicks = sMaxWarpTicks;
delta.warpOffset /= (F32)delta.warpTicks;
delta.rotOffset = rot - delta.rot;
// ignore small offsets
if(delta.rotOffset.z>0 && delta.rotOffset.z<0.001f)
delta.rotOffset.z = 0;
if(delta.rotOffset.z<0 && delta.rotOffset.z>-0.001f)
delta.rotOffset.z = 0;
if(delta.rotOffset.z < - M_PI_F)
delta.rotOffset.z += M_2PI_F;
else if(delta.rotOffset.z > M_PI_F)
delta.rotOffset.z -= M_2PI_F;
delta.rotOffset /= (F32)delta.warpTicks;
}
#7
Cheers.
01/10/2011 (5:24 pm)
That's what I thought made sense ... but was just checking I was on my first cuppa tea ;)Cheers.
#8
01/10/2011 (8:20 pm)
Logged as THREED-1318.
#9
This thread is marked as resolved but the issue is still present in stock T3D 1.1final. No changes like those proposed by Ivan are in the Player code.
Making Ivan's changes solves the issue.
08/17/2011 (2:04 am)
**BUMP**This thread is marked as resolved but the issue is still present in stock T3D 1.1final. No changes like those proposed by Ivan are in the Player code.
Making Ivan's changes solves the issue.
#10
08/17/2011 (7:38 am)
Yeah, this is why the AiPlayer in stock "freaks out" and spins when they approach their destination ... and why it does happen with my custom project!Guiz ... Say, Guiz! This needs goin' into stock, Guiz.
#11
08/17/2011 (9:26 am)
Not sure what happen here. THREED-1318 was not related to this issue. I went ahead and logged a new ticket under THREED-2482. Thanks to everyone for bring this to our attention.
#12
Why does Guiz have to do everything?
08/18/2011 (6:12 am)
Interesting - does it still happen when using setAimObject? I've played with AIPlayers in TGE and not seen this, but I've always used setAimObject instead of a scheduled setAimLocation.Why does Guiz have to do everything?
#13
08/18/2011 (6:40 am)
Daniel, yes, in the video I posted the AIPlayer is using setAimObject to target me.
#14
10/11/2011 (4:32 pm)
Fixed in 1.2.
#15
02/15/2014 (8:32 am)
fixed 1.2??? its not in mit 3.5.....
#16
02/24/2014 (5:21 am)
is this fixed in latest version?
#17
03/03/2014 (7:00 pm)
it wasnt in MIT 3.5
#18
Thanks
06/25/2014 (8:58 pm)
Hey all I don't know if my issue is related to this thread or not but I thought id start here. I pulled down the latest MIT build, compiled fine and ran it. When I click play game, I start in the middle of an empty desert, which is normal, but my camera controls are wacked. The camera is spinning around, and seems inverted. If I wiggle the mouse, it stops for a moment. I can walk around a bit as long as I don't try to turn with the mouse. When I try to turn, I spin around and camera drags to the dirt and I cant move. Not sure what's going on but I did look at the code posted earlier in this thread. It seems that the code was modified to be similar to the solution posted so I didn't change anything. Is there a known issue here, and can someone point in a direction. I simply don't have the time to dig around the player class and figure It out, I'm hoping someone else already knows the answer so I can begin learning this engine.Thanks
#19
06/25/2014 (11:55 pm)
Have you tried mvReset(); in the console? I don't know if it solves the problem, but the main thing this function does is resetting all the triggers involved in moving your character.
#20
Thanks
06/26/2014 (7:10 am)
Hey Richard, I just tried that and I didn't see a difference. Seems as though the camera controls are out of control here. One thing I also tried that I didn't try before was detaching the camera from the player, and even in free look its spinning out of control. I tried to debug it in the player class and I see rotations above 200 on the z, although this could be in degrees instead of radians, but I am not sure if this is a valid value. Shouldn't it be a normalized value?Thanks
Torque Owner Ivan Mandzhukov
Liman3D
When I set:
..rotation is now correct,but no interpolation at all.
I can't beleive this is a 10 years old bug and nobody have seen that AIs have a transformation problem.