For direct access use https://forums.oldunreal.com
It's been quite a while since oldunreal had an overhaul, but we are moving to another server which require some updates and changes. The biggest change is the migration of our old reliable YaBB forum to phpBB. This system expects you to login with your username and old password known from YaBB.
If you experience any problems there is also the usual "password forgotten" function. Don't forget to clear your browser cache!
If you have any further concerns feel free to contact me: Smirftsch@oldunreal.com

Rotation Grabber Issue

The section related to UnrealScript and modding. This board is for coders to discuss and exchange experiences or ask questions.
User avatar
LannFyre
OldUnreal Member
Posts: 157
Joined: Fri Mar 13, 2015 7:01 am

Rotation Grabber Issue

Post by LannFyre »

I have a way to determine a player's rotation, then determine a rotator check between a camera and said player, and the result of some math between the two gives me a total I can plug into a final section that decides what number out of 8 to output based on the player's location/rotation.  This is to give me a value I can use to assign a certain set of sprites.  But I'm having an issue: someone gave me an additional section to get rid of additional rotations above 65536 and to adjust values below 0 so this function will work.  Instead, now if I use said code and my camera is in front of said player and the player is looking in the direction of the camera, I will always get a result of 0 and get either the wrong sprite or no sprite.  Can anyone take a look at this function and assist me?

I've broken this up into three sections: log results, the function in question, and what was added to the function to fix the issue.

log:

Code: Select all

ScriptLog: R1:  0,16384,0
ScriptLog: R2:  1044,12287,0
ScriptLog: R3:  64492,4097,0
ScriptLog: R3 Adjust:  64492,4097,0
ScriptLog: RotResult:  0.000000
ScriptLog: NewSpriteIndex:  0
function

Code: Select all

final function int AdjustDirIndex(Actor sAnimated, RPG_Camera Camera, out int NewSpriteIndex)
{
      local Rotator      R1,R2,R3;
      local int             IndexMax, OldIndex;
      local float            RotResult;
      local bool            bCounterclockwise;
      IndexMax = 8;

      R1 = sAnimated.Rotation;
      log("R1: " @ R1);
      R2 = ( Rotator(Camera.Location - sAnimated.Location) + rot(0,-4096,0)  );
      log("R2: " @ R2);
      R3 = (R1 - R2);
      log("R3: " @ R3);
      
      [INSERT BELOW CODE HERE]

      RotResult = ( ( R3.Yaw / (65536 / IndexMax) ) ) - ( ( ( R3.Yaw / (65536 / IndexMax) ) ) % 1 );
      log("RotResult: " @ RotResult);

      NewSpriteIndex = int(RotResult);
      OldIndex = NewSpriteIndex;
      
      if ( OldIndex > IndexMax )
      {
            NewSpriteIndex = ( OldIndex % IndexMax );
            log("IndexAdjust: " @ NewSpriteIndex);
            OldIndex = NewSpriteIndex;
      }
      else
            log("NewSpriteIndex: " @ NewSpriteIndex);
      return NewSpriteIndex;
}
What was added:

Code: Select all

      if (R3.yaw < 0)
      {
            bCounterclockwise = true;
            R3.yaw =- R3.yaw;
      }
      if ( R3.yaw > 65536 )
            R3.yaw = R3.yaw % 65536; // throw away all multiple rotations of 360°
      if (bCounterclockwise && R3.yaw != 0)
            R3.yaw = 65536 - R3.yaw; // make counterclockwise to clockwise
      log("R3 Adjust: " @ R3);
Last edited by LannFyre on Wed Dec 28, 2016 4:00 am, edited 1 time in total.
i tryin'a be a gud boi
User avatar
ExpEM
OldUnreal Member
Posts: 74
Joined: Sun Jan 20, 2013 4:10 am

Re: Rotation Grabber Issue

Post by ExpEM »

Not fully aware of what your 'player to camera' set up is, it's hard to help (Hint: Screenshots help).

Sounds like it could be done with dot products (If what I imagine you want to do is correct).

Something like:
"Is Player looking toward or away from Camera?"
Followed by:
"Is Player looking to left or right of Camera?"

With the output of both it shouldn't be hard to get the correct sprite.

This should help some (section 2.4 and 2.5 is what you want I think).

http://wiki.beyondunreal.com/Legacy:UnrealScript_Vector_Maths
-Finding new ways to break the engine since 1872.
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Re: Rotation Grabber Issue

Post by Bleeder91[NL] »

No idea if this helps but if I understand what you're doing here then you could probably go for an easier approach:

Code: Select all

function bool NeedToTurn(vector targ)
{
      local int YawErr;

      DesiredRotation = Rotator(targ - location);
      DesiredRotation.Yaw = DesiredRotation.Yaw & 65535;
      YawErr = (DesiredRotation.Yaw - (Rotation.Yaw & 65535)) & 65535;
      if ( (YawErr < 4000) || (YawErr > 61535) )
            return false;

      return true;
}
From ScriptedPawn. Now if we adapt that to the following:

Code: Select all

final function byte RotationToSprite(Actor sAnimated, RPG_Camera Camera)
{
      local Rotator Rotty;
      local int YawErr;
      
      Rotty = Rotator(sAnimated.Location - Camera.Location);
      Rotty.Yaw = Rotty.Yaw & 65535;
      YawErr = (Rotty.Yaw - (Camera.Rotation.Yaw & 65535)) & 65535;
      YawErr=(8*(YawErr/65535))%8; //Gives a number of 0-7.
      
      return YawErr;
}
You get a function that outputs the numbers 0-7. I assumed 8 would be the same sprite as 0 since they both face the camera. Hope you can see what I did thar. :P
Last edited by Bleeder91[NL] on Wed Dec 28, 2016 11:04 am, edited 1 time in total.
Image
User avatar
[]KAOS[]Casey
OldUnreal Member
Posts: 4497
Joined: Sun Aug 07, 2011 4:22 am
Location: over there

Re: Rotation Grabber Issue

Post by []KAOS[]Casey »

God damn I wish I had that when I made the devastator recreation. I just used some fucking awful if checks to determine sprites
User avatar
han
Global Moderator
Posts: 686
Joined: Wed Dec 10, 2014 12:38 am

Re: Rotation Grabber Issue

Post by han »

Code: Select all

RotResult = ( ( R3.Yaw / (65536 / IndexMax) ) ) - ( ( ( R3.Yaw / (65536 / IndexMax) ) ) % 1 );
Well, any integer modulo 1 will be zero as there won't be any remainder.
HX on Mod DB. Revision on Steam. Löffels on Patreon.
User avatar
LannFyre
OldUnreal Member
Posts: 157
Joined: Fri Mar 13, 2015 7:01 am

Re: Rotation Grabber Issue

Post by LannFyre »

Higor got back to me on this one and gave me an understanding of how bit shifting works, so I'm gonna post the solution then his message.

Code: Select all

final function int AdjustDirIndex(Actor sAnimated, RPG_Camera Camera, out int AnimDir)
{
      local Rotator      R1,R2;
//      MAX_WORD is 0b1111111111111111 (65535, 16 bits)
//      MAX_DIR is 0b0000000000000111 (7, 3 bits)

      R1 = sAnimated.Rotation;
      R2 = Rotator(Camera.Location - sAnimated.Location);
//V1 = Camera.Location;
//R2 = Camera.Rotation;
      
      AnimDir = ( ( (R1.Yaw - R2.Yaw) & 65535) + 4096) >> 13;
//log("AnimDir: " @ AnimDir);

      return AnimDir;
}
So first do a function call ( AdjustDirIndex(testactor, aPawnWithAViewport, outputIndex) ).

The function will grab the rotation of the first actor, which as far as I know can be any actor.  Then a rotator is set based on the relative position of aPawnWithAViewport (or any actor really, modify it however you wish) and the first actor's location.  Then the two actors' resulting Yaw is subtracted to get a general number to determine the facing direction of the target actor relative to aPawnWithAViewport.

You take that value and restrict it to 65535 (a value in between 0 and 65536, broken down is 256^2).  After that is done, if my understanding is correct, you can now take the resulting bits that come of a negative and positive rotation that will reset to zero if their value is greater than 65535 (since 65536 is equivalent to 0 I think).  You then offset the result of the two rotations by 4096 so when you are standing directly in front of the target actor that will have sprites, you will get a different sprite index based on the position you are standing if you are either at the front, back, either side, or at an angle of the sprite.  Otherwise, you will get two different sprites if you are in front of the actor and are just slightly off center of the actor to either side.  I'll post a video of this in practice when I get a new hard drive, mine is seeing it's last days.  Then with the resulting integer, you take the 3 most important bits (1,2,4, which can be any value between 0 and 7 which gives us 8 different positions) and grab those for our position output.  This last part with bit shifting is hazy to me, so I'll leave his message to explain that part:
Bitwise operators are your friend.

HEX representation of 0 (DWORD): 0x00000000
HEX representation of 65536 (DWORD): 0x00010000
Both are the same in unreal rotators, so we can completely discard any data beyond the first WORD (right to left)
If we need to operate on those values and our algorithms have a chance of being borked due to values outside of the 0-65535 (one less than 65536) range, then we need to quickly discard the additional data.

Bitwise AND is the right choice:

Code: Select all

local int RY;
RY = (R1.Yaw - R2.Yaw) & 65535;
What's going on here?
HEX representation of 65535 (DWORD): 0x0000FFFF
Bit representation of 65535: 0b00000000000000001111111111111111
Bit representation of 65536: 0b00000000000000010000000000000000
The bitwise AND keeps 1 if both sources are 1, sets to 0 otherwise.
This means that 65535 is a bitmask used to reduce DWORD into a WORD

So, this happens:
HEX representation of 0 (WORD): 0x0000
HEX representation of 65536 (WORD): 0x0000 (not recyprocal)
HEX representation of 65535 (WORD): 0xFFFF
HEX representation of -1 (WORD): 0xFFFF (not recyprocal)


Since you want to convert these into 8 directions and the 0/65536 reference point is a center, not a limit you'll have to 'right' offset this by 1/16 of the full range.
65536/16 = 4096
Now we update the snippet. (If I screwed up then just change signs until it looks ok)

Code: Select all

local int RY;
RY = (R1.Yaw - R2.Yaw) + 4096) & 65535;
With this done, and the coordinates offset by 1/16 of the range, we've correctly offset the 0 'reference' point so that it indicates a boundary between the first and second direction, instead of the center of the first direction.
This means that dividing by 8192 will give us the correct directions of a yaw coord.
But since we're dividing by 2^n values, let's do some more bitwise math here.
MAX_WORD is 0b1111111111111111 (65535, 16 bits)
MAX_DIR is 0b0000000000000111 (7, 3 bits)
The highest bits of the YAW coordinate are the ones we're after, we don't even need a division in this case, we just need to shift the bit set of the YAW coordinate by 16-3 places to the right.
Change the snippet to get the actual direction now:

Code: Select all

local int AnimDir;
AnimDir = ((RotationA.Yaw + RotationB.Way) + 4096) & 65535) >> 13;
Last edited by LannFyre on Mon Jan 09, 2017 2:17 pm, edited 1 time in total.
i tryin'a be a gud boi
User avatar
LannFyre
OldUnreal Member
Posts: 157
Joined: Fri Mar 13, 2015 7:01 am

Re: Rotation Grabber Issue

Post by LannFyre »

I apologize for double posting, but I did say I'd have a video to upload.

Last edited by LannFyre on Mon Jan 09, 2017 8:54 pm, edited 1 time in total.
i tryin'a be a gud boi

Return to “UScript Board”