RMenu
Class RuneLookMesh

source: c:\runehov\RMenu\Classes\RuneLookMesh.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Info
         |
         +--RMenu.RuneMeshActor
            |
            +--RMenu.RuneLookMesh
Direct Known Subclasses:None

class RuneLookMesh
extends RMenu.RuneMeshActor


Variables
 rotator LookAngle
           Angle currently looking
 vector LookSpot
 rotator targetangle
           Only used when bOverrideLookTarget


Function Summary
 void Look(float DeltaTime)
 void PostBeginPlay()
     
// Allow the head to look up double the MaxHeadAngle Pitch
 void Tick(float DeltaTime)
 void Timer()



Source Code


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	}

End Source Code