Jump to content
Guest

Distance to Bounding Box

Recommended Posts

Guest

This function check if the unit _unit is inside building _building:

BRPVP_isInsideBuilding = {
	params ["_unit","_building",["_h",50]];
	private ["_p1","_p2","_p3","_objects","_tstA""_tstB"];
	_p1 = getPosASL _unit;
	_p2 = [_p1 select 0,_p1 select 1,(_p1 select 2) - 1];
	_objects = lineIntersectsWith [_p1,_p2];
	_tstA = _building in _objects;
	if (!_tstA) then {
		_p3 = [_p1 select 0,_p1 select 1,(_p1 select 2) + _h];
		_objects = lineIntersectsWith [_p1,_p3];
		_building in _objects
	} else {
		true
	};
};

Usage:

_isInsideHouse = [player,_house] call BRPVP_isInsideBuilding;

Third parameter:

//EXAMPLE 1
_insideBuilding = [player,_noFloorBuilding,20] call BRPVP_isInsideBuilding; //Will search for ceiling 20 meter above

//EXAMPLE 2
_insideBuilding = [player,_noFloorBuilding] call BRPVP_isInsideBuilding; //Will search for ceiling 50 meter above (50 is default)

Share this post


Link to post
Share on other sites
Guest

Thankyou.

BRPVP_getBBSegments = {
	_bb = boundingBoxReal _this;
	_p1 = _bb select 0;
	_p2 = _bb select 1;
	_p1x = _p1 select 0;
	_p2x = _p2 select 0;
	_p1y = _p1 select 1;
	_p2y = _p2 select 1;
	_p1z = _p1 select 2;
	_p2z = _p2 select 2;
	_segs = [
		//CEIL
		[[_p1x,_p1y,_p1z],[_p2x,_p1y,_p1z]],
		[[_p2x,_p1y,_p1z],[_p2x,_p2y,_p1z]],
		[[_p2x,_p2y,_p1z],[_p1x,_p2y,_p1z]],
		[[_p1x,_p2y,_p1z],[_p1x,_p1y,_p1z]],
		
		//FLOOR
		[[_p1x,_p1y,_p2z],[_p2x,_p1y,_p2z]],
		[[_p2x,_p1y,_p2z],[_p2x,_p2y,_p2z]],
		[[_p2x,_p2y,_p2z],[_p1x,_p2y,_p2z]],
		[[_p1x,_p2y,_p2z],[_p1x,_p1y,_p2z]],
		
		//VERTICAL SEGMENTS
		[[_p1x,_p1y,_p1z],[_p1x,_p1y,_p2z]],
		[[_p2x,_p1y,_p1z],[_p2x,_p1y,_p2z]],
		[[_p2x,_p2y,_p1z],[_p2x,_p2y,_p2z]],
		[[_p1x,_p2y,_p1z],[_p1x,_p2y,_p2z]]
	];
	_segs
};

Share this post


Link to post
Share on other sites
Guest

Thankyou.

 

This is a dual purpose function.

 

About finding the nearest border, the instructions are a bit unclear about were the returned position is on the border.

Share this post


Link to post
Share on other sites
Guest

Its already done.

I share the result on the Post.

Share this post


Link to post
Share on other sites
Guest

Kylania,

 

Its for a "loot" system.
 

I just spawn the loot in a enterable building and if the player enters the building. This is why i need precise info if the player is or not is in the building.

With out this precision, a player passing by on the street can spawn loot in many buildings.

What i will do is firstly check if the player is in the radius of the building. If he is, then i use this Bound Box check to make sure he is inside it.

Share this post


Link to post
Share on other sites

I shoot a ray upwards from player. If it intersects a buildingobject, he is inside. I guess it's lot less calculations. Just an idea.

And according to my experience, boundingboxes on some buildings are not too precise.

  • Like 2

Share this post


Link to post
Share on other sites
Guest

Zapat,

 

Indeed, a lot more simple.

 

:lol2:

 

If the player is inside a building, in an open roon, the ray may not intersect the building?

Share this post


Link to post
Share on other sites

Zapat,

 

Indeed, a lot more simple.

 

:lol2:

 

If the player is inside a building, in an open roon, the ray may not intersect the building?

 

if there is no roof then it will not intersect.

Share this post


Link to post
Share on other sites

I shoot a ray upwards from player. If it intersects a buildingobject, he is inside. I guess it's lot less calculations. Just an idea.

And according to my experience, boundingboxes on some buildings are not too precise.

Intersection task is much much heavier than finding point-to-box relation. The more you go in row "curve to curve", "curve to surface", "surface to surface" the heavier it gets.

It can seem an easier task for user script (having engine caclulating stuff), but still a lof more work to be done with intersections and it is not going anywhere.

Share this post


Link to post
Share on other sites

No limitations on 2d/3d or slope areas.

// returns true if position of _unit is inside real bound box of _obj
PDTH_pointIsInBox = {
	params ["_unit","_obj"];
	_uPos = _obj worldToModel (getPos _unit);
	_oBox = boundingBoxReal _obj;

	_inHelper = {
		params ["_pt0", "_pt1"];
		(_pt0 select 0 <= _pt1 select 0) && (_pt0 select 1 <= _pt1 select 1) && (_pt0 select 2 <= _pt1 select 2)
	}

	([_oBox select 0, _uPos] call _inHelper) && ([_uPos, _oBox select 1] call _inHelper)
};

// returns distance between position of _unit and closest point suface of _obj's real
// bound box (i.e. closest vertex, edge or point in bb's face).
// returns 0 if inside or exactly on surface
PDTH_distance2Box = {
	params ["_unit","_obj"];
	_uPos = _obj worldToModel (getPos _unit);
	_oBox = boundingBoxReal _obj;
	_pt = [0, 0, 0];
	{
		if (_x < (_oBox select 0 select _forEachIndex)) then {
			_pt set [_forEachIndex, (_oBox select 0 select _forEachIndex) - _x];
		} else {
			if ((_oBox select 1 select _forEachIndex) < _x) then {
				_pt set [_forEachIndex, _x - (_oBox select 1 select _forEachIndex)];
			}
		}
	} forEach _uPos;
	_pt distance [0, 0, 0]
};

Share this post


Link to post
Share on other sites
Guest

Thanks a lot pedeathtrian, this seens extremelly light and working as BI intended us to do it to work,

There is something wrong with my function. I belive the way i get BB segments are wrong.

A diagonal don't defines a BB. I'm considering the arests are paralel to axis x, y or z.

I'm giving a try to understand your functions before use it.

Share this post


Link to post
Share on other sites

Intersection task is much much heavier than finding point-to-box relation. The more you go in row "curve to curve", "curve to surface", "surface to surface" the heavier it gets.

It can seem an easier task for user script (having engine caclulating stuff), but still a lof more work to be done with intersections and it is not going anywhere.

 

I use a inside building function using a lineIntersectsWith cast from 40m above the player to 2m below, then remove all non buildings from the results. If there's any objects left, the position is inside a building.

My function takes 0.0180ms if there are no objects above or below the position, and up to 0.0330ms when in heavy jungle.

For reference PDTH_pointIsInBox takes 0.0190ms inside, 0.0210ms outside. PDTH_distance2Box takes 0.0220ms inside and 0.0240ms outside, but they only test a single known object. Finding nearby buildings that the player might be inside of is likely a slower task than the test itself. Line intersection also gives better results due to testing the actual geometry rather than a bounding box.

 

Thanks for sharing your functions, I've recently made an inside volume test using that is terribly slow compared to your functions. I hadn't considered using worldToModel, only the other way around  :)

Edited by ceeeb
  • Like 3

Share this post


Link to post
Share on other sites
Guest

ceeeb,

Thankyou for sharing, and for the performance tests, and for the details about the method  :286: .

Share this post


Link to post
Share on other sites

ceeeb,

Thankyou for sharing, and for the performance tests.

Some of the loot spawn on building roof. If the player is on the roof, the intersection check will return false?

What about check from a point bellow the building and the terrain to a point in the player?

 

It depends how you want to define being inside a building. I use the function to trace paths AI follow when they move in/on/under buildings.

I start the ray from far above the player, and end below the player detects either or both situations:

under a building (such as a shed without a floor, or under the tall military towers on Altis),

on top of a building (such as standing on a pier or roof of a building).

For my purposes, the only time it doesn't return true when it should is when the position is on a ladder on the side of a building with no building beneath. There are some issues with false positive when under powerlines on Tanoa too.

 

The function could easily be split into two functions, one for structure above position, and another for structure below.

 

EDIT: here's a relevant thread where I posted my function, and as usual a faster version by killzone_kid :)

https://forums.bistudio.com/topic/189816-looking-for-a-script-that-finds-all-units-that-are-in-buildings/ 

Edited by ceeeb

Share this post


Link to post
Share on other sites
Guest

Thankyou for answering the old question, i removed before you write.

I did a function:

BRPVP_isInsideBuilding = {
	params ["_unit","_building",["_h",50]];
	private ["_p1","_p2","_p3","_objects","_tstA""_tstB"];
	_p1 = getPosASL _unit;
	_p2 = [_p1 select 0,_p1 select 1,(_p1 select 2) - 1];
	_objects = lineIntersectsWith [_p1,_p2];
	_tstA = _building in _objects;
	if (!_tstA) then {
		_p3 = [_p1 select 0,_p1 select 1,(_p1 select 2) + _h];
		_objects = lineIntersectsWith [_p1,_p3];
		_building in _objects
	} else {
		true
	};
};

It return true if you are:

1) 1 m above the building roof

2) bellow a building with no floor

3) inside the building

 

There are some issues, yes, but its quite usefull.

 

I will check your link!

Share this post


Link to post
Share on other sites

Thankyou for answering the old question, i removed before you write.

I did a function:

BRPVP_isInsideBuilding = {
	params ["_unit","_building",["_h",50]];
	private ["_p1","_p2","_p3","_objects","_tstA""_tstB"];
	_p1 = getPosASL _unit;
	_p2 = [_p1 select 0,_p1 select 1,(_p1 select 2) - 1];
	_objects = lineIntersectsWith [_p1,_p2];
	_tstA = _building in _objects;
	if (!_tstA) then {
		_p3 = [_p1 select 0,_p1 select 1,(_p1 select 2) + _h];
		_objects = lineIntersectsWith [_p1,_p3];
		_building in _objects
	} else {
		true
	};
};

It return true if you are:

1) 1 m above the building roof

2) bellow a building with no floor

3) inside the building

 

There are some issues, yes, but its quite usefull.

 

I will check your link!

I left example in comments about a year ago https://community.bistudio.com/wiki/lineIntersectsSurfaces any good?

 

  • Like 3

Share this post


Link to post
Share on other sites
Guest

Thanks a lot killzone_kid.

 

This function is really good and seens a lot light because its hardcoded to a maximum of 5000 m, what is a lot. I was away from it because it seens complex, but now i understand and its quite simple and usefull.

 

I know if its offtopic, but... you know how i find if an object/vehicle is Physx enabled?

Share this post


Link to post
Share on other sites
Guest

pedeathtrian function comes in rand because i need to check player proximity to a building to lock the building doors or not.

I need to to this check when the player is on the iminence to entering in a building, and is not inside it.

Share this post


Link to post
Share on other sites
On 23/06/2016 at 8:55 PM, pedeathtrian said:

No limitations on 2d/3d or slope areas.


// returns true if position of _unit is inside real bound box of _obj
PDTH_pointIsInBox = {
	params ["_unit","_obj"];
	_uPos = _obj worldToModel (getPos _unit);
	_oBox = boundingBoxReal _obj;

	_inHelper = {
		params ["_pt0", "_pt1"];
		(_pt0 select 0 <= _pt1 select 0) && (_pt0 select 1 <= _pt1 select 1) && (_pt0 select 2 <= _pt1 select 2)
	}

	([_oBox select 0, _uPos] call _inHelper) && ([_uPos, _oBox select 1] call _inHelper)
};

 

 

I updated this slightly so it can accept other input;

 

pdth_fnc_pointIsInBox = {// original by pedeathtrian. returns true if unit is in objs bounding box
	params ["_unit","_obj"];
	private ["_pos"];
	switch (typename _unit) do
		{
			case "STRING": {_pos = getMarkerPos _unit};
			case "OBJECT": {_pos = getpos _unit};
			case "ARRAY": {_pos = _unit};
		};
	_uPos = _obj worldToModel _pos;
	_oBox = boundingBoxReal _obj;
	_inHelper = {
		params ["_pt0", "_pt1"];
		(_pt0 select 0 <= _pt1 select 0) && (_pt0 select 1 <= _pt1 select 1) && (_pt0 select 2 <= _pt1 select 2)
	};
	([_oBox select 0, _uPos] call _inHelper) && ([_uPos, _oBox select 1] call _inHelper)
};

 

Share this post


Link to post
Share on other sites
On 23.6.2016 at 3:19 PM, zapat said:

boundingboxes on some buildings are not too precise.

 

No, it's not that bounding boxes weren't too precise, they're outright wrong. So is boundingBoxReal (i.e. we'd need a boundingBoxRealForReal). They're all excessive in size, since they factor in the wrong/additional LODs for some funny reason. See:

It's IMHO one of the worst things that should have been fixed a long fucking time ago. For A2 I used to manually measure objects and keep my own bounding box lists. For A3 I said fuck it, not again. Shit makes me angry only thinking about it. :icon13:

  • Like 2
  • Thanks 2

Share this post


Link to post
Share on other sites
48 minutes ago, rübe said:

 

No, it's not that bounding boxes weren't too precise, they're outright wrong. So is boundingBoxReal (i.e. we'd need a boundingBoxRealForReal). They're all excessive in size, since they factor in the wrong/additional LODs for some funny reason. See:

It's IMHO one of the worst things that should have been fixed a long fucking time ago. For A2 I used to manually measure objects and keep my own bounding box lists. For A3 I said fuck it, not again. Shit makes me angry only thinking about it. :icon13:

YcA9ZNL.png

 

Holy boundingbox batman!

Did any dev comment on this?

I mean there HAS got to be a reason for this? Please?

 

Cheers

  • Like 2
  • Haha 1
  • Confused 1
  • Sad 2

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×