detecting screen position of an entity

Discuss CSQC related programming.
Post Reply
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

detecting screen position of an entity

Post by Nahuel »

Is there a way to detect the relative coordinates of the screen of an entity of the world (items, monsters, etc...) when this is visible?
I wanna to put a csqc image or string, above the relative position of the entity in the screen, only if this is visible :)
without ssqc i could use a sprite only visible to my client, but i do not want to fight with scale.


Any ideas?

Thanks for your help!
hi, I am nahuel, I love quake and qc.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: detecting screen position of an entity

Post by Spike »

string thetext = "hello world";
vector charsize = '8 8';
vector screenpos = project(theent.origin);
if (screenpos_z >= 0)
{
screenpos_x -= stringwidth(thetext, TRUE, charsize) * 0.5; //align horizontally to centre
screenpos_y -= charsize_y * 0.5; //align vertically again
screenpos_z = 0; //shut up dp.
drawstring(screenpos, thetext, charsize, '1 1 1', 1, 0);
}


(make sure you already set VF_ORIGIN+VF_ANGLES+VF_AFOV+VF_MIN+VF_SIZE etc, otherwise project won't have the correct model matrix+projection matrix+viewport and will give incorrect results, normally they should still be set from the last renderscene call).
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: detecting screen position of an entity

Post by Nahuel »

cool :)
sorry for this noob question.
What is the easy way to share the origin of the ssqc entities with csqc?
hi, I am nahuel, I love quake and qc.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: detecting screen position of an entity

Post by toneddu2000 »

Nahuel wrote:What is the easy way to share the origin of the ssqc entities with csqc?
CSQC_Ent_Update, I guess. At least it's the function I use to sync entities fields (origin,velocity, angles, health, blah) with CSQC. In ssqc use a theentity.SendEntity = MySendFunction; and, in csqc CSQC_Ent_Update retrieve those datas. I use FTE but it should be the same in DP. Interestingly, you can "filter" sending fields(to save bandwith)accordingly to setting a flag. For example

Code: Select all

ssqc
float SendSomeFlags(entity playerent,float changedflags)
{
	msg_entity = playerent;
	WriteByte(MSG_ENTITY, ENT_MYENTITY);	
	WriteByte(MSG_ENTITY, changedflags);ì
	if (changedflags & 8){
		WriteCoord(MSG_ENTITY,self.origin_x);
		WriteCoord(MSG_ENTITY,self.origin_y);
		WriteCoord(MSG_ENTITY,self.origin_z);
	}
	if (changedflags & 12){
		WriteByte(MSG_ENTITY,self.weapon);
	}
	return TRUE;
}

void EntitySpawnFunction()
{
stupientity = spawn();
stupientity.SendEntity = SendSomeFlags;
}
then, still in ssqc, you can "filter" send fields by flag

Code: Select all

void MyMoveFunction(entity ent)
{
ent.origin_x += 10;
ent.SendFlags |= 8;//send only origin vectors to csqc
}

void MyWeaponChooseFunction(entity ent)
{
ent.weapon = 4;//machinegun ooooyeah
ent.SendFlags |= 12;//send only weapon num
}
Same thing in CSQC, you can filter which flag you'll read

Code: Select all

void CSQC_Ent_Update (float isnew)
{
	local float i = readbyte();
	local float flags;
	if (i == ENT_MYENTITY){
		flags=readbyte();
		if(flags & 8){
			//movements
			self.origin_x = readcoord();
			self.origin_y = readcoord();
			self.origin_z = readcoord();	
		}
		if(flags & 12){
			self.csWeapon = readbyte();
		}
	}
}
Instead, if you want a "just one time" connection with CSQC, you can send in ssqc an event and then parse it in csqc .
ssqc
void SendTempOrigin()
{
msg_entity = self;
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
WriteByte(MSG_MULTICAST, PE_ORIGIN);
WriteCoord(MSG_ENTITY,self.origin_x);
WriteCoord(MSG_ENTITY,self.origin_y);
WriteCoord(MSG_ENTITY,self.origin_z);
multicast(self.origin, MULTICAST_ALL);//every player will know about me
}
csqc

Code: Select all

noref void() CSQC_Parse_Event =
{
	local float rb = readbyte();
   if(rb == PE_ORIGIN ){
		local float pvector;
		pvector= [readcoord(),readcoord(),readcoord()];
   mycsqcentity.origin = pvector;
	}
}
PE_ORIGIN is a constant which both ssqc and csqc must know. This is useful for a rocket exploding or something else. Not sure if it works in DP, sorry

My next utopian dream is to create all entities in CSQC and in SSQC create a "master server" which reads only entitites coordinates (player,bullets,explosions, etc.) every X milliseconds and re-send it to all players. That's it.
Everything is made in pure CSQC. No more ssqc+csqc crap every sec. Why? Because THIS is utopian
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: detecting screen position of an entity

Post by Nahuel »

toneddu2000!!
thanks for the clues/explanation :)
hi, I am nahuel, I love quake and qc.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: detecting screen position of an entity

Post by toneddu2000 »

No prob, man! :)
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

Re: detecting screen position of an entity

Post by Nahuel »

Spike wrote:string thetext = "hello world";
vector charsize = '8 8';
vector screenpos = project(theent.origin);
if (screenpos_z >= 0)
{
screenpos_x -= stringwidth(thetext, TRUE, charsize) * 0.5; //align horizontally to centre
screenpos_y -= charsize_y * 0.5; //align vertically again
screenpos_z = 0; //shut up dp.
drawstring(screenpos, thetext, charsize, '1 1 1', 1, 0);
}


(make sure you already set VF_ORIGIN+VF_ANGLES+VF_AFOV+VF_MIN+VF_SIZE etc, otherwise project won't have the correct model matrix+projection matrix+viewport and will give incorrect results, normally they should still be set from the last renderscene call).

Spike, i did use this method and it works great, but i did try to use it with R_BeginPolygon stuff and it doesnt work properly.
I use R_BeginPolygon in 2d stuff successfully, rotating images and cutting (for life bars), even with zooms. so i know the way to use r_beginPolygon stuff (and it is great)
Itś possible to use R_BeginPolygon stuff to draw a fake polygon in world? I mean, i did try to do it but it works very strange, is there a limitation or r incompatibility with "project" function and R_BeginPolygon?

any clue about it??

thanks
hi, I am nahuel, I love quake and qc.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: detecting screen position of an entity

Post by Spike »

be sure to add your 3d polys between your clearscene and renderscene calls.
remember that their verticies will take world-space coords.


there may be some confusion due to older versions of DP having a nasty habit of assuming stuff about whether the polygon is meant to be 2d or 3d. In FTE this was meant to be flags&4 to mean '2d - draw immediately' instead of adding it to the scene. Due to DP's weirdness however, you should use an extra 3rd argument to beginpolygon (FTE will understand this also, if that argument is specified).

Trying to draw '3d' polygons using projected 2d coords will result in affine texture sampling (read: weird depth-related distortions on your textures which might not be noticable if all the verts are the same distance from the camera). So don't do that unless you really have to.

otherwise you're going to hav to clarify what you mean by 'doesnt work properly'.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: detecting screen position of an entity

Post by toneddu2000 »

Try this. Of course replace shd with your shader file

Code: Select all

void Render_TestCube2()
{		
	local string shd = "textures/test/checker";
	local float side = 8192;
	
	// front
	R_BeginPolygon(shd);
		R_PolygonVertex([-side,side,side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([side,side,side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([side,side,-side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([-side,side,-side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
	// top
	R_BeginPolygon(shd);
		R_PolygonVertex([side,-side,side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([side,side,side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([-side,side,side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([-side,-side,side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
	// right
	R_BeginPolygon(shd);
		R_PolygonVertex([side,side,-side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([side,side,side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([side,-side,side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([side,-side,-side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
	// left
	R_BeginPolygon(shd);
		R_PolygonVertex([-side,-side,side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([-side,side,side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([-side,side,-side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([-side,-side,-side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
	// bottom
	R_BeginPolygon(shd);
		R_PolygonVertex([side,-side,side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([-side,-side,side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([-side,-side,-side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([side,-side,-side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
	// back
	R_BeginPolygon(shd);
		R_PolygonVertex([side,side,-side],[0,1,0],[1,1,1],1);
		R_PolygonVertex([side,-side,-side],[1,1,0],[1,1,1],1);
		R_PolygonVertex([-side,-side,-side],[1,0,0],[1,1,1],1);
		R_PolygonVertex([-side,side,-side],[0,0,0],[1,1,1],1);
	R_EndPolygon();
}
In the first argument of each R_PolygonVertex you could *probably* add +org, where org stand for project() origin achieved earlier
Hope it helps

cheers
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Post Reply