Jump to content
Sign in to follow this  
igneous01

Find position with solid surface (roof top)?

Recommended Posts

I have been searching for this for half a day now, and no results.

So the question is:

Is there a method for finding a position (or checking a position) that has solid ground?

I have this little function i wrote that will find a building, find its dimensions using bounding box, and return a position on top of the building (on the roof) in a random radius of the buildings rectangular dimension (so it doesnt always become the center of the building)

however, this script fails at an important aspect: Not all buildings have their highest point or roof at the center of the model. Most OA buildings for example have multiple roof ledges, or a half roof half balcony scenario, and if I try to setpos an object with this position, sometimes the object will simply be off in mid air somewhere, fall down, and possibly die.

The goal for me is to be able to spawn static weapons on top of buildings, but make sure that these weapons spawn on the roof of the building, and that its solid ground.

here is the function:

// Building Top function

// Finds the roof of the building, and outputs a position in a random location on this roof top (but not so random as the edge of the building)

RUFS_BuildingTop = {

private ["_building", "_dimensions", "_center", "_position", "_x", "_y", "_z"];

_building = _this select 0;

_dimensions = boundingBox _building;

_center = boundingCenter _building; // center of the building

if ((typeName _building) != "OBJECT") then {

hint "NO BUILDING EXISTS";

};

// x and y extremes of bounding box

_xmin = ((_dimensions select 0) select 0);

_ymin = ((_dimensions select 0) select 1);

_xmax = ((_dimensions select 1) select 0);

_ymax = ((_dimensions select 1) select 1);

_midx = (_xmax / 2) - 1;

_midy = (_ymax / 2) - 1;

_xC = _center select 0;

_yC = _center select 1;

_z = ((_dimensions select 1) select 2); // height

player sidechat format ["center: %1 isflat: %2", _center, _isFlat];

// adjust this position for any elevation changes (building on top of hill for example)

_position = [(getposATL _building select 0) + (sin (random 360)) * (random _midx), (getposATL _building select 1) + (cos (random 360)) * (random _midy), (getposATL _building select 2) + _z];

_mark = createMarker ["la", _position];

_mark setMarkerType "Dot";

// Output

_position

};

Does anyone have any ideas or methods to find a solid surface?

Share this post


Link to post
Share on other sites

Read out the building positions (buildingPos; just iterate through it until the returned position is [0,0,0], beginning with 0) and filter them according to the height of the returned positions. Otherwise, you're out of luck and the last resort would be to build a library with suitable positions for all buildings by hand.

Share this post


Link to post
Share on other sites

This is one method that I want to use for placing statics by themselves, but since i have small compositions of statics with sandbags around them, I need some space to put these (rather than in buildingPos thats usually near the edge of the building or door)

My alternative solution which is in the works is to use a probe like a baseball to test the position. Letting the simulation of the ball tell me if there is solid ground there.

and check whether the difference in hieght of the balls original position and new position is less than 1m (usually enough to describe it as being flat ground).

however current problem is I want this function to return me a value, but I cannot suspend the function using waitUntil {ball has stopped falling}, hence I may need to use spawn (but then I cant determine whether the position has ground dammit!)

here is the function:

// Probe function
// Creates probe object at a given position, and checks to see if this position has solid ground (diff in height less than 1m) after simulation 
RUFS_ProbeSurface = {
   private ["_pos", "_bball", "_probe", "_zi", "_zf", "_zdiff", "_vel", "_hasSurface"];
   _pos = _this select 0;
   _zi = _pos select 2;
   _bball = "Baseball";
   _probe = _bball createVehicle _pos;
   _probe setpos _pos;
   waitUntil {_vel = velocity _probe select 2; _vel = 0}; // waitUntil the object has stopped falling
   _zf = getpos _probe select 2;
   _zdiff = _zi - _zf;
   // find difference in height
   if (_zdiff > 1) then {
       _hasSurface = false;
       hint "surface unsuitable";
   } else {
       _hasSurface = true;
       hint "surface suitable";
   };
   deletevehicle _probe;
   // output result
   _hasSurface
};

---------- Post added at 08:40 AM ---------- Previous post was at 07:22 AM ----------

*********

My workaround solution is finished and working!

Problem with baseball is that you cannot setVelocity it, nor does it have any simulation (it will float in midair)

so the function is reworked to spawn a rabbit (which is considered a vehicle?) and this rabbit has a velocity vector down of -60m/s. Once it crashes into the ground, the loop will exit, and the difference between positions (original height and new height) will be checked. If the difference is greater than 0.5m down, or 1m up, then the position has no solid surface, and is unsuitable.

here is the function in case someone might need it:

// Probe function
// A workaround for hasSurface
// Creates probe object at a given position, and checks to see if this position has solid ground (diff in height less than 1m) after simulation 
RUFS_ProbeSurface = {
   private ["_pos", "_bball", "_probe", "_zi", "_zf", "_zdiff", "_vel", "_hasSurface"];
   _pos = _this select 0;
   _zi = _pos select 2;
   _bball = "Rabbit"; // our furry little friend
   _probe = _bball createVehicle _pos;
   _probe setpos _pos;
   _vel = -60;
   _probe setVelocity [0, 0 , -60]; // force the object to crash downward
   while {_vel > 0.1 && _vel < -0.1} do {
       _vel = velocity _probe select 2;
   };
   _zf = getposATL _probe select 2;
   _zdiff = _zi - _zf;
   // find difference in height
   if (_zdiff > 0.5 || _zdiff < -1) then {
       _hasSurface = false;
       hint "surface unsuitable";
   } else {
       _hasSurface = true;
       hint "surface suitable";
   };
   deletevehicle _probe;
   // output result
   _hasSurface
};

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
Sign in to follow this  

×