Game Development Community

Call for Advanced Camera new features/changes/fixes

by Thomas \"Man of Ice\" Lund · in Torque Game Engine · 01/16/2005 (3:55 am) · 65 replies

I'm going to give the advanced camera resource another update soon, and from what I hear a lot of people are using it (nice)

Thus I would like to call out to you all and ask you to dig into your modifications and new features + consider if you would like to contribute those to the general public.

Anything goes, so feel free to send anything you have. I'll update the resource and give proper credit naturally.

From my own hand I'm considering working on:
* general code cleanup - removing unused code
* API cleanup and renaming - e.g. changing the setTargetObject to setLookAtObject and other API changes that make it more intuitive to use. This will most likely break your code unless I put in some deprecation warnings in the old methods and keep them there
* make it possible to use GameBase objects instead of ShapeBase objects as "Look At" and "Tracking" objects - for vehicles, projectiles and similar
* client side orbit camera instead of current server side

Hope to recieve a lot of great additions :-)

If you have general ideas, those are also welcome

My email is in my profile
Page «Previous 1 2 3 4 Last »
#1
01/16/2005 (4:12 am)
It's probably already contained in "* client side orbit camera instead of current server side" but a smoother orbit camera would be nice (interpolation) ;o)

the third person mode makes many clipping failures.. perhaps it should make use of the regular third person camera?
(orbit cam, either: go into a house if the camera position is higher than the roof.. but that doesn't bother me, cause i switch to another cam view on entering a building ;) )
#2
01/16/2005 (3:45 pm)
@Thomas - An update would be awesome as i'm just gearing up to use it. The only thing i'd like to see added is smooth transitions between camera modes and addition of a first person mode.
#3
01/16/2005 (11:49 pm)
I'm using the advanced camera and love it. I'd love to see an enhancement to the third person mode which improved situations where the camera is pushed into a wall. Currently it works well in some cases but partially interpenetrates in others.

Thanks for all your work on this Thomas!

Edit: Fixed this one myself - see fix below
#4
01/20/2005 (11:17 am)
I'm using the advanced camera and it works great. One addition I'd like is orbit camera being controlled by mouse and character independent movement(like this resource but with smooth movement. I understand Stephen Zepp planned working on it but I don't know if he did.
#5
01/20/2005 (11:36 am)
@Pablo: A rewrite for the orbit cam is planned, but almost guaranteed to not be in time for Thomas' upgrades unfortunately (it's a couple of milestones down the road for our project).

However, I would love to hear a bit more info on your mod request--I'm not quite sure I understand what you mean. I think you basically mean a client side only mode of the camera, but I'm hesitant to allow this in my own project due to hacking concerns (if it's all done client side only, it can easily be modified to allow players to move the camera anywhere they want).

I definitely agree the networking side either needs to be tweaked via timing constants, or re-written entirely. My current plan is to use the networking style the main FPS/RTS cameras use, instead of the commandToServer concept.
#6
01/20/2005 (12:18 pm)
Am creating a single player game so cheating isn't an issue for me. I want a classic 3d platformer camera where the character is seen from a 3rd person perspective and the camera isn't always behind him, he can walk in any direction and the camera follows him, when you move the mouse the camera turns around the player, an exelent reference for this is ratchet and clank or tak.
Thanks
#7
01/20/2005 (2:32 pm)
I got it to be mouse controlled with a nice smoothing months ago, weeks after licensing the Torque SDK. Probably not the best way to do it, but I'll post the changes, someone might find them useful (if something goes wrong, warn me, since I might have missed posting a modification or two).

(Pardon my horrid C++ skills, working with Torque was also the first time I worked with C/C++)

In advancedCamera.h, find this:

void setOrbitChangeZoom(F32 zoom);

And add this after it:
void addYaw(F32 yawAdjust);
   void addPitch(F32 pitchAdjust);
   void addZoom(F32 zoomAdjust);

   void setYaw(F32 yaw);
   void setPitch(F32 pitch);
   void setZoom(F32 zoom);

   void updateMovementValues(F32 dt);


In advancedCamera.cc, in AdvancedCamera::advanceTime, find this:
Parent::advanceTime(dt);

And add:
updateMovementValues(dt);

In AdvancedCamera::writePacketData find:
mathWrite(*bstream, mCurrentOrbitMinMaxDeclination);

And add this:
bstream->write(mYawAdjust);
   bstream->write(mPitchAdjust);
   bstream->write(mZoomAdjust);

   mYawAdjust   = 0.0f;
   mPitchAdjust = 0.0f;
   mZoomAdjust  = 0.0f;

In AdvancedCamera::readPacketData find:
mathRead(*bstream, &mCurrentOrbitMinMaxDeclination);

And add:
bstream->read(&mYawAdjust);
   bstream->read(&mPitchAdjust);
   bstream->read(&mZoomAdjust);

   mYaw   += mYawAdjust;
   mPitch += mPitchAdjust;
   mZoom  += mZoomAdjust;

(continues in next post...)
#8
01/20/2005 (2:33 pm)
(part 2)

After the AdvancedCamera::setCameraMode function, add this function:
void AdvancedCamera::updateMovementValues(F32 dt)
{
	
	//Determinate the directions being rotated
	F32 mCamRotateLeft  = getMin(mYaw, 0.0f);
	F32 mCamRotateRight = getMax(mYaw, 0.0f);
	F32 mCamRotateUp    = getMin(mPitch, 0.0f);
	F32 mCamRotateDown  = getMax(mPitch, 0.0f);
	F32 mCamZoomIn      = getMin(mZoom, 0.0f);
	F32 mCamZoomOut     = getMax(mZoom, 0.0f);
	
	if (mCamRotateUp) // top
	{
		F32 newDeclinationAngle;
		// we want to process in degrees during testing for understandability
		// since we use declination, moving the camera "up" is a decrease in angle
		// convert to degrees for now, then apply Change
		newDeclinationAngle = ( mDeclination * 180 / M_PI_F ) + mPitch;
		if (newDeclinationAngle >= mCurrentOrbitMinMaxDeclination.x )	
		{
			mDeclination = newDeclinationAngle * M_PI_F / 180; // converted to radians
		}
		else
		{
			mDeclination = mCurrentOrbitMinMaxDeclination.x * M_PI_F/180;  //set to our MinDeclination define
		}
	}
	if (mCamRotateDown) // bottom
	{
		F32 newDeclinationAngle;
		// we want to process in degrees during testing for understandability
		// since we use declination, moving the camera "down" is an increase in angle
		// convert to degrees for now, then apply Change
		newDeclinationAngle = ( mDeclination * 180 / M_PI_F ) + mPitch;
		if ( newDeclinationAngle <= mCurrentOrbitMinMaxDeclination.y )	
		{
			mDeclination = newDeclinationAngle * M_PI_F / 180; // converted to radians
		}
		else
		{
			mDeclination = mCurrentOrbitMinMaxDeclination.y * M_PI_F/180;  //set to our MinDeclination define
		}			
	}
	if (mCamRotateRight) // right
	{
		F32 newAzimuthAngle;
		// we want to process in degrees during testing for understandability
		// since we use azimuth, moving the camera "right" is an increase in azimuth
		// convert to degrees for now, then apply change
		newAzimuthAngle = (mAzimuth * 180/ M_PI_F) + mYaw;
		if ( newAzimuthAngle < 360 )	// wrap using 360 clock math if needed
		{
			mAzimuth = newAzimuthAngle * M_2PI_F / 360; // converted to radians
		}
		else  // wrap
		{
			mAzimuth = ( newAzimuthAngle - 360 ) *M_2PI_F/360;
		}
	}
	if (mCamRotateLeft) // left
	{
		F32 newAzimuthAngle;
		// we want to process in degrees during testing for understandability
		// since we use azimuth, moving the camera "left" is a decrease in azimuth
		// convert to degrees for now, then apply change
		newAzimuthAngle = (mAzimuth * 180/ M_PI_F) + mYaw;
		if ( newAzimuthAngle > 0 )	// wrap using 360 clock math if needed
		{
			mAzimuth = newAzimuthAngle * M_2PI_F / 360; // converted to radians
		}
		else  // wrap
		{
			mAzimuth = ( newAzimuthAngle + 360 ) *M_2PI_F/360;
		}
	}
	if (mCamZoomIn) // zoom in
	{
		F32 newZoom = mZoomDistance;
		newZoom += mZoom;
		if ( newZoom <= mCurrentOrbitMinMaxZoom.x )
		{
			mZoomDistance = mCurrentOrbitMinMaxZoom.x;
		}
		else
		{
			mZoomDistance = newZoom;
		}	  	
	}
	if (mCamZoomOut) // zoom out
	{
		F32 newZoom = mZoomDistance;
		newZoom += mZoom;
		if ( newZoom >= mCurrentOrbitMinMaxZoom.y )
		{
			mZoomDistance = mCurrentOrbitMinMaxZoom.y;
		}
		else
		{
			mZoomDistance = newZoom;
		}	  	
	}
	
	//Calculate the time-based damping
	F32 subDamp;
	subDamp = mPow(mDamping, dt*10.0f);
	
	//Apply damping
	mYaw   *= subDamp;
	mPitch *= subDamp;
	mZoom  *= subDamp;
   
}
(it's a modified version of the processPlayerInput function)

After the AdvancedCamera::setOrbitChangeZoom function, add these:
void AdvancedCamera::addYaw(F32 yawAdjust) {
	mYawAdjust = yawAdjust;
}
void AdvancedCamera::addPitch(F32 pitchAdjust) {
	mPitchAdjust = pitchAdjust;
}
void AdvancedCamera::addZoom(F32 zoomAdjust) {
	mZoomAdjust = zoomAdjust;
}

void AdvancedCamera::setYaw(F32 yaw) {
	mYaw = yaw;
}
void AdvancedCamera::setPitch(F32 pitch) {
	mPitch = pitch;
}
void AdvancedCamera::setZoom(F32 zoom) {
	mZoom = zoom;
}

(continues in next post...)
#9
01/20/2005 (2:33 pm)
(part 3)

Now add these console methods wherever you like:
ConsoleMethod( AdvancedCamera, addYaw, void, 3, 3, "(F32 yawAdjust)"
              "Increment the yaw speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 yawAdjust;
   dSscanf( argv[2], "%f", &yawAdjust );
   camObj->addYaw(yawAdjust);
}
ConsoleMethod( AdvancedCamera, addPitch, void, 3, 3, "(F32 pitchAdjust)"
              "Increment the pitch speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 pitchAdjust;
   dSscanf( argv[2], "%f", &pitchAdjust );
   camObj->addPitch(pitchAdjust);
}
ConsoleMethod( AdvancedCamera, addZoom, void, 3, 3, "(F32 zoomAdjust)"
              "Increment the zoom speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 zoomAdjust;
   dSscanf( argv[2], "%f", &zoomAdjust );
   camObj->addZoom(zoomAdjust);
}

ConsoleMethod( AdvancedCamera, setYaw, void, 3, 3, "(F32 yaw)"
              "Set the yaw speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 yaw;
   dSscanf( argv[2], "%f", &yaw );
   camObj->setYaw(yaw);
}
ConsoleMethod( AdvancedCamera, setPitch, void, 3, 3, "(F32 pitch)"
              "Set the pitch speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 pitch;
   dSscanf( argv[2], "%f", &pitch );
   camObj->setPitch(pitch);
}
ConsoleMethod( AdvancedCamera, setZoom, void, 3, 3, "(F32 zoom)"
              "Set the zoom speed for orbit mode.\n\n") {
   AdvancedCamera *camObj = (AdvancedCamera *) object;

   F32 zoom;
   dSscanf( argv[2], "%f", &zoom );
   camObj->setZoom(zoom);
}


Now you a bunch of nice console methods to rotate the advanced camera. Add these to your default.binds.cs and you'll be able to rotate the camera smoothly with the mouse:
//------------------------------------------------------------------------------
// Advanced Camera Movement
//------------------------------------------------------------------------------

function rotateCameraHorizontal(%val)
{
     localClientConnection.advCamera.addYaw(getMouseAdjustAmount(%val)*(-10.0));
}

function rotateCameraVertical(%val)
{
     localClientConnection.advCamera.addPitch(getMouseAdjustAmount(%val)*(-5.0));
}

moveMap.bind( mouse, xaxis, rotateCameraHorizontal);
moveMap.bind( mouse, yaxis, rotateCameraVertical );
#10
01/20/2005 (2:38 pm)
Wow, I'll try this tonight, thanks a lot Manoel
#11
01/20/2005 (3:07 pm)
I added interpolation to the advanced camera so it lags behind the follow object and isn't always at a static offset. I also improved on this by making the camera stop when the player is within 10 units so it's not always behind the player(can be turned on/off via script). Very good for 3rd person RGPs, currently the stop distance is hard-coded, but I could easily add it to the camera datablock.

Does anyone want me to post my code(the interpolation stuff is floating around here somewhere....)?
#12
01/20/2005 (3:16 pm)
Sure Josh - or ship it to me in an email and I'll sort it out

@Manuel - cool! I'll try to disect it and see what I can put into the resource

Thanks all
#13
01/20/2005 (8:04 pm)
I tried to implement your codemanoel but I have no AdvancedCamera::advanceTime method, maybe you did this on a previous version, I guess only thomas can tell.
#14
01/20/2005 (9:08 pm)
I've heard that your camera resource has problems over a network game. I haven't gotten around to implementing your resource(but I plan to for a later project), to see exactley how it reacts, but incase it wasn't fixed or does have issues it would definitely be a plus to get that stuff ironed out.

All thats left that I can say is good luck, I look forward to seeing how it turns out.

-Jase
#15
01/20/2005 (9:54 pm)
And the mDamping variable also!
#16
01/20/2005 (10:32 pm)
@Jase - only the orbit camera has an issue over network. The other modes are not a problem (afaik). Would be a first time for me to hear that
#17
01/21/2005 (3:55 am)
@Thomas

I'd like to see an improvement on the tracking side of things. The way the Movie Like Camera System is implemented is fantastic - creating mission regions for different tracking cameras. It would be really useful if the mission regions themselves had a few extra features, mostly to refine the positions a lot more:

- starting height for region (position XYZ)
- end height for region (extent XYZ)
- Z Rotation for mission region (allow to better fit regions in non-square areas)
- separate XYZ position for camera sphere (as opposed to just a height setting so it doesn't have to be in the centre)

The reason for these would be so that you could sue them inside a multi-storey building where you have rooms above each other, and you don't necessarily want the camera in the centre of the room.

Thanks for the great work on this!
#18
01/21/2005 (3:49 pm)
@Thomas

Is AdvancedCamera::interpolateTick the substitute of AdvancedCamera::advanceTime?

Thanks
#19
01/21/2005 (4:36 pm)
Tossing out a general idea, wouldn't know how to code this, but...

Would it be possible to set a primary and a secondary setLookAtObject?
With both objects in motion?
And the camera constantly adjusts accordingly.
#20
01/21/2005 (5:08 pm)
@Sam

I believe that there's already a track mode that sets the camera to see two objects
Page «Previous 1 2 3 4 Last »