mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
add_random_instances(), get_slope()
This commit is contained in:
parent
593393dd64
commit
1c8d2859f1
@ -95,11 +95,13 @@ ConfigVariableBool speedtree_transmission_lighting
|
|||||||
|
|
||||||
ConfigVariableBool speedtree_detail_layer
|
ConfigVariableBool speedtree_detail_layer
|
||||||
("speedtree-detail-layer", false,
|
("speedtree-detail-layer", false,
|
||||||
PRC_DESC("Undocumented SpeedTree parameter."));
|
PRC_DESC("True to render the detail texture layer defined on tree and "
|
||||||
|
"terrain objects, false otherwise."));
|
||||||
|
|
||||||
ConfigVariableBool speedtree_detail_normal_mapping
|
ConfigVariableBool speedtree_detail_normal_mapping
|
||||||
("speedtree-detail-normal-mapping", false,
|
("speedtree-detail-normal-mapping", false,
|
||||||
PRC_DESC("True to enable normal maps in SpeedTree."));
|
PRC_DESC("True to render the detail normal maps defined on tree and "
|
||||||
|
"terrain objects, false otherwise."));
|
||||||
|
|
||||||
ConfigVariableBool speedtree_ambient_contrast
|
ConfigVariableBool speedtree_ambient_contrast
|
||||||
("speedtree-ambient-contrast", false,
|
("speedtree-ambient-contrast", false,
|
||||||
@ -109,13 +111,10 @@ ConfigVariableDouble speedtree_transmission_scalar
|
|||||||
("speedtree-transmission-scalar", 1.0f,
|
("speedtree-transmission-scalar", 1.0f,
|
||||||
PRC_DESC("Undocumented SpeedTree parameter."));
|
PRC_DESC("Undocumented SpeedTree parameter."));
|
||||||
|
|
||||||
ConfigVariableDouble speedtree_fog_start_distance
|
ConfigVariableDouble speedtree_fog_distance
|
||||||
("speedtree-fog-start-distance", 2500.0,
|
("speedtree-fog-distance", "2500 5000",
|
||||||
PRC_DESC("Specifies the nearest distance at which fog begins to be visible."));
|
PRC_DESC("Specifies the nearest and farthest distance of the fog on trees "
|
||||||
|
"and terrain."));
|
||||||
ConfigVariableDouble speedtree_fog_end_distance
|
|
||||||
("speedtree-fog-end-distance", 5000.0,
|
|
||||||
PRC_DESC("Specifies the distance at and beyond which fog is complete."));
|
|
||||||
|
|
||||||
ConfigVariableDouble speedtree_fog_color
|
ConfigVariableDouble speedtree_fog_color
|
||||||
("speedtree-fog-color", "1.0 1.0 1.0",
|
("speedtree-fog-color", "1.0 1.0 1.0",
|
||||||
@ -126,13 +125,9 @@ ConfigVariableDouble speedtree_sky_color
|
|||||||
PRC_DESC("Specifies the r g b color of the SpeedTree sky, when the sky "
|
PRC_DESC("Specifies the r g b color of the SpeedTree sky, when the sky "
|
||||||
"is enabled. Currently unused."));
|
"is enabled. Currently unused."));
|
||||||
|
|
||||||
ConfigVariableDouble speedtree_sky_fog_min
|
ConfigVariableDouble speedtree_sky_fog
|
||||||
("speedtree-sky-fog-min", -0.5,
|
("speedtree-sky-fog", "-0.5 1.0",
|
||||||
PRC_DESC("Undocumented SpeedTree parameter."));
|
PRC_DESC("Specifies the range of fog in the sky. -1 is down, 1 is up."));
|
||||||
|
|
||||||
ConfigVariableDouble speedtree_sky_fog_max
|
|
||||||
("speedtree-sky-fog-max", 1.0,
|
|
||||||
PRC_DESC("Undocumented SpeedTree parameter."));
|
|
||||||
|
|
||||||
ConfigVariableDouble speedtree_sun_color
|
ConfigVariableDouble speedtree_sun_color
|
||||||
("speedtree-sun-color", "1.0 1.0 0.85",
|
("speedtree-sun-color", "1.0 1.0 0.85",
|
||||||
@ -239,6 +234,20 @@ ConfigVariableDouble speedtree_area_scale
|
|||||||
"scales from kilometers to feet. You should set a different "
|
"scales from kilometers to feet. You should set a different "
|
||||||
"scale if you use units other than feet."));
|
"scale if you use units other than feet."));
|
||||||
|
|
||||||
|
ConfigVariableBool speedtree_follow_terrain
|
||||||
|
("speedtree-follow-terrain", true,
|
||||||
|
PRC_DESC("Set this true to have trees automatically snap to the terrain "
|
||||||
|
"height when loaded into a SpeedTree node with a configured "
|
||||||
|
"terrain. If this is false, you may still call "
|
||||||
|
"SpeedTreeNode::snap_to_terrain() afterwards."));
|
||||||
|
|
||||||
|
ConfigVariableInt speedtree_max_random_try_count
|
||||||
|
("speedtree-max-random-try-count", 1000,
|
||||||
|
PRC_DESC("This is a cheesy limit to detect bad parameters passed to "
|
||||||
|
"SpeedTreeNode::add_random_instances(). If this number of attempts "
|
||||||
|
"to find a legal place for a tree fail in a row, the parameters "
|
||||||
|
"are deemed to be in error, and the function fails."));
|
||||||
|
|
||||||
ConfigVariableBool speedtree_5_2_stf
|
ConfigVariableBool speedtree_5_2_stf
|
||||||
("speedtree-5-2-stf",
|
("speedtree-5-2-stf",
|
||||||
#if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 2)
|
#if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 2)
|
||||||
|
@ -42,8 +42,7 @@ extern ConfigVariableBool speedtree_detail_layer;
|
|||||||
extern ConfigVariableBool speedtree_detail_normal_mapping;
|
extern ConfigVariableBool speedtree_detail_normal_mapping;
|
||||||
extern ConfigVariableBool speedtree_ambient_contrast;
|
extern ConfigVariableBool speedtree_ambient_contrast;
|
||||||
extern ConfigVariableDouble speedtree_transmission_scalar;
|
extern ConfigVariableDouble speedtree_transmission_scalar;
|
||||||
extern ConfigVariableDouble speedtree_fog_start_distance;
|
extern ConfigVariableDouble speedtree_fog_distance;
|
||||||
extern ConfigVariableDouble speedtree_fog_end_distance;
|
|
||||||
extern ConfigVariableDouble speedtree_fog_color;
|
extern ConfigVariableDouble speedtree_fog_color;
|
||||||
extern ConfigVariableDouble speedtree_sky_color;
|
extern ConfigVariableDouble speedtree_sky_color;
|
||||||
extern ConfigVariableDouble speedtree_sky_fog_min;
|
extern ConfigVariableDouble speedtree_sky_fog_min;
|
||||||
@ -70,6 +69,8 @@ extern ConfigVariableBool speedtree_show_overlays;
|
|||||||
extern ConfigVariableInt speedtree_max_num_visible_cells;
|
extern ConfigVariableInt speedtree_max_num_visible_cells;
|
||||||
extern ConfigVariableDouble speedtree_cull_cell_size;
|
extern ConfigVariableDouble speedtree_cull_cell_size;
|
||||||
extern ConfigVariableDouble speedtree_area_scale;
|
extern ConfigVariableDouble speedtree_area_scale;
|
||||||
|
extern ConfigVariableBool speedtree_follow_terrain;
|
||||||
|
extern ConfigVariableInt speedtree_max_random_try_count;
|
||||||
extern ConfigVariableBool speedtree_5_2_stf;
|
extern ConfigVariableBool speedtree_5_2_stf;
|
||||||
|
|
||||||
extern EXPCL_PANDASPEEDTREE void init_libspeedtree();
|
extern EXPCL_PANDASPEEDTREE void init_libspeedtree();
|
||||||
|
@ -291,7 +291,13 @@ modify_instance_list(const STTree *tree) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void SpeedTreeNode::
|
void SpeedTreeNode::
|
||||||
add_instance(const STTree *tree, const STTransform &transform) {
|
add_instance(const STTree *tree, const STTransform &transform) {
|
||||||
add_tree(tree).add_instance(transform);
|
if (speedtree_follow_terrain && has_terrain()) {
|
||||||
|
STTransform new_transform = transform;
|
||||||
|
new_transform._pos[2] = _terrain->get_height(new_transform._pos[0], new_transform._pos[1]);
|
||||||
|
add_tree(tree).add_instance(new_transform);
|
||||||
|
} else {
|
||||||
|
add_tree(tree).add_instance(transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -353,11 +359,71 @@ add_instances_from(const SpeedTreeNode *other, const TransformState *transform)
|
|||||||
for (int i = 0; i < num_instances; ++i) {
|
for (int i = 0; i < num_instances; ++i) {
|
||||||
CPT(TransformState) other_trans = other_instance_list.get_instance(i);
|
CPT(TransformState) other_trans = other_instance_list.get_instance(i);
|
||||||
CPT(TransformState) new_trans = transform->compose(other_trans);
|
CPT(TransformState) new_trans = transform->compose(other_trans);
|
||||||
this_instance_list.add_instance(new_trans.p());
|
|
||||||
|
if (speedtree_follow_terrain && has_terrain()) {
|
||||||
|
STTransform new_transform = new_trans;
|
||||||
|
new_transform._pos[2] = _terrain->get_height(new_transform._pos[0], new_transform._pos[1]);
|
||||||
|
this_instance_list.add_instance(new_transform);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this_instance_list.add_instance(new_trans.p());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SpeedTreeNode::add_random_instances
|
||||||
|
// Access: Published
|
||||||
|
// Description: Creates a number of random instances of the indicated
|
||||||
|
// true, within the indicated range. If a terrain is
|
||||||
|
// present, height_min and height_max restrict trees to
|
||||||
|
// the (x, y) positions that fall within the indicated
|
||||||
|
// terrain, and slope_min and slope_max restrict trees
|
||||||
|
// to the (x, y) positions that have a matching slope.
|
||||||
|
// If a terrain is not present, height_min and
|
||||||
|
// height_max specify a random range of Z heights, and
|
||||||
|
// slope_min and slope_max are ignored.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void SpeedTreeNode::
|
||||||
|
add_random_instances(const STTree *tree, int quantity,
|
||||||
|
float x_min, float x_max,
|
||||||
|
float y_min, float y_max,
|
||||||
|
float scale_min, float scale_max,
|
||||||
|
float height_min, float height_max,
|
||||||
|
float slope_min, float slope_max,
|
||||||
|
Randomizer &randomizer) {
|
||||||
|
InstanceList &instance_list = add_tree(tree);
|
||||||
|
_needs_repopulate = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < quantity; ++i) {
|
||||||
|
STTransform transform;
|
||||||
|
transform._pos[0] = randomizer.random_real(x_max - x_min) + x_min;
|
||||||
|
transform._pos[1] = randomizer.random_real(y_max - y_min) + y_min;
|
||||||
|
transform._rotate = randomizer.random_real(360.0);
|
||||||
|
transform._scale = randomizer.random_real(scale_max - scale_min) + scale_min;
|
||||||
|
|
||||||
|
if (has_terrain()) {
|
||||||
|
// Spin till we find a valid match with terrain.
|
||||||
|
int repeat_count = speedtree_max_random_try_count;
|
||||||
|
while (!_terrain->placement_is_acceptable(transform._pos[0], transform._pos[1], height_min, height_max, slope_min, slope_max)) {
|
||||||
|
transform._pos[0] = randomizer.random_real(x_max - x_min) + x_min;
|
||||||
|
transform._pos[1] = randomizer.random_real(y_max - y_min) + y_min;
|
||||||
|
if (--repeat_count == 0) {
|
||||||
|
nassert_raise("Exceeded speedtree-max-random-try-count; bad placement parameters?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transform._pos[2] = _terrain->get_height(transform._pos[0], transform._pos[1]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// No terrain; just pick a random height.
|
||||||
|
transform._pos[2] = randomizer.random_real(height_max - height_min) + height_min;
|
||||||
|
}
|
||||||
|
instance_list.add_instance(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: SpeedTreeNode::add_from_stf
|
// Function: SpeedTreeNode::add_from_stf
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -472,8 +538,8 @@ add_from_stf(istream &in, const Filename &pathname,
|
|||||||
if (!speedtree_5_2_stf) {
|
if (!speedtree_5_2_stf) {
|
||||||
// 5.1 or earlier stf files also included these additional
|
// 5.1 or earlier stf files also included these additional
|
||||||
// values, which we will ignore:
|
// values, which we will ignore:
|
||||||
float elev_min, elev_max, slope_min, slope_max;
|
float height_min, height_max, slope_min, slope_max;
|
||||||
in >> elev_min >> elev_max >> slope_min >> slope_max;
|
in >> height_min >> height_max >> slope_min >> slope_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tree != NULL) {
|
if (tree != NULL) {
|
||||||
@ -576,6 +642,10 @@ set_terrain(STTerrain *terrain) {
|
|||||||
_terrain_render.SetRenderInfo(trender_info);
|
_terrain_render.SetRenderInfo(trender_info);
|
||||||
|
|
||||||
_terrain_render.SetHeightHints(terrain->get_min_height(), terrain->get_max_height());
|
_terrain_render.SetHeightHints(terrain->get_min_height(), terrain->get_max_height());
|
||||||
|
|
||||||
|
if (speedtree_follow_terrain) {
|
||||||
|
snap_to_terrain();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -655,12 +725,12 @@ reload_config() {
|
|||||||
render_info.m_bDetailNormalMapping = speedtree_detail_normal_mapping;
|
render_info.m_bDetailNormalMapping = speedtree_detail_normal_mapping;
|
||||||
render_info.m_bAmbientContrast = speedtree_ambient_contrast;
|
render_info.m_bAmbientContrast = speedtree_ambient_contrast;
|
||||||
render_info.m_fTransmissionScalar = speedtree_transmission_scalar;
|
render_info.m_fTransmissionScalar = speedtree_transmission_scalar;
|
||||||
render_info.m_fFogStartDistance = speedtree_fog_start_distance;
|
render_info.m_fFogStartDistance = speedtree_fog_distance[0];
|
||||||
render_info.m_fFogEndDistance = speedtree_fog_end_distance;
|
render_info.m_fFogEndDistance = speedtree_fog_distance[1];
|
||||||
render_info.m_vFogColor = SpeedTree::Vec3(speedtree_fog_color[0], speedtree_fog_color[1], speedtree_fog_color[2]);
|
render_info.m_vFogColor = SpeedTree::Vec3(speedtree_fog_color[0], speedtree_fog_color[1], speedtree_fog_color[2]);
|
||||||
render_info.m_vSkyColor = SpeedTree::Vec3(speedtree_sky_color[0], speedtree_sky_color[1], speedtree_sky_color[2]);
|
render_info.m_vSkyColor = SpeedTree::Vec3(speedtree_sky_color[0], speedtree_sky_color[1], speedtree_sky_color[2]);
|
||||||
render_info.m_fSkyFogMin = speedtree_sky_fog_min;
|
render_info.m_fSkyFogMin = speedtree_sky_fog[0];
|
||||||
render_info.m_fSkyFogMax = speedtree_sky_fog_max;
|
render_info.m_fSkyFogMax = speedtree_sky_fog[1];
|
||||||
render_info.m_vSunColor = SpeedTree::Vec3(speedtree_sun_color[0], speedtree_sun_color[1], speedtree_sun_color[2]);
|
render_info.m_vSunColor = SpeedTree::Vec3(speedtree_sun_color[0], speedtree_sun_color[1], speedtree_sun_color[2]);
|
||||||
render_info.m_fSunSize = speedtree_sun_size;
|
render_info.m_fSunSize = speedtree_sun_size;
|
||||||
render_info.m_fSunSpreadExponent = speedtree_sun_spread_exponent;
|
render_info.m_fSunSpreadExponent = speedtree_sun_spread_exponent;
|
||||||
@ -1445,9 +1515,9 @@ draw_callback(CallbackData *data) {
|
|||||||
PStatTimer timer1(_draw_speedtree_trees_pcollector);
|
PStatTimer timer1(_draw_speedtree_trees_pcollector);
|
||||||
|
|
||||||
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
|
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
|
||||||
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
|
SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
|
||||||
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
|
//SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
|
||||||
SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
|
//SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
|
||||||
set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
|
set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
|
||||||
|
|
||||||
bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
|
bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "transformState.h"
|
#include "transformState.h"
|
||||||
#include "nodePath.h"
|
#include "nodePath.h"
|
||||||
#include "pStatCollector.h"
|
#include "pStatCollector.h"
|
||||||
|
#include "randomizer.h"
|
||||||
#include "speedtree_api.h"
|
#include "speedtree_api.h"
|
||||||
|
|
||||||
class Loader;
|
class Loader;
|
||||||
@ -115,6 +116,14 @@ PUBLISHED:
|
|||||||
void add_instances(const NodePath &root, const TransformState *transform = TransformState::make_identity());
|
void add_instances(const NodePath &root, const TransformState *transform = TransformState::make_identity());
|
||||||
void add_instances_from(const SpeedTreeNode *other);
|
void add_instances_from(const SpeedTreeNode *other);
|
||||||
void add_instances_from(const SpeedTreeNode *other, const TransformState *transform);
|
void add_instances_from(const SpeedTreeNode *other, const TransformState *transform);
|
||||||
|
void add_random_instances(const STTree *tree, int quantity,
|
||||||
|
float x_min, float x_max,
|
||||||
|
float y_min, float y_max,
|
||||||
|
float scale_min, float scale_max,
|
||||||
|
float height_min, float height_max,
|
||||||
|
float slope_min, float slope_max,
|
||||||
|
Randomizer &randomizer = Randomizer());
|
||||||
|
|
||||||
bool add_from_stf(const Filename &stf_filename,
|
bool add_from_stf(const Filename &stf_filename,
|
||||||
const LoaderOptions &options = LoaderOptions());
|
const LoaderOptions &options = LoaderOptions());
|
||||||
bool add_from_stf(istream &in, const Filename &pathname,
|
bool add_from_stf(istream &in, const Filename &pathname,
|
||||||
|
@ -51,6 +51,17 @@ get_size() const {
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: STBasicTerrain::interpolate
|
||||||
|
// Access: Protected, Static
|
||||||
|
// Description: Convenience function to calculate the linear
|
||||||
|
// interpolation from A to B.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float STBasicTerrain::
|
||||||
|
interpolate(float a, float b, float t) {
|
||||||
|
return (a + (b - a) * t);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: STBasicTerrain::InterpolationData::Constructor
|
// Function: STBasicTerrain::InterpolationData::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -103,8 +114,6 @@ ValueType STBasicTerrain::InterpolationData<ValueType>::
|
|||||||
calc_bilinear_interpolation(float u, float v) const {
|
calc_bilinear_interpolation(float u, float v) const {
|
||||||
u -= cfloor(u);
|
u -= cfloor(u);
|
||||||
v -= cfloor(v);
|
v -= cfloor(v);
|
||||||
nassertr((u >= 0.0f) && (u < 1.0f) &&
|
|
||||||
(v >= 0.0f) && (v < 1.0f), 0);
|
|
||||||
|
|
||||||
u *= (float)_width;
|
u *= (float)_width;
|
||||||
v *= (float)_height;
|
v *= (float)_height;
|
||||||
|
@ -297,7 +297,7 @@ get_smooth_height(float x, float y, float radius) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
float STBasicTerrain::
|
float STBasicTerrain::
|
||||||
get_slope(float x, float y) const {
|
get_slope(float x, float y) const {
|
||||||
return 0.0f;
|
return _slope_data.calc_bilinear_interpolation(x / _size, y / _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -395,9 +395,101 @@ read_height_map() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compute_slope(0.5f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: STBasicTerrain::compute_slope
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Once _height_data has been filled in, compute the
|
||||||
|
// corresponding values for _slope_data.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void STBasicTerrain::
|
||||||
|
compute_slope(float smoothing) {
|
||||||
|
nassertv(!_height_data._data.empty());
|
||||||
|
|
||||||
|
int width = _height_data._width;
|
||||||
|
int height = _height_data._height;
|
||||||
|
_slope_data.reset(width, height);
|
||||||
|
|
||||||
|
float u_spacing = _size / (float)width;
|
||||||
|
float v_spacing = _size / (float)height;
|
||||||
|
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
int left = (i + width - 1) % width;
|
||||||
|
int right = (i + 1) % width;
|
||||||
|
|
||||||
|
for (int j = 0; j < height; ++j) {
|
||||||
|
int top = (j + height - 1) % height;
|
||||||
|
int bottom = (j + 1) % height;
|
||||||
|
|
||||||
|
float slope = 0.0f;
|
||||||
|
float this_height = _height_data._data[i + j * width];
|
||||||
|
slope += catan2(cabs(this_height - _height_data._data[right + j * width]), u_spacing);
|
||||||
|
slope += catan2(cabs(this_height - _height_data._data[left + j * width]), u_spacing);
|
||||||
|
slope += catan2(cabs(this_height - _height_data._data[i + top * width]), v_spacing);
|
||||||
|
slope += catan2(cabs(this_height - _height_data._data[i + bottom * width]), v_spacing);
|
||||||
|
|
||||||
|
slope *= (0.5f / MathNumbers::pi_f);
|
||||||
|
|
||||||
|
if (slope > 1.0f) {
|
||||||
|
slope = 1.0f;
|
||||||
|
}
|
||||||
|
_slope_data._data[i + j * width] = slope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smoothing > 0.0f) {
|
||||||
|
// Create a temporary array for smoothing data.
|
||||||
|
InterpolationData<float> smoothing_data;
|
||||||
|
smoothing_data.reset(width, height);
|
||||||
|
float *smoothed = &smoothing_data._data[0];
|
||||||
|
|
||||||
|
int steps = int(smoothing);
|
||||||
|
float last_interpolation = smoothing - steps;
|
||||||
|
++steps;
|
||||||
|
for (int si = 0; si < steps; ++si) {
|
||||||
|
|
||||||
|
// compute smoothed normals
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
int left = (i + width - 1) % width;
|
||||||
|
int right = (i + 1) % width;
|
||||||
|
|
||||||
|
for (int j = 0; j < height; ++j) {
|
||||||
|
int top = (j + height - 1) % height;
|
||||||
|
int bottom = (j + 1) % height;
|
||||||
|
|
||||||
|
smoothed[i + j * width] = (_slope_data._data[right + j * width] +
|
||||||
|
_slope_data._data[left + j * width] +
|
||||||
|
_slope_data._data[i + top * width] +
|
||||||
|
_slope_data._data[i + bottom * width] +
|
||||||
|
_slope_data._data[right + top * width] +
|
||||||
|
_slope_data._data[right + bottom * width] +
|
||||||
|
_slope_data._data[left + top * width] +
|
||||||
|
_slope_data._data[left + bottom * width]);
|
||||||
|
smoothed[i + j * width] *= 0.125f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolate or set
|
||||||
|
if (si == steps - 1) {
|
||||||
|
// last step, interpolate
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
for (int j = 0; j < height; ++j) {
|
||||||
|
_slope_data._data[i + j * width] = interpolate(_slope_data._data[i + j * width], smoothed[i + j * width], last_interpolation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// full smoothing step, copy everything
|
||||||
|
_slope_data = smoothing_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: STBasicTerrain::read_quoted_filename
|
// Function: STBasicTerrain::read_quoted_filename
|
||||||
// Access: Private, Static
|
// Access: Private, Static
|
||||||
|
@ -57,6 +57,9 @@ PUBLISHED:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool read_height_map();
|
bool read_height_map();
|
||||||
|
void compute_slope(float smoothing);
|
||||||
|
|
||||||
|
INLINE float interpolate(float a, float b, float t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void read_quoted_filename(Filename &result, istream &in,
|
static void read_quoted_filename(Filename &result, istream &in,
|
||||||
|
@ -129,6 +129,29 @@ get_slope(float x, float y) const {
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: STTerrain::placement_is_acceptable
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the elevation and slope of point (x,
|
||||||
|
// y) fall within the requested limits, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool STTerrain::
|
||||||
|
placement_is_acceptable(float x, float y,
|
||||||
|
float height_min, float height_max,
|
||||||
|
float slope_min, float slope_max) {
|
||||||
|
float height = get_height(x, y);
|
||||||
|
if (height < height_min || height > height_max) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float slope = get_slope(x, y);
|
||||||
|
if (slope < slope_min || slope > slope_max) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: STTerrain::fill_vertices
|
// Function: STTerrain::fill_vertices
|
||||||
// Access: Published, Virtual
|
// Access: Published, Virtual
|
||||||
|
@ -65,6 +65,10 @@ PUBLISHED:
|
|||||||
virtual float get_smooth_height(float x, float y, float radius) const;
|
virtual float get_smooth_height(float x, float y, float radius) const;
|
||||||
virtual float get_slope(float x, float y) const;
|
virtual float get_slope(float x, float y) const;
|
||||||
|
|
||||||
|
bool placement_is_acceptable(float x, float y,
|
||||||
|
float height_min, float height_max,
|
||||||
|
float slope_min, float slope_max);
|
||||||
|
|
||||||
virtual void fill_vertices(GeomVertexData *data,
|
virtual void fill_vertices(GeomVertexData *data,
|
||||||
float start_x, float start_y,
|
float start_x, float start_y,
|
||||||
float size_xy, int num_xy) const;
|
float size_xy, int num_xy) const;
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
void write_datagram(BamWriter *manager, Datagram &dg);
|
void write_datagram(BamWriter *manager, Datagram &dg);
|
||||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
LPoint3f _pos;
|
LPoint3f _pos;
|
||||||
float _rotate;
|
float _rotate;
|
||||||
float _scale;
|
float _scale;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user