mirror of
https://github.com/beestat/app.git
synced 2026-02-26 05:00:21 -05:00
Weather
This commit is contained in:
parent
3d31831408
commit
161f5bb27c
@ -163,10 +163,12 @@ beestat.component.card.three_d.prototype.decorate_contents_ = function(parent) {
|
||||
const scene_settings_container = document.createElement('div');
|
||||
Object.assign(scene_settings_container.style, {
|
||||
'position': 'absolute',
|
||||
'top': `${beestat.style.size.gutter + 72}px`,
|
||||
'top': `${beestat.style.size.gutter + 52}px`,
|
||||
'right': `${beestat.style.size.gutter}px`,
|
||||
'min-width': '220px',
|
||||
'max-width': '250px',
|
||||
'height': '375px',
|
||||
'overflow-y': 'auto',
|
||||
'z-index': 2
|
||||
});
|
||||
parent.appendChild(scene_settings_container);
|
||||
@ -581,26 +583,30 @@ beestat.component.card.three_d.prototype.get_weather_settings_from_mode_ = funct
|
||||
return {
|
||||
'cloud_density': 0.5,
|
||||
'rain_density': 0,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 2
|
||||
};
|
||||
case 'raining':
|
||||
return {
|
||||
'cloud_density': 1,
|
||||
'rain_density': 1,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 2
|
||||
};
|
||||
case 'snowing':
|
||||
return {
|
||||
'cloud_density': 1,
|
||||
'rain_density': 0,
|
||||
'snow_density': 1
|
||||
'snow_density': 1,
|
||||
'wind_speed': 1
|
||||
};
|
||||
case 'sunny':
|
||||
default:
|
||||
return {
|
||||
'cloud_density': 0,
|
||||
'cloud_density': 0.03,
|
||||
'rain_density': 0,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 1
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -803,21 +809,41 @@ beestat.component.card.three_d.prototype.decorate_scene_settings_panel_ = functi
|
||||
});
|
||||
panel.appendChild(separator);
|
||||
};
|
||||
const add_section_title = (title) => {
|
||||
const heading = document.createElement('div');
|
||||
Object.assign(heading.style, {
|
||||
'font-size': '11px',
|
||||
'letter-spacing': '0.06em',
|
||||
'text-transform': 'uppercase',
|
||||
'color': 'rgba(255,255,255,0.75)',
|
||||
'margin-top': '2px'
|
||||
});
|
||||
heading.innerText = title;
|
||||
panel.appendChild(heading);
|
||||
};
|
||||
|
||||
// Weather
|
||||
add_section_title('Weather');
|
||||
add_number_setting(get_title_case_label('cloud_density'), 'cloud_density', 0, 2, 0.1);
|
||||
add_number_setting(get_title_case_label('rain_density'), 'rain_density', 0, 2, 0.1);
|
||||
add_number_setting(get_title_case_label('snow_density'), 'snow_density', 0, 2, 0.1);
|
||||
add_number_setting(get_title_case_label('wind_speed'), 'wind_speed', 0, 2, 0.1);
|
||||
|
||||
add_separator();
|
||||
add_section_title('Wind');
|
||||
add_number_setting(get_title_case_label('wind_speed'), 'wind_speed', 0, 5, 0.1);
|
||||
add_number_setting(get_title_case_label('wind_direction'), 'wind_direction', 0, 360, 1);
|
||||
|
||||
add_separator();
|
||||
|
||||
// Tree
|
||||
add_section_title('Tree');
|
||||
add_boolean_setting(get_title_case_label('tree_enabled'), 'tree_enabled');
|
||||
add_boolean_setting(get_title_case_label('tree_wobble'), 'tree_wobble');
|
||||
|
||||
add_separator();
|
||||
|
||||
// Light / Sky
|
||||
add_section_title('Light / Sky');
|
||||
add_number_setting(get_title_case_label('star_density'), 'star_density', 0, 2, 0.1);
|
||||
add_boolean_setting(get_title_case_label('light_user_enabled'), 'light_user_enabled');
|
||||
this.update_fps_visibility_();
|
||||
|
||||
@ -74,7 +74,7 @@ beestat.component.scene.environment_padding = 400;
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
beestat.component.scene.weather_rain_max_count = 2200;
|
||||
beestat.component.scene.weather_rain_max_count = 1100;
|
||||
|
||||
/**
|
||||
* Maximum snow particle count at full snow intensity.
|
||||
@ -278,6 +278,8 @@ beestat.component.scene.star_drift_visual_factor = 0.12;
|
||||
* rain_density: number,
|
||||
* snow_density: number,
|
||||
* wind_speed: number,
|
||||
* wind_direction: number,
|
||||
* tree_wobble: boolean,
|
||||
* tree_enabled: boolean,
|
||||
* star_density: number,
|
||||
* light_user_enabled: boolean,
|
||||
@ -289,6 +291,8 @@ beestat.component.scene.default_settings = {
|
||||
'rain_density': 1,
|
||||
'snow_density': 1,
|
||||
'wind_speed': 1,
|
||||
'wind_direction': 0,
|
||||
'tree_wobble': true,
|
||||
'tree_enabled': true,
|
||||
'star_density': 1,
|
||||
'light_user_enabled': true,
|
||||
@ -495,6 +499,7 @@ beestat.component.scene.prototype.reset_runtime_scene_references_for_rerender_ =
|
||||
this.light_sources_ = [];
|
||||
this.tree_foliage_meshes_ = [];
|
||||
this.tree_branch_groups_ = [];
|
||||
this.tree_wind_meshes_ = [];
|
||||
|
||||
delete this.floor_plan_group_;
|
||||
delete this.environment_group_;
|
||||
@ -699,6 +704,7 @@ beestat.component.scene.prototype.decorate_ = function(parent) {
|
||||
self.controls_.update();
|
||||
self.update_raycaster_();
|
||||
self.update_celestial_light_intensities_();
|
||||
self.update_tree_wind_();
|
||||
self.update_weather_();
|
||||
self.renderer_.render(self.scene_, self.camera_);
|
||||
};
|
||||
|
||||
@ -138,25 +138,31 @@ beestat.component.scene.prototype.create_snow_particle_texture_ = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Create a streak-like particle texture for rain.
|
||||
* Create a soft circular particle texture for rain.
|
||||
*
|
||||
* @return {THREE.Texture}
|
||||
*/
|
||||
beestat.component.scene.prototype.create_rain_particle_texture_ = function() {
|
||||
const width = 24;
|
||||
const height = 64;
|
||||
const width = 56;
|
||||
const height = 56;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
const context = canvas.getContext('2d');
|
||||
const gradient = context.createLinearGradient(0, 0, 0, height);
|
||||
gradient.addColorStop(0.0, 'rgba(170, 200, 255, 0.0)');
|
||||
gradient.addColorStop(0.25, 'rgba(185, 210, 255, 0.85)');
|
||||
gradient.addColorStop(1.0, 'rgba(170, 200, 255, 0.0)');
|
||||
|
||||
const gradient = context.createRadialGradient(
|
||||
width / 2,
|
||||
height / 2,
|
||||
0,
|
||||
width / 2,
|
||||
height / 2,
|
||||
width * 0.5
|
||||
);
|
||||
gradient.addColorStop(0.0, 'rgba(195, 218, 255, 0.95)');
|
||||
gradient.addColorStop(0.55, 'rgba(175, 205, 255, 0.55)');
|
||||
gradient.addColorStop(1.0, 'rgba(165, 198, 255, 0.0)');
|
||||
context.fillStyle = gradient;
|
||||
context.fillRect(width / 2 - 2, 0, 4, height);
|
||||
context.fillRect(0, 0, width, height);
|
||||
|
||||
const texture = new THREE.CanvasTexture(canvas);
|
||||
texture.needsUpdate = true;
|
||||
|
||||
@ -2,6 +2,154 @@
|
||||
* Scene methods split from scene.js.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register a tree mesh for procedural wind bending.
|
||||
*
|
||||
* @param {THREE.Mesh} mesh
|
||||
* @param {{stiffness:number, max_sway_ratio:number}=} options
|
||||
*/
|
||||
beestat.component.scene.prototype.register_tree_wind_mesh_ = function(mesh, options) {
|
||||
if (
|
||||
mesh === undefined ||
|
||||
mesh.geometry === undefined ||
|
||||
mesh.geometry.attributes === undefined ||
|
||||
mesh.geometry.attributes.position === undefined
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const position_attribute = mesh.geometry.attributes.position;
|
||||
const source_positions = position_attribute.array;
|
||||
if (source_positions === undefined || source_positions.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.tree_wind_meshes_ === undefined) {
|
||||
this.tree_wind_meshes_ = [];
|
||||
}
|
||||
|
||||
const count = position_attribute.count;
|
||||
const base_positions = new Float32Array(source_positions.length);
|
||||
base_positions.set(source_positions);
|
||||
const weights = new Float32Array(count);
|
||||
const phase_offsets = new Float32Array(count);
|
||||
|
||||
const mesh_offset_z = Number(mesh.position !== undefined ? mesh.position.z : 0);
|
||||
let min_world_z = Infinity;
|
||||
let max_world_z = -Infinity;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const world_z = base_positions[(i * 3) + 2] + mesh_offset_z;
|
||||
min_world_z = Math.min(min_world_z, world_z);
|
||||
max_world_z = Math.max(max_world_z, world_z);
|
||||
}
|
||||
const height = Math.max(0.0001, max_world_z - min_world_z);
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const offset = i * 3;
|
||||
const x = base_positions[offset];
|
||||
const y = base_positions[offset + 1];
|
||||
const world_z = base_positions[offset + 2] + mesh_offset_z;
|
||||
const height_ratio = (max_world_z - world_z) / height;
|
||||
const clamped_ratio = Math.max(0, Math.min(1, height_ratio));
|
||||
|
||||
// Keep trunk/branch bases anchored and increase bending toward tips.
|
||||
weights[i] = Math.pow(clamped_ratio, 1.75);
|
||||
phase_offsets[i] = ((x * 0.02) + (y * 0.015)) * 0.4;
|
||||
}
|
||||
|
||||
const resolved_options = options || {};
|
||||
const stiffness = Math.max(0.1, Number(resolved_options.stiffness || 1));
|
||||
const max_sway_ratio = Math.max(
|
||||
0,
|
||||
Number(resolved_options.max_sway_ratio === undefined ? 0.03 : resolved_options.max_sway_ratio)
|
||||
);
|
||||
|
||||
this.tree_wind_meshes_.push({
|
||||
'mesh': mesh,
|
||||
'base_positions': base_positions,
|
||||
'weights': weights,
|
||||
'phase_offsets': phase_offsets,
|
||||
'height': height,
|
||||
'stiffness': stiffness,
|
||||
'max_sway_ratio': max_sway_ratio,
|
||||
'phase_seed': Math.random() * Math.PI * 2
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update tree vertex sway for current wind speed.
|
||||
* Wind direction is single-axis to keep motion physically directional.
|
||||
*/
|
||||
beestat.component.scene.prototype.update_tree_wind_ = function() {
|
||||
if (this.tree_wind_meshes_ === undefined || this.tree_wind_meshes_.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const wind_speed = Math.max(0, Math.min(5, Number(this.get_scene_setting_('wind_speed') || 0)));
|
||||
const wind_direction = Math.max(0, Math.min(360, Number(this.get_scene_setting_('wind_direction') || 0)));
|
||||
const tree_wobble_enabled = this.get_scene_setting_('tree_wobble') !== false;
|
||||
// Keep overall tree effect lower than prior tuning while preserving responsiveness.
|
||||
const wind_strength = wind_speed * 0.5;
|
||||
const time_seconds = window.performance.now() / 1000;
|
||||
const wind_radians = THREE.MathUtils.degToRad(wind_direction);
|
||||
const wind_direction_x = Math.cos(wind_radians);
|
||||
const wind_direction_y = Math.sin(wind_radians);
|
||||
const gust = 0.78 + (0.22 * Math.sin(time_seconds * 0.16));
|
||||
|
||||
for (let i = 0; i < this.tree_wind_meshes_.length; i++) {
|
||||
const wind_mesh = this.tree_wind_meshes_[i];
|
||||
const mesh = wind_mesh.mesh;
|
||||
if (
|
||||
mesh === undefined ||
|
||||
mesh.geometry === undefined ||
|
||||
mesh.geometry.attributes === undefined ||
|
||||
mesh.geometry.attributes.position === undefined
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const position_attribute = mesh.geometry.attributes.position;
|
||||
const positions = position_attribute.array;
|
||||
const base_positions = wind_mesh.base_positions;
|
||||
const weights = wind_mesh.weights;
|
||||
const phase_offsets = wind_mesh.phase_offsets;
|
||||
const count = position_attribute.count;
|
||||
|
||||
if (tree_wobble_enabled !== true || wind_strength <= 0) {
|
||||
for (let vertex_index = 0; vertex_index < count; vertex_index++) {
|
||||
const offset = vertex_index * 3;
|
||||
positions[offset] = base_positions[offset];
|
||||
positions[offset + 1] = base_positions[offset + 1];
|
||||
positions[offset + 2] = base_positions[offset + 2];
|
||||
}
|
||||
position_attribute.needsUpdate = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
const max_sway = wind_mesh.height * wind_mesh.max_sway_ratio * (wind_strength / wind_mesh.stiffness);
|
||||
const steady_lean = max_sway * 0.28;
|
||||
const oscillation_strength = max_sway * (0.58 + (0.24 * gust));
|
||||
const frequency = (0.75 + (wind_strength * 0.42)) / Math.max(0.25, wind_mesh.stiffness);
|
||||
|
||||
for (let vertex_index = 0; vertex_index < count; vertex_index++) {
|
||||
const offset = vertex_index * 3;
|
||||
const weight = weights[vertex_index];
|
||||
const phase = (time_seconds * frequency) + wind_mesh.phase_seed + phase_offsets[vertex_index];
|
||||
const oscillation =
|
||||
Math.sin(phase) +
|
||||
(Math.sin((phase * 2.1) + 0.6) * 0.25);
|
||||
const along_wind = (steady_lean + (oscillation * oscillation_strength)) * weight;
|
||||
|
||||
positions[offset] = base_positions[offset] + (wind_direction_x * along_wind);
|
||||
positions[offset + 1] = base_positions[offset + 1] + (wind_direction_y * along_wind);
|
||||
positions[offset + 2] = base_positions[offset + 2];
|
||||
}
|
||||
|
||||
position_attribute.needsUpdate = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Build a radial alpha texture used for soft tree-ground contact decals.
|
||||
@ -156,6 +304,10 @@ beestat.component.scene.prototype.create_conical_tree_ = function(height, max_di
|
||||
trunk.receiveShadow = true;
|
||||
trunk.userData.is_environment = true;
|
||||
tree.add(trunk);
|
||||
this.register_tree_wind_mesh_(trunk, {
|
||||
'stiffness': 2.4,
|
||||
'max_sway_ratio': 0.01
|
||||
});
|
||||
this.add_tree_ground_contact_(tree, trunk_radius_bottom, 0x5d4226);
|
||||
|
||||
if (has_foliage === false) {
|
||||
@ -247,6 +399,10 @@ beestat.component.scene.prototype.create_conical_tree_ = function(height, max_di
|
||||
foliage_mesh.userData.is_tree_foliage = true;
|
||||
foliage_mesh.userData.base_tree_foliage_color = foliage_mesh.material.color.getHex();
|
||||
tree.add(foliage_mesh);
|
||||
this.register_tree_wind_mesh_(foliage_mesh, {
|
||||
'stiffness': 1.1,
|
||||
'max_sway_ratio': 0.045
|
||||
});
|
||||
|
||||
previous_apex_height = segment_base_height + segment_height;
|
||||
previous_radius = radius;
|
||||
@ -502,6 +658,10 @@ beestat.component.scene.prototype.create_round_tree_ = function(height, max_diam
|
||||
const trunk = trunk_stick.mesh;
|
||||
trunk.position.z = -(trunk_height / 2) + Math.max(0.7, trunk_radius_bottom * 0.14);
|
||||
tree.add(trunk);
|
||||
this.register_tree_wind_mesh_(trunk, {
|
||||
'stiffness': 2.2,
|
||||
'max_sway_ratio': 0.012
|
||||
});
|
||||
this.add_tree_ground_contact_(tree, trunk_radius_bottom, 0x6a4d2f);
|
||||
|
||||
// Single branch layer: starts halfway up trunk and thins/shortens toward the top.
|
||||
@ -767,6 +927,10 @@ beestat.component.scene.prototype.create_round_tree_ = function(height, max_diam
|
||||
branch.quaternion.setFromUnitVectors(branch_axis, direction);
|
||||
branches.add(branch);
|
||||
branch.updateMatrixWorld(true);
|
||||
self.register_tree_wind_mesh_(branch, {
|
||||
'stiffness': 1.7,
|
||||
'max_sway_ratio': 0.02
|
||||
});
|
||||
|
||||
return {
|
||||
'mesh': branch,
|
||||
@ -860,6 +1024,10 @@ beestat.component.scene.prototype.create_round_tree_ = function(height, max_diam
|
||||
canopy_mesh.userData.is_environment = true;
|
||||
foliage.add(canopy_mesh);
|
||||
this.tree_foliage_meshes_.push(canopy_mesh);
|
||||
this.register_tree_wind_mesh_(canopy_mesh, {
|
||||
'stiffness': 1.0,
|
||||
'max_sway_ratio': 0.04
|
||||
});
|
||||
}
|
||||
|
||||
if (has_foliage === true) {
|
||||
|
||||
@ -24,30 +24,34 @@ beestat.component.scene.prototype.set_weather = function(weather) {
|
||||
weather_settings = {
|
||||
'cloud_density': 1,
|
||||
'rain_density': 0,
|
||||
'snow_density': 1
|
||||
'snow_density': 1,
|
||||
'wind_speed': 1
|
||||
};
|
||||
break;
|
||||
case 'rain':
|
||||
weather_settings = {
|
||||
'cloud_density': 1,
|
||||
'rain_density': 1,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 2
|
||||
};
|
||||
break;
|
||||
case 'cloudy':
|
||||
weather_settings = {
|
||||
'cloud_density': 0.5,
|
||||
'rain_density': 0,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 2
|
||||
};
|
||||
break;
|
||||
case 'sunny':
|
||||
case 'none':
|
||||
default:
|
||||
weather_settings = {
|
||||
'cloud_density': 0,
|
||||
'cloud_density': 0.03,
|
||||
'rain_density': 0,
|
||||
'snow_density': 0
|
||||
'snow_density': 0,
|
||||
'wind_speed': 1
|
||||
};
|
||||
break;
|
||||
}
|
||||
@ -329,7 +333,11 @@ beestat.component.scene.prototype.create_precipitation_system_ = function(bounds
|
||||
'drift_x': drift_x,
|
||||
'drift_y': drift_y,
|
||||
'max_count': max_count,
|
||||
'target_opacity': config.opacity
|
||||
'target_opacity': config.opacity,
|
||||
'static_opacity': config.static_opacity === true,
|
||||
'max_wind_angle': config.max_wind_angle || 0,
|
||||
'max_wind_speed_scale': config.max_wind_speed_scale || 2,
|
||||
'wind_motion_multiplier': config.wind_motion_multiplier || 1
|
||||
};
|
||||
};
|
||||
|
||||
@ -340,8 +348,16 @@ beestat.component.scene.prototype.create_precipitation_system_ = function(bounds
|
||||
* @param {object} precipitation
|
||||
* @param {number} target_count
|
||||
* @param {number} delta_seconds
|
||||
* @param {number} wind_speed
|
||||
* @param {number} wind_direction
|
||||
*/
|
||||
beestat.component.scene.prototype.update_precipitation_system_ = function(precipitation, target_count, delta_seconds) {
|
||||
beestat.component.scene.prototype.update_precipitation_system_ = function(
|
||||
precipitation,
|
||||
target_count,
|
||||
delta_seconds,
|
||||
wind_speed,
|
||||
wind_direction
|
||||
) {
|
||||
if (
|
||||
precipitation === undefined ||
|
||||
precipitation.points === undefined ||
|
||||
@ -357,7 +373,9 @@ beestat.component.scene.prototype.update_precipitation_system_ = function(precip
|
||||
);
|
||||
precipitation.points.geometry.setDrawRange(0, clamped_count);
|
||||
|
||||
if (precipitation.max_count > 0) {
|
||||
if (precipitation.static_opacity === true) {
|
||||
precipitation.points.material.opacity = precipitation.target_opacity;
|
||||
} else if (precipitation.max_count > 0) {
|
||||
precipitation.points.material.opacity =
|
||||
precipitation.target_opacity * (clamped_count / precipitation.max_count);
|
||||
} else {
|
||||
@ -373,10 +391,32 @@ beestat.component.scene.prototype.update_precipitation_system_ = function(precip
|
||||
const span_y = bounds.max_y - bounds.min_y;
|
||||
const span_z = bounds.max_z - bounds.min_z;
|
||||
const positions = precipitation.points.geometry.attributes.position.array;
|
||||
const clamped_wind_speed = Math.max(0, Math.min(5, Number(wind_speed || 0)));
|
||||
const clamped_wind_direction = Math.max(0, Math.min(360, Number(wind_direction || 0)));
|
||||
const wind_direction_radians = THREE.MathUtils.degToRad(clamped_wind_direction);
|
||||
const wind_x = Math.cos(wind_direction_radians);
|
||||
const wind_y = Math.sin(wind_direction_radians);
|
||||
const max_wind_angle = Number(precipitation.max_wind_angle || 0);
|
||||
const wind_angle = (clamped_wind_speed / 5) * max_wind_angle;
|
||||
const wind_angle_radians = THREE.MathUtils.degToRad(wind_angle);
|
||||
const vertical_scale = Math.cos(wind_angle_radians);
|
||||
const horizontal_scale = Math.sin(wind_angle_radians);
|
||||
const max_wind_speed_scale = Math.max(
|
||||
1,
|
||||
Number(precipitation.max_wind_speed_scale || 2)
|
||||
);
|
||||
const wind_speed_scale = 1 + ((clamped_wind_speed / 5) * (max_wind_speed_scale - 1));
|
||||
const wind_motion_multiplier = Math.max(0, Number(precipitation.wind_motion_multiplier || 1));
|
||||
const direction_velocity_x = horizontal_scale * wind_x;
|
||||
const direction_velocity_y = horizontal_scale * wind_y;
|
||||
const direction_velocity_z = vertical_scale;
|
||||
|
||||
for (let i = 0; i < clamped_count; i++) {
|
||||
const offset = i * 3;
|
||||
positions[offset + 2] += precipitation.speeds[i] * delta_seconds;
|
||||
const speed = precipitation.speeds[i] * delta_seconds * wind_speed_scale * wind_motion_multiplier;
|
||||
positions[offset + 2] += speed * direction_velocity_z;
|
||||
positions[offset] += speed * direction_velocity_x;
|
||||
positions[offset + 1] += speed * direction_velocity_y;
|
||||
positions[offset] += precipitation.drift_x[i] * delta_seconds;
|
||||
positions[offset + 1] += precipitation.drift_y[i] * delta_seconds;
|
||||
|
||||
@ -407,11 +447,14 @@ beestat.component.scene.prototype.update_precipitation_system_ = function(precip
|
||||
*/
|
||||
beestat.component.scene.prototype.add_weather_ = function(center_x, center_y, plan_width, plan_height) {
|
||||
const padding = beestat.component.scene.environment_padding + 120;
|
||||
const weather_span_multiplier = 1.25;
|
||||
const weather_width = (plan_width + (padding * 2)) * weather_span_multiplier;
|
||||
const weather_height = (plan_height + (padding * 2)) * weather_span_multiplier;
|
||||
const bounds = {
|
||||
'min_x': center_x - ((plan_width + padding * 2) / 2),
|
||||
'max_x': center_x + ((plan_width + padding * 2) / 2),
|
||||
'min_y': center_y - ((plan_height + padding * 2) / 2),
|
||||
'max_y': center_y + ((plan_height + padding * 2) / 2),
|
||||
'min_x': center_x - (weather_width / 2),
|
||||
'max_x': center_x + (weather_width / 2),
|
||||
'min_y': center_y - (weather_height / 2),
|
||||
'max_y': center_y + (weather_height / 2),
|
||||
'min_z': -780,
|
||||
'max_z': 140
|
||||
};
|
||||
@ -508,11 +551,14 @@ beestat.component.scene.prototype.add_weather_ = function(center_x, center_y, pl
|
||||
{
|
||||
'size': 11,
|
||||
'color': 0xa8c7ff,
|
||||
'opacity': 0.7,
|
||||
'opacity': 0.5,
|
||||
'static_opacity': true,
|
||||
'speed_min': 280,
|
||||
'speed_max': 430,
|
||||
'drift': 28,
|
||||
'texture': this.rain_particle_texture_
|
||||
'texture': this.rain_particle_texture_,
|
||||
'max_wind_angle': 45,
|
||||
'max_wind_speed_scale': 2
|
||||
}
|
||||
);
|
||||
this.weather_group_.add(this.rain_particles_.points);
|
||||
@ -530,7 +576,10 @@ beestat.component.scene.prototype.add_weather_ = function(center_x, center_y, pl
|
||||
'speed_min': 18,
|
||||
'speed_max': 44,
|
||||
'drift': 12,
|
||||
'texture': this.snow_particle_texture_
|
||||
'texture': this.snow_particle_texture_,
|
||||
'max_wind_angle': 75,
|
||||
'max_wind_speed_scale': 3,
|
||||
'wind_motion_multiplier': 2.5
|
||||
}
|
||||
);
|
||||
this.weather_group_.add(this.snow_particles_.points);
|
||||
@ -562,6 +611,8 @@ beestat.component.scene.prototype.update_weather_ = function() {
|
||||
if (delta_seconds <= 0) {
|
||||
return;
|
||||
}
|
||||
const wind_speed = Math.max(0, Math.min(5, Number(this.get_scene_setting_('wind_speed') || 0)));
|
||||
const wind_direction = Math.max(0, Math.min(360, Number(this.get_scene_setting_('wind_direction') || 0)));
|
||||
|
||||
if (this.weather_profile_target_ === undefined) {
|
||||
this.update_weather_targets_();
|
||||
@ -653,8 +704,20 @@ beestat.component.scene.prototype.update_weather_ = function() {
|
||||
}
|
||||
}
|
||||
|
||||
this.update_precipitation_system_(this.rain_particles_, this.current_rain_count_, delta_seconds);
|
||||
this.update_precipitation_system_(this.snow_particles_, this.current_snow_count_, delta_seconds);
|
||||
this.update_precipitation_system_(
|
||||
this.rain_particles_,
|
||||
this.current_rain_count_,
|
||||
delta_seconds,
|
||||
wind_speed,
|
||||
wind_direction
|
||||
);
|
||||
this.update_precipitation_system_(
|
||||
this.snow_particles_,
|
||||
this.current_snow_count_,
|
||||
delta_seconds,
|
||||
wind_speed,
|
||||
wind_direction
|
||||
);
|
||||
this.update_snow_surface_colors_(this.get_snow_cover_blend_());
|
||||
|
||||
if (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user