Drawing of attack areas -- help needed

Drawing of attack areas -- help needed

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
colorblind
Spring Developer
Posts: 374
Joined: 14 Mar 2005, 12:32

Drawing of attack areas -- help needed

Post by colorblind »

In this post I suggested that when placing a defensive unit, you can immediately see where it can and cannot fire. As the SY'ers are busy implementing other cool features for the next release, I decided to write some code. Here's how it looks:

Image

It looks pretty nifty, but it's damn slow. Can anybody see how to speed up the code below? I think the easiest way is to lower the scan resolution, but I don't know how to do it ...

Code: Select all

for(int y=starty;y<endy;++y){
	for(int x=0;x<gs->hmapx;++x){
		int a=y*(gs->pwr2mapx>>1)+x;
		bool inCircle=false;
		// convert square (x,y) to a float3 position
		float xpos = (float) x * SQUARE_SIZE * 2;
		float zpos = (float) y * SQUARE_SIZE * 2;
		// determine whether we're in the bounding box
		if (xpos > drawAttackRangeUnit->pos[0] - drawAttackRangeUnit->maxRange && 
            xpos < drawAttackRangeUnit->pos[0] + drawAttackRangeUnit->maxRange && 
			zpos > drawAttackRangeUnit->pos[2] - drawAttackRangeUnit->maxRange && 
			zpos < drawAttackRangeUnit->pos[2] + drawAttackRangeUnit->maxRange)
		{
			float	ypos		= readmap->centerheightmap[y*gs->mapx+x];
			float3	currentPos	= float3(xpos,ypos,zpos);
			// check whether we're in the circle						
			if (drawAttackRangeUnit->pos.distance2D(currentPos) < drawAttackRangeUnit->maxRange)
			{
				inCircle = true;
				bool canAttackHere	= false;
				for(std::vector<CWeapon*>::iterator wi=drawAttackRangeUnit->weapons.begin();wi!=drawAttackRangeUnit->weapons.end();++wi)
				{
					if ((*wi)->TryTarget(currentPos,true,0))
					{
						canAttackHere = true;
						break;
					}
				}

				if (canAttackHere)
				{
					// good area, draw it green
					infoTexMem[a*4+0]=0;
					infoTexMem[a*4+1]=255;
					infoTexMem[a*4+2]=0;
				}
				else
				{
					// bad area, draw it red
					infoTexMem[a*4+0]=255;
					infoTexMem[a*4+1]=0;
					infoTexMem[a*4+2]=0;
				}
			} // circle
		} // bounding box
		if (!inCircle) // draw areas outside the circle normally
		{
			infoTexMem[a*4+0]=128;
			infoTexMem[a*4+1]=128;
			infoTexMem[a*4+2]=128;
		}
	}
}
Warlord Zsinj
Imperial Winter Developer
Posts: 3742
Joined: 24 Aug 2004, 08:59

Post by Warlord Zsinj »

Nice. Perhaps make it only check for terrain, not units, as that is less essential. You could even just read from LOS then...

Does it take into account ballistics?
IMSabbel
Posts: 747
Joined: 30 Jul 2005, 13:29

Post by IMSabbel »

I am pretty sure the the trytarget function is the bottleneck.
You get easitly get many 1000 calls to it for each build position while placing the tower, and i dont think its optimised for such a usage. (as it has to check for units in range, parse the terrain, ect,ect).

Maybe a more basic function would help, as like zjins said, there is much than can be skipped for that kind of use of the trytarget function.
Torrasque
Posts: 1022
Joined: 05 Oct 2004, 23:55

Post by Torrasque »

That feature would be really awesome.
As Warlord said, I don't think you must check for mobile units.

Ad for a Vulcain, It surely overkill your computer, no?
colorblind
Spring Developer
Posts: 374
Joined: 14 Mar 2005, 12:32

Post by colorblind »

The problem when not checking for units is that you have to write a new function, instead of just using one that's already there. Furthermore you would have to write a new function for every type of weapon -- so I'll wait untill the SY comment on this. And I still think that lowering the scangrid resolution remains a valid option.

And yes, it takes ballistas into account. But you only want to check for lasertype weapons anyway; if you put ballistas on high trajectory they can hit anything, so this feature is pretty meaningless for them.
SJ
Posts: 618
Joined: 13 Aug 2004, 17:13

Post by SJ »

The only easy way to speed it up if try target is the bottleneck is probably not to update the whole thing every frame. You might also want to avoid redrawing the whole map every frame by just looping inside what you call the bouning box instead of doing lots of if on it.

Another problem with this kind of thing though is that weapons no longer aim for the feet but the middle of the units. So in many cases you will be able to hit units (esp high ones) even where the function shows no hits possible.
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Post by cain »

why for the middle and not feet?

in quake, i rocket always too feet, to maximize splash damage when missing.

just asking.
IMSabbel
Posts: 747
Joined: 30 Jul 2005, 13:29

Post by IMSabbel »

well, in quake maybe...
In the army, we were taught to shoot people in the body, noot the boots, otoh.

It works in quake because of high splash damage and little health. It doesnt owrk with a tank, or a mech (kbot==mech), ect.
cain
AI Developer
Posts: 124
Joined: 09 Aug 2005, 10:04

Post by cain »

thanks
IMSabbel
Posts: 747
Joined: 30 Jul 2005, 13:29

Post by IMSabbel »

Also considere: most line of sight weapons in TA arent explosive/splashdamage.

And shells will already arc down, so aiming for the center will still result in splash damage when missing.
User avatar
GrOuNd_ZeRo
Posts: 1370
Joined: 30 Apr 2005, 01:10

Post by GrOuNd_ZeRo »

I have little to add on how things are coded since I have little experience here.


But I do have to comment on the green circle, maybe a more subtle circle, with about >50% opacity?
IMSabbel
Posts: 747
Joined: 30 Jul 2005, 13:29

Post by IMSabbel »

If you only want to calculate it for LOS weapons...

Wouldnt it be possible to just use stencil shadowing and do it in the pixel shader?
colorblind
Spring Developer
Posts: 374
Joined: 14 Mar 2005, 12:32

Post by colorblind »

I've managed to get the scanning resolution down, and it now works smooth on my pc (p3 866mhz), even for a vulcan. So it should work smooth for everybody else too.

The only problem remaining is that it works only for units that already exist, that is, that have already been loaded into the simulation. If you want to place a defensive structure and hover with it over the map, it isn't loaded yet (right?). So I'mg guessing that if you want to draw the attack areas you have to make a dummy unit.

Can anybody tell me the best way to that?
User avatar
GrOuNd_ZeRo
Posts: 1370
Joined: 30 Apr 2005, 01:10

Post by GrOuNd_ZeRo »

Well, the defensive unit that is not build yet displays a ring already to show it's range, so perhaps the best way to get it working is to add that piece of code to the pre-build unit?
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Would it be possible to make the green and red a bit more soft and transparent?
User avatar
aGorm
Posts: 2928
Joined: 12 Jan 2005, 10:25

Post by aGorm »

Yhe... less obtrusive would be nice.

But other than that what a super feature!

aGorm
colorblind
Spring Developer
Posts: 374
Joined: 14 Mar 2005, 12:32

Post by colorblind »

GrOuNd_ZeRo wrote:Well, the defensive unit that is not build yet displays a ring already to show it's range, so perhaps the best way to get it working is to add that piece of code to the pre-build unit?
No, a pre-build unit isn't a member of the CUnit class. It's nothing, Spring gets the range for the red attackcircle from the unitdefinition of that particular type of unit, which hasn't got a TryTarget function. In fact, the unitdef is just a plain old C++ structure, so you can't add functions to it.

It looks like the only way out of it is to temporarily load a unit with the UnitLoader, so you can access its weapons TryTarget function. The problem is that I don't know how to make the dummy unit inert; it seems to me that it always has to be loaded into a team.

SJ, care to help me out here?
Post Reply

Return to “Engine”