Game Development Community

dev|Pro Game Development Curriculum

Camera Orbitmode Camera/Player Independant Rotate (TGE 1.3)

by Entr0py · 06/26/2004 (9:10 pm) · 13 comments

Changes:
- Player now changes facing when walking left/right in orbit mode, but the player will strafe normally in all other camera modes.
- moving the mouse around rotates the camera around the player in orbit mode.
- Made a new function called setCamView to centralize the various advCamera.setBlahModes which is called with setCamView(%this,'orbit(etc)');

I removed a line from advanced camera.cc (to prevent console spam) but the rest is done in script.

The camera orbits the player rather sluggishly and very choppy. I think it may be that it is constantly sending serverCmds to the server but I am not sure, nevertheless I am probably going to modify the camera networking code next because I don't think the server really needs to know anything about the cam except maybe check every once in a while that it is still on target and has not escaped its limits (cheat detection).

**** Disclaimer ***** I am mainly an artist and not a coder. This is my first little bit of code and I thought I would contribute it. Hopefully somebody can make some use of it. It's pretty sloppy and could no doubt be heavily improved on, so use at your own risk, I havent tested it much, and might have left some bits out of the snippet.

That being said, here it is:

First, I implemented Cory Osborn and Thomas "Man of Ice" Lund's Advanced Camera snippet found here.

I wanted the player to turn as he moved left and right in orbit mode, so in default.bind.cs I added this:

function moveleft(%val)
{
   $mvLeftAction = %val * $movementSpeed;
   if ($OrbitModeSet==true)
      $mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}

function moveright(%val)
{
   $mvRightAction = %val * $movementSpeed;
   if ($OrbitModeSet==true)
      $mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
}

I wanted strafes to be normal in first-person mode so in function toggleFirstPerson I changed this:

function toggleFirstPerson(%val)
{
   if (%val)
   {
      $firstPerson = !$firstPerson;
   }
   
}

to this:

function toggleFirstPerson(%val)
{
   if (%val)
   {
      $firstPerson = !$firstPerson;
   }
   
    if ($pref::Camview =="orbit")
  {
  if ($firstPerson)
     $OrbitModeSet=false;
     else
     $OrbitModeSet=true;
     }
}

and this:

function yaw(%val)
{
   $mvYaw += getMouseAdjustAmount(%val);

}
function pitch(%val)
{
 $mvPitch += getMouseAdjustAmount(%val);
}

to this:

function pitch(%val)
{

$mvPitch += getMouseAdjustAmount(%val);
rotateCameraVertical(%val);

}

function yaw(%val)
{
if ($OrbitModeSet==true)
{
   rotateCameraHorizontal(%val);

  }
  else $mvYaw += getMouseAdjustAmount(%val);
  rotateCameraHorizontal(%val);
}

I wanted a function to handle the changing of the modes so I could refer to it from other parts of the script (such as adding a toggle)so in game.cs (end of function GameConnection::createPlayer) I replaced this:

// We set the camera system to run in 3rd person mode around the %player
  %this.advCamera.setPlayerObject(%player);
  %this.advCamera.setThirdPersonMode();
  %this.advCamera.setFollowTerrainMode(false);
  %this.setCameraObject(%this.advCamera);

with this:

setCamView(%this,'orbit');

Here's the function I created, I had to use a bunch of "if's" because I couldnt get switches to work for some reason. In camera.cs I added this:

function setCamView(%this, %mode, %followterrain)
{

 if (%followterrain)
 %this.advCamera.setFollowTerrainMode(true);
 $OrbitModeSet=false;

// We set the camera system to run in 3rd person mode around the %player
  %this.advCamera.setPlayerObject(%this.player);
//  The offset values in the datablock can be changed for the camera object via script using
//      get/setLookAtOffset();
//      get/setThirdPersonOffset();
//      get/setGodViewOffset();

if (%mode=="track")
      %this.advCamera.setTrackMode();
      
if (%mode=="third")
      %this.advCamera.setThirdPersonMode();
      
if (%mode=="target")
      //  Need a setTargetObject()  here
      // and setCameraPosition(Point3F pos) for stationary camera
      %this.advCamera.setThirdPersonTargetMode();
      
if (%mode=="god")
      %this.advCamera.setGodViewMode();
      
if (%mode=="orbit")
{
      $OrbitModeSet=true;
      %this.advCamera.setOrbitMode();
      
      }
// Set the pref for later reference
$pref::Camview  = %mode;
%this.setCameraObject(%this.advCamera);

}

I didn't need these controls anymore since they are taken care of in moveleft/right and pitch/yaw so in config.cs I commented out these lines like this:

//moveMap.bind(keyboard, "g", AvatarCamRotateClockwise);
//moveMap.bind(keyboard, "j", AvatarCamRotateCounterClockwise);
//moveMap.bind(keyboard, "h", AvatarCamPitchDown);
//moveMap.bind(keyboard, "y", AvatarCamPitchUp);

To speed up the rate at which the camera rotates around the player i changed orbitChangeAngle in datablock AdvancedCameraData from 5 to 10.

I commented out this line (from the sourcecode in advancedcamera.cc) to prevent console spam:

Con::printf("At processPlayerInput: direction is %i", direction);

Well that's it. I hope I didn't leave anything out. Feel free to abuse it, improve it and otherwise exploit it however you wish :)

#1
06/27/2004 (12:45 am)
Very cool! Happy to see that the resource is in use! Congratulations.

I'll remove the spamming Con::printf in my next release.

The jerky camera movement comes from setting the change angle to be 10. To give a smooth movement it should rather be something like 0.5 as the current code doesnt do smooth/fluid changes but brutally sets the new angle to be "current angle + change angle". Stephen Zepp (original author of the orbit mode that he contributed) is AFAIK working on a smooth angle switch mode, that will be included in later releases of Adv Cam.
#2
06/27/2004 (5:16 am)
Ok, I tested this on fresh build of stock TGE HEAD and it works.
#3
06/27/2004 (7:41 am)
As Thomas mentioned, the "jerkiness" of the Orbit Cam is basically an artifact of the change angle being set to a pretty large angle. If you have it set high, your camera will rotate so much around the sphere that what is displayed jumps from position to the next position, but if you set it too low, it requires a lot of user input to get it to budge at all.

I'm working on changing the way the control inputs are processed so that instead of directly controlling the camera's current position by sending an angle change, you'll send a "desired new angle" (can be an increment from current angle of course), and the camera code will smoothly (and hopefully quickly) rotate from the current position to the desired position in very small (<.5 degree per tick) increments, at a relatively high speed.

I hope that this will make things just as smooth during rotation as the "normal" yaw/pitch camera changes are, but still give you the flexibility to have one user input move the camera a decent amount (5 degrees or so).

P.S.: Good catch on the debug printf, sorry I missed that!
#4
06/30/2004 (7:32 am)
ugh found a bug. In function yaw and function pitch "if ($OrbitModeSet=true)" should be "if ($OrbitModeSet==true)"

I have corrected the snippet above to fix the bug.
#5
08/01/2004 (1:16 pm)
I was able to use a switch statement:

in camera.cs

switch$ (%mode)
	{
		case "track":  %this.advCamera.setTrackMode();      
		case "third":	%this.advCamera.setThirdPersonMode();      
		case "target":
		//  Need a setTargetObject()  here      
		// and setCameraPosition(Point3F pos) for stationary camera      
			%this.advCamera.setThirdPersonTargetMode();      
		case "god":	%this.advCamera.setGodViewMode();
		case "orbit":
				$OrbitModeSet=true;      
				%this.advCamera.setOrbitMode();            
					
	}

I had to change the function call to:
setCamView(%this, "orbit");
#6
10/10/2004 (9:41 pm)
Oh switch$(), i was using switch(), no wonder.
#7
07/04/2005 (11:51 am)
Hi,

this a noob question...
but where is this funcitions?
AvatarCamRotateClockwise
AvatarCamRotateCounterClockwise
AvatarCamPitchDown)
AvatarCamPitchUp

thanks
#8
03/20/2006 (8:47 pm)
This resource doesn't work. The Avatar functions don't exist.
#9
03/22/2006 (6:13 am)
Nice Ressouce, i have implement this (with some modifications) to 1.4, thx.

One question: if im in one line with ground, and zoom to player, the camera begin to fly over the player.. so if im staying direchtly over the player, i look from abowe.
How can i zoom really close to the player, without difformation of camera-view?
#10
03/27/2006 (6:28 pm)
Anton:
This resource is old and I am no longer updating it, but you can try these in place of the "avatar" functions (they are from the Advanced Camera resource):

function rotateCameraHorizontal(%val)
{
     $advCamera::Yaw = getMouseAdjustAmount(%val)*$cameraYawSpeed ;
}

function rotateCameraVertical(%val)
{
     $advCamera::Pitch = getMouseAdjustAmount(%val)*$cameraPitchSpeed;
}

function yaw(%val)
{
if ($OrbitModeSet==true)
{
   rotateCameraHorizontal(%val);

  }
  else $mvYaw += getMouseAdjustAmount(%val);
  rotateCameraHorizontal(%val);
}

 function pitch(%val)
{
$mvPitch += getMouseAdjustAmount(%val);
rotateCameraVertical(%val);

}


Stalker: Check some of the other forums here, I don't know, it's been a while since I worked with this.
#11
06/09/2008 (9:38 am)
This has to be the buggiest code I have ever seen. Did you even test it?
#12
06/07/2009 (7:25 pm)
I found this part useful:
$mvYawRightSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;
$mvYawLeftSpeed = %val ? $Pref::Input::KeyboardTurnSpeed : 0;

This at least enables having your strafe do turn rather strafe, such as A and D for if you are in a vehicle vs. FPS.
#13
06/28/2009 (7:33 pm)
Matt: Look at the date it was submitted, it's for a far older version of TGE.