DP_EF_NODEPTHTEST

Discuss programming in the QuakeC language.
Ghost_Fang
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

DP_EF_NODEPTHTEST

Post by Ghost_Fang »

Quick question about DP_EF_NODEPTHTEST, does or can Darkplaces detect whether or not its rendering an entity with this effect through walls or not? Like if its rendering through a wall, could it be known to the engine so I could give the entity a different effect for being shown through walls. Or could this effect be achieved through some other way? The goal is to get all the clients (or frikbots) to always been seen even through walls, much like Left 4 Dead does, but with an outline or a sort of wireframe possibly. Or am I looking more towards some CSQC to get this effect?

EDIT: Hmmm, my mistake, wrong subforum, meant to put this in engine...
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: DP_EF_NODEPTHTEST

Post by Baker »

Ghost_Fang wrote:Quick question about DP_EF_NODEPTHTEST, does or can Darkplaces detect whether or not its rendering an entity with this effect through walls or not? Like if its rendering through a wall, could it be known to the engine so I could give the entity a different effect for being shown through walls. Or could this effect be achieved through some other way? The goal is to get all the clients (or frikbots) to always been seen even through walls, much like Left 4 Dead does, but with an outline or a sort of wireframe possibly. Or am I looking more towards some CSQC to get this effect?

EDIT: Hmmm, my mistake, wrong subforum, meant to put this in engine...
Likely, DP_EF_NODEPTHTEST probably ...

1) tells the server NOT to test the entity for visibility
2) tells the client NOT to test the entity for visibility
3) Draw the entity last with renderer depth testing off (Means draw on top of everything basically)

The intent of this feature was to allow stuff like being able to figure out where home/enemy base for CTF is more easily.

I could comment on whether or not there is a way to know if such an entity was supposed to be visible, you would think there is probably NOT since such a consideration was probably not thought of. Then again, part of this is speculation.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: DP_EF_NODEPTHTEST

Post by Spike »

you need a shader with a weird depthtest flag, so that its only drawn if its obscured, with your normal model drawn if it isn't obscured. But note that you may need to pay attention to drawing order/shader sorting to avoid drawing it behind fleshy objects.

the engine doesn't know if its obscured, and even if it is obscured, it might not be fully obscured. checking if the entire thing is obscured is a little slow, and probably not very useful (unless you want a corona?..).
Arkage
Posts: 66
Joined: Thu Nov 19, 2009 4:17 pm

Re: DP_EF_NODEPTHTEST

Post by Arkage »

What about checking with a traceline? I
If it makes it all the way remove the effect otherwise add the effect. Should be able to do it in CSQC too.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: DP_EF_NODEPTHTEST

Post by Spike »

tracelines won't work correctly for partially obscured entities.
Ghost_Fang
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Re: DP_EF_NODEPTHTEST

Post by Ghost_Fang »

Hmmmm that would work wouldn't it? Like make a traceline check using find(), loop it, and sending a traceline from origin to the other 3 player's origin found using find(). Is that how I would go about doing it? That would even work with SSQC.

Thanks arkage
Ghost_Fang
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Re: DP_EF_NODEPTHTEST

Post by Ghost_Fang »

Spike wrote:tracelines won't work correctly for partially obscured entities.
Yea but it would work for what its worth.
Arkage
Posts: 66
Joined: Thu Nov 19, 2009 4:17 pm

Re: DP_EF_NODEPTHTEST

Post by Arkage »

Ah yea, what about trace-box then?
Ghost_Fang
Posts: 336
Joined: Thu Nov 12, 2009 4:37 am

Re: DP_EF_NODEPTHTEST

Post by Ghost_Fang »

well while doing this, I had a sudden realization that I'd need to do this in CSQC to get it just right, what I did works perfectly in Singleplayer (with frikbots). I just used a simple sprite above the head, much like Halo. With the sprite, the traceline worked perfectly for it, but I ran into problems when there was more than one player client. The one player would update it and/or change it for the other player as well. But this is what I came up with:

Code: Select all

.float icon
.entity header	
void() headerloop =
	{
	
	
	/*local entity fplayer
	
	//fplayer = find(world, classname, "player");
	fplayer = findradius(self.owner.origin, 2000);
	while(fplayer)
	{
		if(fplayer != self)
			{
				if(fplayer.classname == "player")
					{
						traceline(self.owner.origin, fplayer.origin, TRUE, world);
						if (trace_fraction != 1)
							fplayer.icon = TRUE;
						else
							fplayer.icon = FALSE;
							
					}
			}
		fplayer = fplayer.chain;
	}
	if (self.owner.health > 0 && self.icon == FALSE)
		{
		setmodel(self, "progs/invis.spr");		
		self.think = headerloop;
		self.nextthink = time + 0.01;
		}
	*/	 //commented out and just made the icon on all the time
	
	if (self.owner.health > 0)  //&& (self.owner.icon == TRUE)
		{
		setorigin(self, self.owner.origin + '0 0 35');
		self.think = headerloop;
		self.nextthink = time + 0.01;
		setmodel(self, "progs/p_ind.spr");
		}
	else
		{
		setmodel(self, "progs/ind_die.spr");		
		self.think = SUB_Remove();
		self.nextthink = time + 3;
		}
	
	};

void() spawn_head_sprite =
	{
		if(deathmatch)
			return;
	
	self.header = spawn();
	self.header.owner = self;
	
	setorigin(self.header, self.header.owner.origin + '0 0 35');
	self.header.movetype = MOVETYPE_NONE;
	self.header.solid = SOLID_NOT;
	self.header.effects = self.header.effects | EF_NODEPTHTEST;
	self.header.nodrawtoclient = self;
	self.header.think = headerloop;
	self.header.nextthink = time + 0.05;
	
	};
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: DP_EF_NODEPTHTEST

Post by Spike »

customizeentityforclient is your friend...

Code: Select all

float() somecustomizefunction =
{
    traceline(other.origin + other.view_ofs, self.owner.origin, TRUE, other);
    if (trace_fraction == 1 || trace_entity == self.owner)
        return FALSE; /*trace hit our owner, so tell the server to not send us to this player*/

    /*the trace hit something first, we are obscured, so we should make ourselves explicitly visible*/
    setorigin(self, self.owner.origin + '0 0 48'); /*might as well update the entity in here*/
    return TRUE; /*allow the server to send this entity to the client*/
};

.float() customizeentityforclient; /*including this in case you don't have a suitable header*/

void() spawn_head_sprite =
{
    local entity foo;
    foo = spawn();
    setmodel(foo, "progs/p_ind.spr");
    foo.owner = self;
    foo.customizeentityforclient = somecustomizefunction;
    foo.effects = EF_NODEPTHTEST;
};
will give you an indicator above some victim's head that is only visible when that victim is obscured, that should also work fine in coop/deathmatch/whatever.
Uses EF_NODEPTHTEST and DP_SV_CUSTOMIZEENTITYFORCLIENT extensions.
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: DP_EF_NODEPTHTEST

Post by r00k »

Spike wrote:tracelines won't work correctly for partially obscured entities.
Via QuakeC or engine side?
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: DP_EF_NODEPTHTEST

Post by mh »

Traces are also incredibly expensive operations - you certainly don't want to be doing too many of them. (You have a problem, you say "I know, I'll use traceline", now you have two problems.)
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: DP_EF_NODEPTHTEST

Post by mh »

r00k wrote:
Spike wrote:tracelines won't work correctly for partially obscured entities.
Via QuakeC or engine side?
It's ultimately the same code either way.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: DP_EF_NODEPTHTEST

Post by Baker »

mh wrote:Traces are also incredibly expensive operations - you certainly don't want to be doing too many of them. (You have a problem, you say "I know, I'll use traceline", now you have two problems.)
Should they be though?

Isn't that a design inefficiency? I'm not saying I have the answer, I'm not quite knowledgeable yet to mess with the BSP collision code. But I've started to play around with collision concepts, mostly involving the more simple radius-based.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: DP_EF_NODEPTHTEST

Post by Spike »

BSP code is fairly straight forward really, the complications come from precision.
See the pointcontents code for a primer - it just goes down through the tree until it finds the leaf.
Well, traces are basically the same, except they have two points.
Go down the tree, favouring the start side every time, so that you can early out properly. When you've got a node between the points, it has to go down both. If its solid on the other side of the node (quake actually uses a pointcontentsalike for that) then you have an impact, figure out the fraction and return up the tree to the caller.
There's quite a few things that make this costly.
1: Its a tree, which has hopefully been balanced somewhat to try to limit the maximum cost. On huge maps, this can still get quite high.
2: the balancing probably left node positions with somewhat random ordering so each node will give you a new cache miss... or more... cache misses are slow, and they get slower (proportionally) the faster the cpu is.
3: Trees suffer from the same inefficincy as lists, that is ptr = ptr->next; foo = ptr->field; contains a memory fetch in the first statement with the second directly depending upon its result. The cpu has to wait on the result of the first before it can evaluate the second. When iterating a list, the index is already in a register, thus idx = idx + 1; has no memory fetch, thus the second instruction no longer needs to wait for as long. X86 CPUs can generally reorder instructions with some small tolerances, but its not magic.
4: quake uses pointcontents to determine solidity on the other side of the node! this means that for every node, its walking down its immediate children twice... 5 nodes means that its walking down to the same leaf 32 times! A couple of engines have a fix for this, but the precision aspect makes it clumsy. Really though this issue isn't quite as bad as it sounds - those nodes will at least be cached. :)
A couple of engines have a fix for this, but its still fairly expensive.
5: It uses floating point. Floating point operations are more expensive than integer operations. An x86 has multiple floating point units nowadays and can crunch multiple numbers simultaneously to reduce the effective cost down to only a couple of cycles, assuming the compiler can interleave enough integer operations in there to give the float operations time to finish. An ARM chip often doesn't actually have an FPU and thus quite a lot of programs for arm are built to emulate floats with ints... which is rather slow (but faster than compiling for an FPU and having the operating system emulate it whenever it detects an illegal instruction...).

anyway, tracelines are slow. 1000 a frame and you'll notice, and have people shouting at you, even with a fixed/optimised traceline.
[ontopic]
tracelines are slow, you can add some timer and recalculate it only every halfsecond or so, but that gets awkward in tracking *which* player can see each marker, which requires at least two .floats for quakeworld (only one for NQ's traditional max of 16 players, which kinda highlights the awkwardness of tracking players with a bitmask).
[/ontopic]
Post Reply