Core.Object | +--Engine.Actor | +--Engine.Info | +--RMenu.RuneMeshActor | +--RMenu.RuneLookMesh
rotator
LookAngle
vector
LookSpot
targetangle
void
Look(float DeltaTime)
PostBeginPlay()
// Allow the head to look up double the MaxHeadAngle Pitch
Tick(float DeltaTime)
Timer()
00001 class RuneLookMesh extends RuneMeshActor; 00002 00003 00004 var vector LookSpot; 00005 var rotator targetangle; // Only used when bOverrideLookTarget 00006 var rotator LookAngle; // Angle currently looking 00007 var(Look) float LookDegPerSec; // Degrees/Second velocity for turning to look 00008 var(AI) float PeripheralVision; // Cosine of limits of peripheral vision. (-1..1) 00009 var(Look) rotator MaxBodyAngle; // Max angles on each axis for body turning 00010 var(Look) rotator MaxHeadAngle; // Max angles on each axis for head turning 00011 var(Look) bool bRotateHead; 00012 var(Look) bool bRotateTorso; // Torso turns during look 00013 var(Look) bool bHeadLookUpDouble; // Allow the head to look up double the MaxHeadAngle Pitch 00014 00015 00016 function PostBeginPlay() 00017 { 00018 LookSpot = Location + vect(20, 0, 0); 00019 SetTimer(RandRange(1, 1.5), true); 00020 } 00021 00022 function Timer() 00023 { 00024 LookSpot = Location + VRand()*100; 00025 } 00026 00027 function Tick(float DeltaTime) 00028 { 00029 Look(DeltaTime); 00030 } 00031 00032 function Look(float DeltaTime) 00033 { 00034 local int head,body; 00035 local float headdeg,bodydeg,rotvel; 00036 local rotator headangle, bodyangle; 00037 local rotator ragnarRot; 00038 local float headPitchUp; 00039 local int joint; 00040 00041 if (Skeletal==None) 00042 return; 00043 00044 ragnarRot = Rotation; 00045 ragnarRot.Pitch = 0; 00046 00047 targetangle = rotator(LookSpot - Location); 00048 targetangle -= ragnarRot; 00049 00050 // Fix angles (0..180,0..-180) 00051 while (targetangle.Yaw > 32768) 00052 targetangle.Yaw = targetangle.Yaw - 65535; 00053 while (targetangle.Yaw < -32768) 00054 targetangle.Yaw = targetangle.Yaw + 65535; 00055 while (targetangle.Pitch > 32768) 00056 targetangle.Pitch = targetangle.Pitch - 65535; 00057 while (targetangle.Pitch < -32768) 00058 targetangle.Pitch = targetangle.Pitch + 65535; 00059 00060 rotvel = LookDegPerSec * 65535.0 / 360.0; 00061 00062 // If target is in dead zone, return to looking forward 00063 if (cos(targetangle.Yaw*2.0*Pi/65535.0) < PeripheralVision) 00064 { 00065 targetangle = rot(0,0,0); 00066 rotvel *= 0.5; // slower rate when returning to straight 00067 } 00068 00069 // Yaw towards target angle 00070 if (targetangle.Yaw < LookAngle.Yaw) 00071 { // Turning left 00072 LookAngle.Yaw -= rotvel * DeltaTime; 00073 if (LookAngle.Yaw < targetangle.Yaw) // Disallow overshoot 00074 LookAngle.Yaw = targetangle.Yaw; 00075 } 00076 else 00077 { // Turning right 00078 LookAngle.Yaw += rotvel * DeltaTime; 00079 if (LookAngle.Yaw > targetangle.Yaw) // Disallow overshoot 00080 LookAngle.Yaw = targetangle.Yaw; 00081 } 00082 00083 // Pitch towards target angle 00084 rotvel = 0.5 * LookDegPerSec * 65535.0 / 360.0; 00085 if (targetangle.Pitch < LookAngle.Pitch) 00086 { // Pitching Up 00087 LookAngle.Pitch -= rotvel * DeltaTime; 00088 if (LookAngle.Pitch < targetangle.Pitch) 00089 LookAngle.Pitch = targetangle.Pitch; 00090 } 00091 else 00092 { // Pitching Down 00093 LookAngle.Pitch += rotvel * DeltaTime; 00094 if (LookAngle.Pitch > targetangle.Pitch) 00095 LookAngle.Pitch = targetangle.Pitch; 00096 } 00097 00098 if(bHeadLookUpDouble) 00099 { 00100 headPitchUp = MaxHeadAngle.Pitch * 2; 00101 } 00102 else 00103 { 00104 headPitchUp = MaxHeadAngle.Pitch; 00105 } 00106 00107 // Now translate LookAngle.Yaw into head and body angles 00108 if (bRotateHead) 00109 { 00110 headangle = LookAngle; 00111 00112 00113 // Overflow any extra angle beyond head maximums into body 00114 if (headangle.Yaw > MaxHeadAngle.Yaw) 00115 { 00116 bodyangle.Yaw = headangle.Yaw - MaxHeadAngle.Yaw; 00117 headangle.Yaw = MaxHeadAngle.Yaw; 00118 } 00119 else if (headangle.Yaw < -MaxHeadAngle.Yaw) 00120 { 00121 bodyangle.Yaw = headangle.Yaw + MaxHeadAngle.Yaw; 00122 headangle.Yaw = -MaxHeadAngle.Yaw; 00123 } 00124 00125 if (headangle.Pitch > headPitchUp) 00126 { 00127 bodyangle.Pitch = headangle.Pitch - headPitchUp; 00128 headangle.Pitch = headPitchUp; 00129 } 00130 else if (headangle.Pitch < -MaxHeadAngle.Pitch) 00131 { 00132 bodyangle.Pitch = headangle.Pitch + MaxHeadAngle.Pitch; 00133 headangle.Pitch = -MaxHeadAngle.Pitch; 00134 } 00135 } 00136 else if (bRotateTorso) 00137 { 00138 bodyangle = LookAngle; 00139 } 00140 00141 // Do head roll 00142 if (MaxHeadAngle.Roll > 0) // TODO: Make proportional 00143 headangle.Roll = headangle.Yaw / 2; 00144 if (MaxBodyAngle.Roll > 0) // TODO: Make proportional 00145 bodyangle.Roll = bodyangle.Yaw / 2; 00146 00147 // Clamp to max angles 00148 bodyangle.Yaw = Clamp(bodyangle.Yaw, -MaxBodyAngle.Yaw, MaxBodyAngle.Yaw); 00149 bodyangle.Pitch = Clamp(bodyangle.Pitch, -MaxBodyAngle.Pitch, MaxBodyAngle.Pitch); 00150 bodyangle.Roll = Clamp(bodyangle.Roll, -MaxBodyAngle.Roll, MaxBodyAngle.Roll); 00151 headangle.Yaw = Clamp(headangle.Yaw, -MaxHeadAngle.Yaw, MaxHeadAngle.Yaw); 00152 headangle.Pitch = Clamp(headangle.Pitch, -MaxHeadAngle.Pitch, headPitchUp); 00153 headangle.Roll = Clamp(headangle.Roll, -MaxHeadAngle.Roll, MaxHeadAngle.Roll); 00154 00155 //headdeg = headangle.Yaw * 360.0 / 65536.0; 00156 //bodydeg = bodyangle.Yaw * 360.0 / 65536.0; 00157 //Log("Head="$headdeg$" Body="$bodydeg); 00158 00159 headangle += Rotation; 00160 bodyangle += Rotation; 00161 00162 joint = JointNamed('torso'); 00163 if (joint != 0) 00164 { 00165 if (bRotateTorso) 00166 TurnJointTo(joint, bodyangle); 00167 else 00168 TurnJointTo(joint, Rotation); // No extra rotation 00169 } 00170 00171 joint = JointNamed('head'); 00172 if (joint != 0) 00173 { 00174 if (bRotateHead) 00175 TurnJointTo(joint, headangle); 00176 else 00177 TurnJointTo(joint, Rotation); // No extra rotation 00178 } 00179 } 00180 00181 defaultproperties 00182 { 00183 LookDegPerSec=360.000000 00184 PeripheralVision=-1.000000 00185 MaxBodyAngle=(Yaw=8192) 00186 MaxHeadAngle=(Pitch=4096,Yaw=8192) 00187 bRotateHead=True 00188 bRotateTorso=True 00189 bHeadLookUpDouble=True 00190 }