Overhead camera?

Discuss programming in the QuakeC language.
Post Reply
Mexicouger
Posts: 514
Joined: Sat May 01, 2010 10:12 pm
Contact:

Overhead camera?

Post by Mexicouger »

How would I go about creating a Straight top down camera without the _y angles of the player affecting it?
mankrip
Posts: 924
Joined: Fri Jul 04, 2008 3:02 am

Re: Overhead camera?

Post by mankrip »

Set the .angles of the camera to the direction you want, and then set the .fixangle of the camera to TRUE. However, this only works in PlayerPreThink.

This must be done in every frame, and due to this it does have some impact on networked games. A solution that doesn't impact network performance would be to use CSQC, but that's beyond my current knowledge at the moment.

And another hint: When setting the camera's position, doing that in PlayerPostThink is better than doing it in PlayerPreThink. PlayerPreThink is run before the player's physics, so any position you set within it will be outdated when the player's physics run.

Another interesting detail is that the whole set of PlayerPreThink :arrow: player's physics :arrow: player's .think :arrow: PlayerPostThink functions is run before any other entities. So, even though setting a camera position in PlayerPostThink will make it follow the player's physics correctly, the player's position can still be changed by any other entity that comes after (e.g. the sliding platform over the first acid pool in E1M1: push the button, and run over the platform while it's still moving to see the camera lagging). Only the physics of the very last entity will be guaranteed to be not unpredictably changed by some other entity after it runs.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Overhead camera?

Post by Spike »

csqc can, but otherwise you can't without implementing the y angles serverside - an aproach that disables all mouse looking (you can reorient the player based upon the direction they are moving but this hurts aiming, or you can implement +turnleft etc serverside via impulses but this is lame).
Angles spammed by fixangles will be echoed back to the server in the v_angle field, and csqc is the only way to override that.
A one-function csprogs should be enough, just get some minimalistic csqc code and add in setviewprop(VF_ANGLES, myhardcodedviewangle); just before the renderscene() call. This won't be seen by the server - the angles the server sees are as normal, including mouse looking (yes, even pitch, setviewprop(VF_CL_VIEWANGLES_X, 0); can be used to force a pitch of 0 clientside - ignore the backwards names, the concept kinda got mixed up in DP).

my old gno mod does it somewhat easily without using csqc by locking the m_pitch cvar to 0, and avoiding the use of fixangles, this allows the client to freely change yaw but this will be shown onscreen. The player always faces upwards on the screen, but the camera position is provided via svc_setview, so could be positioned infront of the player to give better use of screen space. Pitch changes in areas with low ceilings are sent as required, but may revert changes to the y angle when they are sent - there's no solution to that other than of course csqc.
Mexicouger
Posts: 514
Joined: Sat May 01, 2010 10:12 pm
Contact:

Re: Overhead camera?

Post by Mexicouger »

So I started coding the top down camera in CSQC, and this is what I have so far:

Code: Select all




void() Update_Player_Always =
{
	local entity ent;

	ent = nextent(world);
	while (ent)
	{
		if (ent.classname == "player")
		{
			CSQC_VIEW = ent.origin + '0 0 150';
			makevectors (ent.v_angle);
			ent.v_angle_x = 90;
			ent.v_angle_z = 0;
			ent.angles_x = 90;
			ent.angles_z = 0;
			input_angles_x = ent.v_angle_x;
			input_angles_y = ent.v_angle_y;
			input_angles_z = ent.v_angle_z;
		}
		ent = nextent(ent);
	}
};

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void(float newent) UpdateCSPlayer=
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
	if (newent)
	{
		self.classname = "player";
		self.drawmask = MASK_NORMAL; // makes the entity visible
	}
};
void CSQC_Ent_Update (float isnew)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{

	self.enttype = ReadByte();
	if(self.enttype == ENT_PLAYER)
	{
		self.origin_x = ReadCoord();
		self.origin_y = ReadCoord();
		self.origin_z = ReadCoord();
		self.velocity_x = ReadShort();
		self.velocity_y = ReadShort();
		self.velocity_z = ReadShort();
		self.v_angle_x = ReadShort();
		self.v_angle_y = ReadShort();
		self.v_angle_z = ReadShort();
		self.angles_x = ReadShort();
		self.angles_y = ReadShort();
		self.angles_z = ReadShort();

		UpdateCSPlayer(isnew);
	}
//CSQC Update view
	Update_Player_Always();
	
	R_ClearScene();

//	R_SetView(VF_DRAWWORLD, 1); // Will do it anyway.
	R_SetView(VF_DRAWCROSSHAIR, 1);
	R_SetView(VF_DRAWENGINESBAR, 0);
	R_SetView(VF_ORIGIN, CSQC_VIEW);
	R_SetView(VF_ANGLES, input_angles);

Now for the questions, how can I make the player model actually show up like I'm in a chase cam, and how can I disable all other angles besides the _y angle? I tried setting the _x and _z to 0 to override the Qc, but it doesn't do anything. So far all that code does, is set the camera looking down from above.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Overhead camera?

Post by Spike »

why are you calling rendering functions within a network function? that's nearly always a bug, and will always result in flickering - the only time it makes any sense is for loading screens, eg precache_model can take some time in some engines.

to get the player visible, you need to get the player entity added to the scene, either via explicitly calling addentity between clearscene and renderscene, or by setting a drawmask and allowing addentities to pick it up (which is the recommended way). This of course also requires that its modelindex and origin are correct.
If you want to interpolate or animate the entity, you can give it a .predraw function, and addentities will automatically call that before actually adding the entity, you can just put your entity update code within this function.
Post Reply