Jump to content
Sign in to follow this  
NeoArmageddon

Smoothing Terrain [Visitor Script]

Recommended Posts

Aloha,

with the new "Brush"-feature of Visitor3 directly editing the terrain in Buldozer and V3 has become much easier and quite handy. The leveling feature is great for reducing the bank of roads and buildings but slopes could get a little bit stepped. For this I created a small script that smoothes a selected area in Visitor3. This is especially helpful if you use roads placed as objects and not as networks (if you are using Road Painter 2 for example).

Here is the first version of the script:

// SmoothTerrain.vis
//
// *************************************************************************************************************
// This script allows to smooth the terrain in a selected area. This will help with getting rid of the unaesthetic
// terrain edges when working with the buldozer brush/leveler.
// The smoothing algorithmen is a simple average with additional weight to the smoothed vertex.
//
// Author: NeoArmageddon
// Parts of this script are taken from the script shipped with Visitor3 (SmoothRoads.vis)
//
// *************************************************************************************************************



// **********************************************************************************************************
// IsAValidArea
// **********************************************************************************************************
IsAValidArea = 
{
private["_params", "_doc", "_area", "_vertices", "_test", "_returnValues"];

// gets document and area 
_params = _this;
_doc = _params select 0;
_area = _params select 1;

// gets the vertices under the area
_vertices = _doc getVerticesUnder _area;

// core - test validity
_test = true;
if(isnil("_vertices")) then
{
	_test = false;
};

_returnValues = [_test, _vertices];

// return value
_returnValues
};


// **********************************************************************************************************
// WarningDialog
// **********************************************************************************************************
WarningDialog =
{
private["_type", "_title", "_messageRow1", "_messageRow2", "_dlgWarning", "_result"];

// gets the type of warning
_type = _this;

// sets title and message
_title = "";
_messageRow1 = "";
_messageRow2 = "";
switch(_type) do
{
	case 1:
	 	{
			_title = "Warning - No area selected.";
			_messageRow1 = "This script requires that you select an area before you run it.";
			_messageRow2 = "Please select an area and then rerun the script.";
	 	};
	default
	 	{
			_title = "Warning - Error in dialog setting";
			_messageRow1 = "Error in WarningDialog function.";
	 	};
}; 

// sets dialog
_dlgWarning = [220, 55, _title,
	    	  ["label", 200, 13, _messageRow1, 0], ["break"],
	    	  ["label", 200, 13, _messageRow2, 0], ["break"],
    		  ["ok-button", 50, 13]];

// shows the dialog
_result = dialogBox _dlgWarning;

// return value
_result
};




// **********************************************************************************************************
// FindVertex
// **********************************************************************************************************
FindVertex = 
{
private ["_params", "_vertices", "_point", "_i", "_count", "_v", "_result"];

// get params
_params   = _this;
_vertices = _params select 0;
_point    = _params select 1;

_i = 0;
_count = count _vertices;
_result = -1;
while "_i < _count && _result == -1" do 
{
	_v = _vertices select _i;
	if ((_v select 0) == (_point select 0)) then 
	{
		if ((_v select 1) == (_point select 1)) then 
		{
			_result = _i
		};
	};
	_i = _i + 1;
};

//return value
_result
};


// **********************************************************************************************************
// SmoothTerrain
// **********************************************************************************************************
SmoothTerrain =
{
private ["_params", "_doc", "_vertices", "_gridStepArray", "_gridStep", "_averageHeight", "_Surrounding", "_x1", "_y1",
	   "_i", "_pt", "_z1", "_z2", "_i1", "_p1", "_p2","_n1","_n2","_n3","_n4","_flag"];

// get params
_params   = _this;
_doc      = _params select 0;
_vertices = _params select 1;

// gets the grid step
_gridStepArray = getTerrainSize _doc;
_gridStep      = _gridStepArray select 2;

_Surrounding = [];

{
	_x1 = _x select 0;
	_y1 = _x select 1;
	_z1 = _x select 2;
	_flag = true;
	_averageHeight = _z1;

	_n1 = [_vertices, [_x1 - _gridStep, _y1]] call FindVertex;
	_n2 = [_vertices, [_x1 + _gridStep, _y1]] call FindVertex;
	_n3 = [_vertices, [_x1 , _y1 - _gridStep]] call FindVertex;
	_n4 = [_vertices, [_x1, _y1 + _gridStep]] call FindVertex;

	if (_n1 != -1) then 
	{
		_averageHeight = _averageHeight + ((_vertices select _n1) select 2);	
	} else {
		_flag = false;
	};
	if (_n2 != -1) then 
	{
		_averageHeight = _averageHeight + ((_vertices select _n2) select 2);
	} else {
		_flag = false;
	};
	if (_n3 != -1) then 
	{
		_averageHeight = _averageHeight + ((_vertices select _n3) select 2);
	} else {
		_flag = false;
	};
	if (_n4 != -1) then 
	{
		_averageHeight = _averageHeight + ((_vertices select _n4) select 2);
	} else {
		_flag = false;
	};
	if(_flag) then {
		_Surrounding = _Surrounding + [[_x1,_y1,(_averageHeight*0.2)]];
	};
} forEach _vertices;


//return value
_Surrounding
};


echo "---------------";
echo "SmoothTerrain.vis";
echo "---------------";

// ---------------------------------
// internal variables default values
// ---------------------------------
_scriptName   = "Smooth Terrain 1.0.0";
_lblParameter = " Range (odd number):";
_parameter    = 25;
_totalCounter = 0;
_smoothedVertices = [];
_vertices = [];
_iterations = 1;
// -------------------
// dialogs definitions
// -------------------
_dlgInput = [210, 105, _scriptName,
	["begin-subframe", 200, 80, " Smoothing method "],
		["begin-subframe", 190, 30, " Iterations "],
		    	["textline", 40, 13, "_iterations", 0], ["break"],
		["end-subframe"], ["break"],
	["end-subframe"], ["break"],
	["ok-button", 50, 13], ["cancel-button", 50, 13]];

_dlgOutput = [220, 90, _scriptName,
	 ["label", 200, 13, "Vertices edited:", 2], ["break"],
	 ["dynlabel", 200, 40, "_totalCounter", 2], ["break"],
		 ["ok-button", 50, 13]];
// ------------------------
// gets the active document
// ------------------------
_doc = getActiveDoc;    

// ----------------------
// gets the selected area 
// ----------------------
_area = getSelectedArea _doc;

// ------------------------
// verify the selected area 
// ------------------------
_verifyArea = [_doc, _area] call IsAValidArea;
_validArea = _verifyArea select 0;
_vertices = _verifyArea select 1; 	// gets the selected vertices 

// -----------
// script core 
// -----------
if (!(_validArea)) then    // no area selected in the document
{
_warningNum = 1;
_warningNum call WarningDialog;
}
else    // valid area selection
{
// shows the input dialog
_result = dialogBox _dlgInput;

if(_result == 1) then
{		
	for "_i" from 0 to (_iterations-1) do
	{
			// smooths the surrounding terrain 
			_vertices = [_doc, _vertices] call SmoothTerrain;			
	};
	// apply to terrain
	_vertices setVerticesTo _doc;
	_totalCounter = count(_vertices);
	_result = dialogBox _dlgOutput;

};
};

The smoothing algorithmen is very simple (average mean + extra weight towards the current vertex). One iteration should be enough to get rid of all ugly edges in the sleected area.

I plan to implement more smoothing algorithmens with different features. I am also trying to build a road smoother for non-network roads.

Hope this is helpful for some of you.

Share this post


Link to post
Share on other sites

Amazing! :yay: More of such stuff, especially for roads.

Share this post


Link to post
Share on other sites

Top! Can't tell how Id like to have a script that will do that with the shapefile roads once V4 is there :-)

Share this post


Link to post
Share on other sites

I would like to create a map for a mod for ArmA3 but have zero experience in doing any of this. I have been searching around these forums looking at the various guides and downloadable content to help me do this. I just don't know where to begin to get started. I have a good understanding of most things PC but as far as something like this goes I have no idea.

I'm wondering if there is anyone out there that would be willing to join me on TeamSpeak and help me get the ball rolling/give me some introductory lessons. I learn better by doing rather than reading and trying myself (I've already failed at getting the editor in A3 working by simply creating new mission.biedi and changing the file path of the shortcut to A3...) Also what I want to do is going to be a project that I won't be able to do by myself. So I am also looking for people with experience and are looking for a project.

Share this post


Link to post
Share on other sites
If you use Arma3 as buldozer in Visitor, press "S" until it says "Brush", then use LMB to increase the terrain, and RMB to lower the terrain.

Also you can do the following

Left Alt + M + Mousewheel will change the intensity

Left Alt + B + Mousewheel will change the brush size

Left Alt + N + Mousewheel will change outer brush size only

Left Shift toggles a leveling-mode.

i used this for Smoothing Terrain,

hope this helps ;)

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  

×