UMSCamera
Class MovieCamera

source: e:\games\UnrealTournament\UMSCamera\Classes\MovieCamera.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--UMS1_6.UMS
         |
         +--UMSCamera.MovieCamera
Direct Known Subclasses:SmoothCamera

class MovieCamera
extends UMS1_6.UMS

//============================================================================= // MovieCamera. //=============================================================================
Variables
 rotator ChaseRotOffset
 Actor ChaseTarget
 rotator ChaseVecOffRot
 float ChaseVecOffSize
 float CircleShrinkAmount
 float CircleShrinkRadius
 float CircleShrinkTime
 Actor CircleTarget
 vector CirclingOffset
 rotator CirclingSpeed
 float CurrentFOV
 float DesiredFOV
 vector DesiredLocation
 vector DollyChange
 Actor DollyTarget
 float DollyTime
 float DollyTotalTime
 vector OriginalDollyLocation
 rotator OriginalPanRotation
 rotator PanChange
 Actor PanTarget
 float PanTime
 float PanTotalTime
 vector Radius
 rotator TargetRotation
 rotator TrackingDirections
 vector TrackingOffset
 Actor TrackingTarget
 float VertigoConst
 Actor VertigoTarget
 float ZoomChange
 float ZoomTime
 bool bActive
 bool bChaseCam
 bool bCircleShrinking
 bool bCircling
 bool bDollying
 bool bFlip
 bool bFlipNext
 bool bPanning
 bool bTracking
 bool bVertigo
 bool bZooming


Function Summary
 void DoChaseCam(Actor NewTarget, vector Offset, rotator RotOffset)
 void DoCircleShrink(vector NewRadius, float TimeToChange)
 void DoCircling(Actor NewTarget, rotator Speed, vector Offset, float Distance)
 void DoDolly(vector NewLocation, Actor NewTarget, float Time)
 void DoInterpolate(Actor InterpPoint, float DesiredRate, float DesiredAlpha)
 void DoPan(rotator NewRotation, Actor NewTarget, float Time)
     
//The Do Functions
//Each command that is given to a camera takes the form of calling a
//Do funtion, which sets up the camera to do the command properly.
 void DoTracking(Actor NewTarget, vector Offset, rotator Directions)
 void DoVertigo(Actor NewTarget)
 void DoZoom(float NewFOV, float Time)
 void InterpolateEnd(Actor InterpPoint)
 void setActive(bool bActivate)
 void setFOV()



Source Code


00001	//=============================================================================
00002	// MovieCamera.
00003	//=============================================================================
00004	class MovieCamera expands UMS;
00005	
00006	//The current FOV of the camera.
00007	var() float CurrentFOV;
00008	//Whether this camera is active or not...
00009	var bool bActive;
00010	//The number of units of rotation that make up half a full rotation,
00011	//or one Pi radians.
00012	const RotPiVal = 32768;
00013	
00014	//Panning actually includes tilting and rotating the camera, since 
00015	//all three can be controlled with it -- let me know if you need
00016	//seperate functions for the three kinds of rotation
00017	var bool bPanning;
00018	//The rotation to pan to
00019	var rotator TargetRotation;
00020	//The number of seconds to spend rotating
00021	var float PanTime;
00022	var float PanTotalTime;
00023	var rotator OriginalPanRotation;
00024	//The change in Pan per second
00025	var rotator PanChange;
00026	//The actor the camera is trying to pan to
00027	var actor PanTarget;
00028	//Dollying is moving the camera around, to set locations.
00029	var bool bDollying;
00030	//The location the camera is trying to dolly to.
00031	var vector DesiredLocation;
00032	var vector OriginalDollyLocation;
00033	//The number of seconds to spend dollying
00034	var float DollyTime;
00035	var float DollyTotalTime;
00036	//The change in camera location per second
00037	var vector DollyChange;
00038	//The actor the camera is trying to dolly to
00039	var actor DollyTarget;
00040	//Changing the Field Of View to see more or less of the picture.
00041	var bool bZooming;
00042	//The FOV the camera is trying to zoom to.
00043	var float DesiredFOV;
00044	//The number of seconds to spend zooming.
00045	var float ZoomTime;
00046	//The change per second while zooming
00047	var float ZoomChange;
00048	//The camera must stay pointed at the TrackingTarget.
00049	var bool bTracking;
00050	//The offset while tracking
00051	var vector TrackingOffset;
00052	//The actor the camera is tracking
00053	var Actor TrackingTarget;
00054	//The directions that will be tracked.  If the value is greater than
00055	//or equal to zero that kind of rotation will be used to track.  So
00056	//only if you don't want to track in a given direction will you want
00057	//to set one of the values to -1.
00058	var rotator TrackingDirections;
00059	//The camera is right behind some actor, and stays exactly behind it.
00060	var bool bChaseCam;
00061	//The vector offset the camera is from the actor being chased, in the
00062	//form of a rotator and a size
00063	var rotator ChaseVecOffRot;
00064	var float ChaseVecOffSize;
00065	//The rotation offset as the camera chases
00066	var rotator ChaseRotOffset;
00067	//The actor the camera is chasing.
00068	var actor ChaseTarget;
00069	//The camera is circling some point, or some moving actor, but not
00070	//pointing at it (unless combined with tracking).
00071	var bool bCircling;
00072	//The radius between the point and the camera that the camera uses
00073	//to rotate.
00074	var vector Radius;
00075	//The change of rotation per second while circling
00076	var rotator CirclingSpeed;
00077	//The offset while circing
00078	var vector CirclingOffset;
00079	//The actor the camera is circling.
00080	var actor CircleTarget;
00081	//The camera needs to flip due to circling over a tracked target.
00082	var bool bFlip;
00083	var bool bFlipNext;
00084	//Whether the camera is holding an actor in the middle of the screen
00085	var bool bVertigo;
00086	//The value that is set when the HoldZoom is started
00087	var float VertigoConst;
00088	//The target for holding the zoom on
00089	var actor VertigoTarget;
00090	//Whether the Circling radius is changing (it can be growing as well as shrinking)
00091	var bool bCircleShrinking;
00092	//The time for the radius to change
00093	var float CircleShrinkTime;
00094	//The radius after the change
00095	var float CircleShrinkRadius;
00096	//The amount that the circle will change per second
00097	var float CircleShrinkAmount;
00098	
00099	
00100	//Everything happens in Tick.  UnrealScript calls Tick several times
00101	//a second, with DeltaTime being the time since the last tick (which
00102	//changes all the time).  So we always check to see what needs to be
00103	//updated in tick.
00104	//
00105	//Right now there are several combinations of commands that don't 
00106	//work.  Let me know if you need any of these changed, since it is
00107	//possible to change some of these with a little extra code.
00108	//
00109	//Invalid Combinations:
00110	//	+ Circling with dollying, chase cam, or interpolation.
00111	//	+ ChaseCam with anything other than zooming.
00112	//	+ Tracking with chase cam or panning.
00113	//  + Panning with tracking or chase cam.
00114	//  + Dollying with chase cam, circling, or interpolation.
00115	//  + Interpolation with chase cam, circling, or dollying.
00116	
00117	
00118	event Tick(float DeltaTime)
00119	{
00120		local vector TempVec, X, Y, Z;
00121		local rotator TempRot, TempRot2;
00122		local float TempFloat, TempFloat2;
00123		local PlayerPawn P;
00124		
00125		//Check for interpolation
00126		if(bInterpolating)
00127		{
00128			//Do nothing, regular physics will handle this
00129		}
00130		else
00131			SetPhysics(PHYS_None);
00132		
00133		//Check for panning
00134		if(bPanning)
00135		{
00136			//First, do update for moving target/camera if neccesary.
00137			if(PanTarget != NONE)
00138			{
00139				TempRot = rotator(PanTarget.Location - Location);
00140				DoPan(TempRot, PanTarget, PanTime);
00141			}
00142			
00143			//We need a check to see if it is done.
00144			if(PanTime <= DeltaTime)
00145			{
00146				SetRotation(TargetRotation);
00147				bPanning = false;
00148			}
00149			else
00150			{
00151				SetRotation(Rotation + (PanChange * DeltaTime));
00152				PanTime -= DeltaTime;
00153			}
00154		}
00155		
00156		//Check for dollying
00157		if(bDollying)
00158		{
00159			//First, do update for moving target if neccesary.
00160			if(DollyTarget != NONE)
00161			{
00162				TempVec = DollyTarget.Location;
00163				DoDolly(TempVec, DollyTarget, DollyTime);
00164			}
00165	
00166			//Check to make sure you do not over-dolly
00167			if(DollyTime <= DeltaTime)
00168			{
00169				SetLocation(DesiredLocation);
00170				bDollying = false;
00171			}
00172			else
00173			{
00174				SetLocation(Location + (DollyChange * DeltaTime));
00175				DollyTime -= DeltaTime;
00176			}
00177		}
00178		
00179		//Check for zooming
00180		if(bZooming)
00181		{
00182			//Check to see if finished zooming.
00183			if(ZoomTime <= DeltaTime)
00184			{
00185				CurrentFOV = DesiredFOV;
00186				bZooming = false;
00187			}
00188			else
00189			{
00190				CurrentFOV += ZoomChange * DeltaTime;
00191				ZoomTime -= DeltaTime;
00192			}
00193			setFOV();
00194		}
00195		
00196		if(bVertigo)
00197		{
00198			if(VertigoTarget == NONE)
00199				bVertigo = false;
00200			else
00201			{
00202				TempFloat = vsize(Location - VertigoTarget.Location);
00203				TempFloat2 = 2 * atan(VertigoConst / TempFloat);
00204				CurrentFOV = TempFloat2 * (180 / pi);
00205			}
00206		}
00207	
00208		if(bCircleShrinking)
00209		{
00210			if(!bCircling)
00211				bCircleShrinking = false;
00212			else
00213			{
00214				TempFloat = CircleShrinkRadius/CircleShrinkTime;
00215			}
00216		}
00217	
00218		//Check for circling
00219		if(bCircling)
00220		{	
00221			//First, check to see if we have lost our target.
00222			if(CircleTarget == NONE)
00223				bCircling = false;
00224			else
00225			{
00226				TempRot = rotator(Radius);
00227				TempRot2 = CirclingSpeed * DeltaTime;
00228				
00229				//Check for over-head switch
00230				if(abs(TempRot.Pitch + TempRot2.Pitch) > (RotPiVal/2))
00231				{
00232					TempRot.Yaw += RotPiVal;
00233					CirclingSpeed.Pitch *= -1;
00234					//Flip the camera over so it does not look goofy.
00235					bFlip = !bFlip;
00236				}
00237				
00238				TempRot += CirclingSpeed * DeltaTime;			
00239				TempVec = vector(TempRot) * VSize(Radius);
00240				Radius = TempVec;
00241				SetLocation(CircleTarget.Location + Radius + CirclingOffset);
00242			}
00243		}
00244		
00245		//Check for tracking
00246		if(bTracking)
00247		{
00248			//First, check to see if we have lost our target.
00249			if(TrackingTarget == NONE)
00250				bTracking = false;
00251			else
00252			{
00253				TempVec = (TrackingTarget.Location + TrackingOffset) - Location;
00254				TempRot = rotator(TempVec);
00255				//Examine TrackingDirections to determine how to track.
00256				if(TrackingDirections.Yaw < 0)
00257					TempRot.Yaw = 0;
00258				if(TrackingDirections.Pitch < 0)
00259					TempRot.Pitch = 0;
00260				if(TrackingDirections.Roll < 0)
00261					TempRot.Roll = 0;
00262				//Flip over the camera if needed.
00263				if(bFlip)
00264				{
00265					TempRot.Roll += RotPiVal;
00266				}
00267				SetRotation(TempRot);
00268				
00269			}
00270		}
00271	
00272		//Check for chase cam
00273		if(bChaseCam)
00274		{
00275			//Check to see if target has been lost.
00276			if(ChaseTarget == NONE)
00277				bChaseCam = false;
00278			else
00279			{
00280				SetRotation(ChaseTarget.Rotation + ChaseRotOffset);
00281				TempRot = Rotation + ChaseVecOffRot;
00282				TempVec = vector(TempRot);
00283				TempVec *= ChaseVecOffSize;
00284				SetLocation(ChaseTarget.Location + TempVec);
00285			}
00286		}
00287	}
00288	
00289	
00290	function setFOV()
00291	{
00292		local PlayerPawn M;
00293		
00294	    foreach AllActors(class 'PlayerPawn', M)
00295	    {
00296	    	M.desiredFOV = currentFOV;
00297	    }
00298	}
00299	
00300	function setActive(bool bActivate)
00301	{
00302		bActive = bActivate;
00303		
00304		if(bActive)
00305			setFOV();
00306	}
00307	
00308	//The Do Functions
00309	//Each command that is given to a camera takes the form of calling a
00310	//Do funtion, which sets up the camera to do the command properly.
00311	
00312	function DoPan(rotator NewRotation, actor NewTarget, float Time)
00313	{
00314	    //Check for instant pan.
00315		if(Time == 0)
00316		{
00317			SetRotation(NewRotation);
00318			bPanning = false;
00319		}		
00320		else
00321		{
00322			bPanning = true;
00323			bChaseCam = false;
00324			bTracking = false;
00325			PanTime = Time;
00326			PanTarget = NewTarget;
00327	        TargetRotation = NewRotation;
00328	        while((TargetRotation.yaw - Rotation.yaw) > 32768)
00329	        {
00330	            TargetRotation.yaw -= 65536;
00331	        }
00332	        while((TargetRotation.pitch - Rotation.pitch) > 32768)
00333	        {                  
00334	            TargetRotation.pitch -= 65536;
00335	        }
00336	        while((TargetRotation.roll - Rotation.roll) > 32768)
00337	        {
00338	            TargetRotation.roll -= 65536;
00339	        }
00340	        while((TargetRotation.yaw - Rotation.yaw) < -32768)
00341	        {
00342	            TargetRotation.yaw += 65536;
00343	        }
00344	        while((TargetRotation.pitch - Rotation.pitch) < -32768)
00345	        {                  
00346	            TargetRotation.pitch += 65536;
00347	        }
00348	        while((TargetRotation.roll - Rotation.roll) < -32768)
00349	        {
00350	            TargetRotation.roll += 65536;
00351	        }
00352	        PanChange = (TargetRotation - Rotation) / PanTime;
00353		}
00354	}
00355	
00356	function DoDolly(vector NewLocation, actor NewTarget, float Time)
00357	{		
00358		//Check for instant dolly.
00359		if(Time == 0)
00360		{
00361			SetLocation(NewLocation);
00362			bDollying = false;
00363		}		
00364		else
00365		{
00366			DesiredLocation = NewLocation;
00367			DollyTarget = NewTarget;
00368			bDollying = true;
00369			bCircling = false;
00370			bChaseCam = false;
00371			bInterpolating = false;
00372			DollyTime = Time;
00373			DollyChange = (DesiredLocation - Location) / DollyTime;
00374		}
00375	}
00376	
00377	function DoZoom(float NewFOV, float Time)
00378	{
00379		//Check for instant zoom.
00380		if(Time == 0)
00381		{
00382			CurrentFOV = NewFOV;
00383			setFOV();
00384			bZooming = false;
00385		}		
00386		else
00387		{
00388			bZooming = true;
00389			bVertigo = false;
00390			DesiredFOV = NewFOV;
00391			ZoomTime = Time;
00392			ZoomChange = (DesiredFOV - CurrentFOV) / ZoomTime;
00393			setFOV();
00394		}
00395	}
00396	
00397	function DoVertigo(actor NewTarget)
00398	{
00399		local float DistFromActor, CurrentFOVRad;
00400		
00401		if(NewTarget == NONE)
00402			bVertigo = false;
00403		else
00404		{
00405			bVertigo = true;
00406			bZooming = false;
00407			VertigoTarget = NewTarget;
00408			CurrentFOVRad = CurrentFOV * (pi / 180);
00409			DistFromActor = vsize(Location - NewTarget.Location);
00410			VertigoConst = DistFromActor * tan(CurrentFOVRad/2);
00411		}
00412	}
00413	
00414	function DoCircling(actor NewTarget, rotator Speed, vector Offset, float Distance)
00415	{
00416		//Check for no target.
00417		if(NewTarget == NONE)
00418			bCircling = false;
00419		else
00420		{
00421			bCircling = true;
00422			bDollying = false;
00423			bChaseCam = false;
00424			bInterpolating = false;
00425			CircleTarget = NewTarget;
00426			Radius = -1 * (CircleTarget.Location - Location);
00427			if(Distance != 0)
00428				Radius = (Radius / VSize(Radius)) * Distance;
00429			CirclingSpeed = Speed;
00430			CirclingOffset = Offset;
00431		}
00432	}
00433	
00434	function DoCircleShrink(vector NewRadius, float TimeToChange)
00435	{
00436		if(!bCircling)
00437			bCircleShrinking = false;
00438		else
00439		{
00440			bCircleShrinking = true;
00441			CircleShrinkTime = TimeToChange;
00442			CircleShrinkRadius = vsize(NewRadius);
00443		}
00444	}
00445	
00446	function DoTracking(actor NewTarget, vector Offset, rotator Directions)
00447	{
00448		//Check for no target.
00449		if(NewTarget == NONE)
00450			bTracking = false;
00451		else
00452		{
00453			bTracking = true;
00454			bPanning = false;
00455			bChaseCam = false;
00456			TrackingTarget = NewTarget;
00457			TrackingOffset = Offset;
00458			TrackingDirections = Directions;
00459		}
00460	}
00461	
00462	function DoChaseCam(actor NewTarget, vector Offset, rotator RotOffset)
00463	{
00464		//Check for no target.
00465		if(NewTarget == NONE)
00466			bChaseCam = false;
00467		else
00468		{
00469			bChaseCam = true;
00470			bPanning = false;
00471			bDollying = false;
00472			bCircling = false;
00473			bTracking = false;
00474			bInterpolating = false;
00475			ChaseTarget = NewTarget;
00476			ChaseVecOffRot = rotator(Offset);
00477			ChaseVecOffSize = VSize(Offset);
00478			ChaseRotOffset = RotOffset;
00479		}
00480	}
00481	
00482	function DoInterpolate(actor InterpPoint, float DesiredRate, float DesiredAlpha)
00483	{
00484		//Check for no target
00485		if(InterpPoint == NONE)
00486			bInterpolating = false;
00487		else
00488		{
00489			SetCollision(True,false,false);
00490			bCollideWorld = False ;
00491			Target = InterpPoint;
00492			SetPhysics(PHYS_Interpolating);
00493			PhysRate = DesiredRate;
00494			PhysAlpha = DesiredAlpha;
00495			bInterpolating = true;
00496			bChaseCam = false;
00497			bDollying = false;
00498			bCircling = false;
00499		}
00500	}
00501	
00502	function InterpolateEnd(actor InterpPoint)
00503	{
00504		if(InterpolationPoint(InterpPoint).bEndOfPath)
00505			SetPhysics(PHYS_None) ;
00506	}
00507	
00508	defaultproperties
00509	{
00510	     CurrentFOV=90.000000
00511	     bCanTeleport=True
00512	     bStasis=True
00513	     DrawType=DT_Mesh
00514	     Mesh=LodMesh'UnrealI.BigFlash'
00515	     CollisionRadius=0.000000
00516	     CollisionHeight=0.000000
00517	     Mass=0.000000
00518	}

End Source Code