influence static method
Place a geographic feature on the terrain.
List<Vector3> g
The vertex array for plane geometry to modify with heightmap data. This
method sets the z property of each vertex.
TerrainOptions options
A map of settings that control how the terrain is constructed and
displayed. Valid values are the same as those for the options parameter
of {@link THREE.Terrain}().
[double Function(double,double?,double?)?] f
A function describing the feature. The function should accept one
parameter representing the distance from the feature's origin expressed as
a number between -1 and 1 inclusive. Optionally it can accept a second and
third parameter, which are the x- and y- distances from the feature's
origin, respectively. It should return a number between -1 and 1
representing the height of the feature at the given coordinate.
THREE.Terrain.Influences contains some useful functions for this
purpose.
double x = 0.5
How far across the terrain the feature should be placed on the X-axis, in
PERCENT (as a decimal) of the size of the terrain on that axis.
double y = 0.5
How far across the terrain the feature should be placed on the Y-axis, in
PERCENT (as a decimal) of the size of the terrain on that axis.
double r = 64
The radius of the feature.
double h = 64
The height of the feature.
String t = NormalBlending
Determines how to layer the feature on top of the existing terrain. Valid
values include THREE.AdditiveBlending, THREE.SubtractiveBlending,
THREE.MultiplyBlending, THREE.NoBlending, THREE.NormalBlending, and
any function that takes the terrain's current height, the feature's
displacement at a vertex, and the vertex's distance from the feature
origin, and returns the new height for that vertex. (If a custom function
is passed, it can take optional fourth and fifth parameters, which are the
x- and y-distances from the feature's origin, respectively.)
Easign e = EaseIn
A function that determines the "falloff" of the feature, i.e. how quickly
the terrain will get close to its height before the feature was applied as
the distance increases from the feature's location. It does this by
interpolating the height of each vertex along a curve. Valid values
include THREE.Terrain.Linear, THREE.Terrain.EaseIn,
THREE.Terrain.EaseOut, THREE.Terrain.EaseInOut,
THREE.Terrain.InEaseOut, and any custom function that accepts a float
between 0 and 1 representing the distance to the feature origin and
returns a float between 0 and 1 with the adjusted distance. (Custom
functions can also accept optional second and third parameters, which are
the x- and y-distances to the feature origin, respectively.)
Implementation
static void influence(Float32List g, TerrainOptions options, [double Function(double,[double?,double?])? f, double? x, double? y, double? r, double? h, int? t, Easing? e]) {
f = f ?? influences[InfluenceType.hill]; // feature shape
x ??= 0.5; // x-location %
y ??= 0.5; // y-location %
r ??= 64; // radius
h ??= 64; // height
t ??= NormalBlending; // blending
e = e ?? Easing.easeIn; // falloff
// Find the vertex location of the feature origin
int xl = options.xSegments + 1, // # x-vertices
yl = options.ySegments + 1; // # y-vertices
double vx = xl*x, // vertex x-location
vy = yl * y, // vertex y-location
xw = options.xSize / options.xSegments, // width of x-segments
yw = options.ySize / options.ySegments, // width of y-segments
rx = r / xw, // radius of the feature in vertices on the x-axis
ry = r / yw, // radius of the feature in vertices on the y-axis
r1 = 1 / r; // for speed
int xs = (vx - rx).ceil(), // starting x-vertex index
xe = (vx + rx).floor(), // ending x-vertex index
ys = (vy - ry).ceil(), // starting y-vertex index
ye = (vy + ry).floor(); // ending y-vertex index
// Walk over the vertices within radius of origin
for (int i = xs; i < xe; i++) {
for (int j = ys; j < ye; j++) {
int k = j*xl + i;
// distance to the feature origin
double fdx = (i - vx)*xw,
fdy = (j - vy)*yw,
fd = math.sqrt(fdx*fdx + fdy*fdy),
fdr = fd*r1,
fdxr = fdx*r1,
fdyr = fdy*r1,
// Get the displacement according to f, multiply it by h,
// interpolate using e, then blend according to t.
d = f!(fdr, fdxr, fdyr)*h*(1 - e(fdr, fdxr, fdyr));
final k2 = g.getK(k);
if (fd > r) continue;// || g.get(k) == null
if (t == AdditiveBlending){
g[k2] += d; // jscs:ignore requireSpaceAfterKeywords
}
else if (t == SubtractiveBlending){
g[k2] -= d;
}
else if (t == MultiplyBlending){
g[k2] *= d;
}
else if (t == NoBlending){
g[k2] = d;
}
else if (t == NormalBlending){
g[k2] = e(fdr, fdxr, fdyr) * g[k2] + d;
}
//else if (typeof t == 'function') g[k] = t(g[k].z, d, fdr, fdxr, fdyr);
}
}
}