Calculating WaterDepth

Discuss programming in the QuakeC language.
Post Reply
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Calculating WaterDepth

Post by Cobalt »

Trying to create some code to supply the actual number of Quake units reflecting actual Waterdepth an ent is in. This almost is working, except if we are under a bridge and our waterlevel is 3, its lowering the value. Anyone have an idea whats wrong?

// Called when waterlevel = 3 for a player

Code: Select all

float (vector xyz) WaterDepth =
{
local vector zyx;
local float zz;
zyx = xyz;
if (self.ishuman) // offset to add player models height to the final result , zero for non client ents
zz = 56;
zyx_z = self.absmax_z;
makevectors (self.v_angle);
normalize (v_forward);
traceline (zyx, (zyx + '0 0 +1000' + v_forward), TRUE, self);

if (!trace_inwater)
{
bprint ("waterdepth : ");
bprint (ftos (floor(zz + (trace_fraction) * 112)));
PrintNL();
	return (floor(zz + trace_fraction * 112));
	
	}
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Calculating WaterDepth

Post by Spike »

what are you actually trying to do? work out how much water there is above the player?
that's not going to work with traceline. traceline can only detect solids, it can't find water.
trace_inwater / trace_inopen merely state that *part* of the trace was inside water/empty. if they're both set then you know that it crosses a water surface, but you don't know where. probably you'll have to bisect it until you find where the surface is.

basically trace up from 0 to 1000 units. if it crosses into air, try 0 to 500, if it doesn't, try 500 to 750, etc, until the range is small enough that you don't care too much.
or you can spam some pointcontents calls.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: Calculating WaterDepth

Post by Cobalt »

Hrm, I thought the trace_fraction would reflect how much of the trace took place before it encountered the non water content.

There is also : trace_plane_dist , but it does not seem to be well documented in any QC stuff I can find.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Calculating WaterDepth

Post by Spike »

like I said. traceline is never blocked by 'nothing', thus the trace will happily leave the water and give you nice fractions and stuff. it can never impact on the inside of the water surface.

trace_plane_dist describes the wall that got hit. its not really very useful, so noone uses it. go research standard plane equations, and then negate the distance, and you'll have a better understanding of this result value.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: Calculating WaterDepth

Post by Cobalt »

Thanks Spike.

For the time being, I figured another way. Using DP_SV_ENTITYCONTENTSTRANSITION, I will mark that origin_z where the transition takes place as the surface of the water and merely subtract from it to get the waterfdepth.

For the most part it ought to work, save for a map like E1M4, where you can re-surface at lower depths than previously marked....but thats a problem for another day.
Spike wrote:like I said. traceline is never blocked by 'nothing', thus the trace will happily leave the water and give you nice fractions and stuff. it can never impact on the inside of the water surface.

trace_plane_dist describes the wall that got hit. its not really very useful, so noone uses it. go research standard plane equations, and then negate the distance, and you'll have a better understanding of this result value.
Seven
Posts: 301
Joined: Sat Oct 06, 2007 8:49 pm
Location: Germany

Re: Calculating WaterDepth

Post by Seven »

Hello Cobalt,

If I understood you correctly, you want to write qc for detecting a water surface, and then start a calculation to compare the players origin with it ?
Qrv did the 1st part here for you:
http://forums.inside3d.com/viewtopic.php?f=2&t=4397

I also use this and it works great.
The only thing is, that you should not do it every frame as it will become a bit performance hungry then.
You can adjust its accuracy and thereby influence directly the performance impact.

For Darkplaces (or other supporting engines), DP_SV_ENTITYCONTENTSTRANSITION might be better though.

Best regards.
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: Calculating WaterDepth

Post by Cobalt »

Hi Seven

Yes, I believe I found that same code in your mod as its used to traceline with the shotguns to spawn a bullet splash. Its similar to what I was looking to do, but for the ost part I was looking to get a starting value for the surface z_ origin on maps that have liquid so in case an entity winds up in the liquid, we can apply that into how the entity will behave in regard to movement physics, such as avelocity and such. Its really experimental tests, but today I was also thinking that could be used as a way to maybe reduce the sound volume on the client / players side sound levels as a cheap hack for an underwater sound only mod, but there is probably more to it, and best done engine side anyway.

On maps like e1m4, where you have pockets and more than one surface level, it also creates some more complex problems that most likely require seperate QC for the specific map....


Seven wrote:Hello Cobalt,

If I understood you correctly, you want to write qc for detecting a water surface, and then start a calculation to compare the players origin with it ?
Qrv did the 1st part here for you:
http://forums.inside3d.com/viewtopic.php?f=2&t=4397

I also use this and it works great.
The only thing is, that you should not do it every frame as it will become a bit performance hungry then.
You can adjust its accuracy and thereby influence directly the performance impact.

For Darkplaces (or other supporting engines), DP_SV_ENTITYCONTENTSTRANSITION might be better though.

Best regards.
PrimalLove
Posts: 14
Joined: Sun Oct 19, 2014 2:37 am

Re: Calculating WaterDepth

Post by PrimalLove »

Code: Select all

.float water_depth;
.float water_check_time;
.float water_in;

// Keeps Entity Just Below Water Surface 
void() water_depth_think =
{
	
	local vector spot1, spot2;
	local string depth;
	spot1 = self.origin;
	spot2 = self.owner.origin + self.owner.view_ofs;
	
	if (self.owner.waterlevel <= 2)
        {
        self.owner.water_in = 0;
	remove(self);
        }
	
        // Just here for testing. Prints the current vector length in a rounded integer
	if (self.water_check_time < time)
	{
	self.water_check_time = time + 1.5;
	self.owner.water_depth = vlen (spot1 - spot2);
	depth = ftos(rint(self.owner.water_depth));
	bprint (depth);
	bprint ("\n");
	}
	self.velocity = self.owner.velocity;
	self.avelocity = self.owner.avelocity;
       // Kind of a hack   :roll:  
	if (pointcontents(self.origin) != CONTENT_WATER)
	self.velocity_z = -50;
	else if (self.waterlevel > 1)
	self.velocity_z = 50;
	else
	{
	self.velocity_z = 0;
	self.avelocity_z = 0;
	}
	self.nextthink = time + .01;
};	

// Made visible here for testing	
void() water_depth_entity =
{
	local entity wmeter;
	wmeter = spawn();
	setmodel(wmeter, "progs/s_bubble.spr");
	wmeter.origin = self.origin + self.view_ofs;
	wmeter.colormod = '0 0 10';
	wmeter.classname = "wmeter";
	wmeter.solid = SOLID_NOT;
	wmeter.movetype = MOVETYPE_NOCLIP;
	wmeter.owner = self;
	wmeter.think = water_depth_think;
	wmeter.nextthink = time;
	self.water_in = 1;
};	


// Place in PlayerPreThink Or Similar

	if (self.waterlevel == 2)
		CheckWaterJump ();
		
	[b]if (self.waterlevel == 3 && !(self.water_in))
		water_depth_entity();[/b]
This entity would keep readjusting itself to different waterlevels or if it somehow moved into a location that wasn't content_water. However, this wouldn't be a very good solution but a workable one even on levels that have different waterlevel sections.
Post Reply