Better detection of Water Depth

Better detection of Water Depth

Requests for features in the spring code.

Moderator: Moderators

Post Reply
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Better detection of Water Depth

Post by Argh »

Very simply... I'd like us to be able to return a non-binary value for "is over water". Spring has inherited the TA engine's very crude recognition of water depth. This leaves us with the same limitations as OTA, where a lot've units, like "swimming tanks" aren't really practical. I've built a unit for NanoBlobs 0.51b that can "swim", but the crudity of the water/land boundary is obvious, and annoying.

What we need, in my opinion, is to use the standard BOS, but have the results coming back from the engine be a little different. Currently, we use scripts to detect water like this one:

Code: Select all

setSFXoccupy(level)
{
	WaterDepth = level;
	If( Waterdepth == 1 )
		{
		Overwater = 0;
		}
	If( Waterdepth == 2 )
		{
		Overwater = 1;
		}
	If( Waterdepth == 3 )
		{
		Overwater = 1;
		}
	If( Waterdepth == 4 )
		{
		Overwater = 0;
		}
	return (0);
}
Surely we can have something better than this. We already know the waterheight, so we know when the water "begins". So why not just have something like this:

Code: Select all

setSFXoccupy(level)
{
	WaterDepth = level;
	If( Waterdepth >= 1 )
		{
		Overwater = 0;
		}
	return (0);
}
... where level, the value we're seeking from the Spring game engine, is the difference between the Y height of the unit and the water level set in the map, expressed as a float for smooth translations between states?

When you see my new unit I made for NanoBlobs, I think you'll understand why I'm a little disappointed that this part of Spring is very crude- it's an awesome unit that has some serious problems in terms of look-and-feel simply because I cannot make it accurately anticipate that it's about to leave the water :P
Gnomre
Imperial Winter Developer
Posts: 1754
Joined: 06 Feb 2005, 13:42

Post by Gnomre »

What does "get GROUND_HEIGHT" report when on the water?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I thought thats how it worked currently??

Currently the water plane is always at 0 in spring. Anything below 0 gets rendered below the water plane and anything above 0 is rendered above the water plane.

Thus

if(height >0){
overwater=0;
}

If this is different for BOS then I'm sure it can be changed easily...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

<Shrugs>

Wrote this code, and it consistently returns 0. GROUND_HEIGHT is returning a non-zero number... now for some experiments to find out if it's returning anything that's actually useful...

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth < 0)
	{
	OverWater = 1;
	}
	If (WaterDepth > 0)
	{
	OverWater = 0;
	}
	sleep 100;
}
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Aha. Getting somewhere. This returns a value of 1. Betcha it's using a value of 256, with 127 or 128 as the value for the water level.

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth <= 10000)
	{
	OverWater = 1;
	}
	If (WaterDepth > 10000)
	{
	OverWater = 0;
	}
	sleep 100;
}
... nope, that doesn't work. Thinks I'm over water!

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth <= 0.5)
	{
	OverWater = 1;
	}
	If (WaterDepth > 0.5)
	{
	OverWater = 0;
	}
	sleep 100;
}
STILL thinks I'm over water! Something's very, very odd here.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Soooo... the number is over 0, but below 0.5. Erm, ok... let's try something absurdely low:

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth <= 0.000001)
	{
	OverWater = 1;
	}
	If (WaterDepth > 0.000001)
	{
	OverWater = 0;
	}
	sleep 100;
}
.... no dice!

Oops, my first check didn't look for == 0. Let's try that...

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth < 0)
	{
	OverWater = 1;
	}
	If (WaterDepth >= 0)
	{
	OverWater = 0;
	}
	sleep 100;
}
Hmm... zero.

Code: Select all

CheckWaterDepth()
{
	WaterDepth = get GROUND_HEIGHT;
	If (WaterDepth <= 0)
	{
	OverWater = 1;
	}
	If (WaterDepth > 0)
	{
	OverWater = 0;
	}
	sleep 100;
}
Zero! It always returns zero, period. Any other ideas, folks? It appears that this value is returned as zero by Spring... probably to prevent crashes with units that made use of this feature in OTA. Methinks it should just return the real Y value of the heightmap pixel the unit's over when queried, with any values under the water level returning negative numbers, for simplicity's sake. That'd solve it, and be easy to wrap our heads around.
Yeha
Posts: 96
Joined: 13 Aug 2004, 19:12

Post by Yeha »

It returns the height at specific coordinates. If you want the height under the unit try "get GROUND_HEIGHT(get UNIT_XZ)".
User avatar
ILMTitan
Spring Developer
Posts: 410
Joined: 13 Nov 2004, 08:35

Post by ILMTitan »

If GROUND_HEIGHT is being converted to an unsigned int from an int, then 128 and above would be below water and below would be ground. 255 -> -1, 128->-128.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Interesting. I've gotten it to work, kind've, but... it's not returning anything like the values you guys are talking about.

I got it to work with a combo that evaluated it for 0 or not 0, but when I try to convert it to a number that I can look at as a range (which is what I need here- something less crude than just a binary state change)... it's not returning a number... hmm
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Getting closer to the truth, here. This script finally returns a valid TRUE/FALSE every time. It looks dumb, but the little math bits there at the start seem to be forcing Spring to finally evaluate it as a number properly.

Code: Select all

CheckWaterDepth()
{
	while(TRUE)
	{
   	WaterDepth = get GROUND_HEIGHT(get UNIT_XZ);
   	WaterDepth = WaterDepth + 1.00;
   	WaterDepth = WaterDepth * 1.00;
   	If (WaterDepth > 1)
   	{
   	OverWater = 0;
   	}
   	If (WaterDepth <= 1)
   	{
   	OverWater = 1;
   	}
   	sleep 100;
   	}
}
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

More trouble. Whatever this is returning, it's greater than -5, no matter how deep the water is. Methinks it's zero. Sigh. That's not what I was hoping for!

Code: Select all

CheckWaterDepth()
{
	while(TRUE)
	{
   	WaterDepth = get GROUND_HEIGHT(get UNIT_XZ);
   	WaterDepth = WaterDepth + 1.00;
   	WaterDepth = WaterDepth * 1.00;
   	WaterDepth = WaterDepth - 1.00;
   	If (WaterDepth > -5.0)
   	{
   	OverWater = 0;
   	}
   	If (WaterDepth <= -5.0)
   	{
   	OverWater = 1;
   	}
   	sleep 100;
   	}
}
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Definately... zero! Ok, so water is zero. Everything else is positive- there are no negative numbers. I cannot measure the distance from the ocean surface to the ocean floor- insofar as Spring is concerned, it doesn't really exist, since my unit isn't a sub/ship (which is a whole nother set of issues- I have got to convince you guys to do away with all of the special classes someday). Kind've sucks to be me. Now, let's see... maybe I can get this another way...
User avatar
SinbadEV
Posts: 6475
Joined: 02 May 2005, 03:56

Post by SinbadEV »

so how do tanks that run across the bottom of the water report their deapth?

reason I ask is that units that "float" never go under water... so maybe from THEIR perpective the water is always 0 pixles deep, while to a submersible unit (not a sub, subs are just boats whoes models are drawn underwater) who acctually goes underwater might recornoze the acctual deapth... still useless to you I would think... but good to know...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Ok, I'm reeeeeally close now. I just have one final problem, and this is probably a no-brainer for you scripting experts out there...

It almost works perfectly now. It can tell when it's over water, and when it's over land. I've set the detection points far enough apart that it needs to go a ways "out to sea" before submerging (the whole point of this, really). The only problem left is that it keeps "tipping" on land- it's very clearly getting a value that tells it it's on the ocean, and then is very quickly getting corrected... over and over and over again :P Any idea why it's failing to continuously update properly? It's gotta be something dumb, but I'm too tired to find it.

Code: Select all

CheckWaterDepth()
{
   	WaterDepth = (((get GROUND_HEIGHT(get PIECE_XZ(front_point))) + 1) * ((get GROUND_HEIGHT(get PIECE_XZ(rear_point))) + 1) * ((get GROUND_HEIGHT(get PIECE_XZ(right_point))) + 1) * ((get GROUND_HEIGHT(get PIECE_XZ(front_point))) + 1));
   	If (WaterDepth > 1)
   	{
   	OverWater = 1;
   	}
   	If (WaterDepth <= 1)
   	{
   	OverWater = 0;
   	}
   	sleep 1;
   	return(0);
}

SlopeAdjust()
{
	var x-slope, z-slope;
	while(TRUE)
		{
		call-script CheckWaterDepth();
		sleep 50;
		if (OverWater == 1)
			{
			x-slope=get ATAN (((get GROUND_HEIGHT(get PIECE_XZ(front_point))) - (get GROUND_HEIGHT(get PIECE_XZ(front_point)))),((get XZ_HYPOT( ((get PIECE_XZ(rear_point)) - (get PIECE_XZ(front_point)))))));
			z-slope=get ATAN (((get GROUND_HEIGHT(get PIECE_XZ(right_point))) - (get GROUND_HEIGHT(get PIECE_XZ(left_point)))),((get XZ_HYPOT( ((get PIECE_XZ(right_point)) - (get PIECE_XZ(left_point)))))));
			turn body to x-axis x-slope speed <400>;
			turn body to z-axis z-slope speed <400>;
			move body to y-axis [0] speed [30];
			}
		if (OverWater == 0)
			{
			turn body to x-axis <-20> speed <200>;
			move body to y-axis [-6] speed [1];
			}
		}
		return(0);
}
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

In case you want to get a value out of a BOS script, here is a model and script for an eleven digit decimal counter that can display any number from the script. If I knew how to do modulo it'd work better, though.

Just in case you need to do that later on.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Cool, well I can use that to find out what feedback I'm getting from this... didn't have any time/mental energy to mess with this last night (been very rough at work this week, had Weds off).
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

WOOT!!! GOT IT!

The best part is, it's not even terribly hard... now I just need to get the timing right, for perfect animation...
Post Reply

Return to “Feature Requests”