Compare commits
1 Commits
day-night-
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
650000a79e |
@@ -1,283 +0,0 @@
|
|||||||
# Dynamic Sky System for Godot 4.6
|
|
||||||
|
|
||||||
A stylized dynamic sky system with day/night cycles, weather, clouds, and VFX.
|
|
||||||
|
|
||||||
## Setup Instructions
|
|
||||||
|
|
||||||
### Step 1: Open Project in Godot
|
|
||||||
1. Open your Godot 4.6 project
|
|
||||||
2. Wait for the editor to import all scripts (check the bottom progress bar)
|
|
||||||
3. If you see script errors, click **Project > Reload Current Project**
|
|
||||||
|
|
||||||
### Step 2: Add to Your Scene
|
|
||||||
1. Open the scene where you want the sky system
|
|
||||||
2. Drag `dynamic-sky/dynamic_sky.tscn` into your scene tree
|
|
||||||
3. Or right-click in the scene tree → **Instance Child Scene** → select `dynamic_sky.tscn`
|
|
||||||
|
|
||||||
### Step 3: Configure the Environment
|
|
||||||
The DynamicSky node auto-creates required children. To link an existing environment:
|
|
||||||
|
|
||||||
1. Select the **DynamicSky** node
|
|
||||||
2. In the Inspector, under **Environment**:
|
|
||||||
- Assign your existing `WorldEnvironment` node (or leave empty to auto-create)
|
|
||||||
- Assign existing `DirectionalLight3D` for sun/moon (or leave empty)
|
|
||||||
|
|
||||||
### Step 4: Generate Cloud Textures
|
|
||||||
Clouds need textures. Use the procedural generator:
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# In a tool script or _ready():
|
|
||||||
var cloud_tex = ProceduralCloudTexture.create_default_cloud_texture(1)
|
|
||||||
$DynamicSky/CloudSystem.layer_configs[0].texture = cloud_tex
|
|
||||||
```
|
|
||||||
|
|
||||||
Or assign existing cloud textures to each `CloudLayerConfig` in the Inspector.
|
|
||||||
|
|
||||||
### Step 5: Configure Shadow Texture
|
|
||||||
```gdscript
|
|
||||||
var shadow_tex = ProceduralCloudTexture.create_shadow_texture()
|
|
||||||
$DynamicSky/ShadowProxySystem.shadow_texture = shadow_tex
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing the System
|
|
||||||
|
|
||||||
### Test 1: Basic Scene Test
|
|
||||||
1. Create a new 3D scene with a `Camera3D` and a `MeshInstance3D` (e.g., plane for ground)
|
|
||||||
2. Instance `dynamic_sky.tscn`
|
|
||||||
3. Run the scene (F5)
|
|
||||||
4. You should see a gradient sky with sun light
|
|
||||||
|
|
||||||
### Test 2: Time of Day
|
|
||||||
Add this script to test time changes:
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@onready var sky = $DynamicSky
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
# Start at morning
|
|
||||||
sky.set_time_of_day(0.25)
|
|
||||||
|
|
||||||
func _process(delta):
|
|
||||||
# Press keys to change time
|
|
||||||
if Input.is_action_just_pressed("ui_right"):
|
|
||||||
sky.set_time_of_day(sky.get_time_of_day() + 0.05)
|
|
||||||
if Input.is_action_just_pressed("ui_left"):
|
|
||||||
sky.set_time_of_day(sky.get_time_of_day() - 0.05)
|
|
||||||
|
|
||||||
# Print current time
|
|
||||||
if Input.is_action_just_pressed("ui_accept"):
|
|
||||||
print("Time: ", sky.get_time_of_day())
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 3: Weather System
|
|
||||||
```gdscript
|
|
||||||
func _input(event):
|
|
||||||
if event.is_action_pressed("ui_up"):
|
|
||||||
$DynamicSky.set_weather(WeatherProfile.WeatherState.RAIN)
|
|
||||||
if event.is_action_pressed("ui_down"):
|
|
||||||
$DynamicSky.set_weather(WeatherProfile.WeatherState.CLEAR)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 4: Debug Panel
|
|
||||||
1. Add a `CanvasLayer` to your scene
|
|
||||||
2. Add a `Control` node as child
|
|
||||||
3. Attach the `sky_debug_panel.gd` script
|
|
||||||
4. In Inspector, assign the `DynamicSky` node to the `dynamic_sky` property
|
|
||||||
5. Run and use the UI controls
|
|
||||||
|
|
||||||
### Test 5: Meteor Shower
|
|
||||||
```gdscript
|
|
||||||
func _ready():
|
|
||||||
# Ensure it's night for visibility
|
|
||||||
$DynamicSky.set_time_of_day(0.0)
|
|
||||||
# Wait a moment then trigger
|
|
||||||
await get_tree().create_timer(1.0).timeout
|
|
||||||
$DynamicSky.trigger_meteor_shower(30.0)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test 6: Kill Volumes
|
|
||||||
1. Add an `Area3D` to your scene
|
|
||||||
2. Attach `weather_kill_volume.gd` script
|
|
||||||
3. Configure the shape and size in Inspector
|
|
||||||
4. Precipitation will be blocked inside this volume
|
|
||||||
|
|
||||||
## Complete Test Scene Example
|
|
||||||
|
|
||||||
Create a new scene with this structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
TestScene (Node3D)
|
|
||||||
├── DynamicSky (instance of dynamic_sky.tscn)
|
|
||||||
├── Camera3D
|
|
||||||
├── Ground (MeshInstance3D with PlaneMesh)
|
|
||||||
├── CanvasLayer
|
|
||||||
│ └── DebugPanel (Control with sky_debug_panel.gd)
|
|
||||||
└── TestScript (Node with test script below)
|
|
||||||
```
|
|
||||||
|
|
||||||
Test script:
|
|
||||||
```gdscript
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@onready var sky = $"../DynamicSky"
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
# Generate cloud textures
|
|
||||||
_setup_clouds()
|
|
||||||
|
|
||||||
# Start at mid-morning
|
|
||||||
sky.set_time_of_day(0.35)
|
|
||||||
|
|
||||||
print("Dynamic Sky Test Ready!")
|
|
||||||
print("Arrow keys: Change time")
|
|
||||||
print("1-6: Change weather")
|
|
||||||
print("M: Meteor shower")
|
|
||||||
print("P: Pause/Resume time")
|
|
||||||
|
|
||||||
func _setup_clouds():
|
|
||||||
var cloud_system = sky.cloud_system
|
|
||||||
if cloud_system:
|
|
||||||
for i in cloud_system.layer_configs.size():
|
|
||||||
var tex = ProceduralCloudTexture.create_default_cloud_texture(i)
|
|
||||||
cloud_system.layer_configs[i].texture = tex
|
|
||||||
cloud_system.rebuild_layers()
|
|
||||||
|
|
||||||
var shadow_system = sky.shadow_proxy_system
|
|
||||||
if shadow_system:
|
|
||||||
shadow_system.shadow_texture = ProceduralCloudTexture.create_shadow_texture()
|
|
||||||
|
|
||||||
func _input(event):
|
|
||||||
if event is InputEventKey and event.pressed:
|
|
||||||
match event.keycode:
|
|
||||||
KEY_RIGHT:
|
|
||||||
sky.set_time_of_day(wrapf(sky.get_time_of_day() + 0.02, 0, 1))
|
|
||||||
KEY_LEFT:
|
|
||||||
sky.set_time_of_day(wrapf(sky.get_time_of_day() - 0.02, 0, 1))
|
|
||||||
KEY_1:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.CLEAR)
|
|
||||||
KEY_2:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.CLOUDY)
|
|
||||||
KEY_3:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.OVERCAST)
|
|
||||||
KEY_4:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.RAIN)
|
|
||||||
KEY_5:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.STORM)
|
|
||||||
KEY_6:
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.SNOW)
|
|
||||||
KEY_M:
|
|
||||||
sky.trigger_meteor_shower(30.0)
|
|
||||||
KEY_P:
|
|
||||||
if sky.day_night_controller.paused:
|
|
||||||
sky.resume_time()
|
|
||||||
else:
|
|
||||||
sky.pause_time()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
| Issue | Solution |
|
|
||||||
|-------|----------|
|
|
||||||
| Script errors on load | Reload project: Project → Reload Current Project |
|
|
||||||
| No sky visible | Ensure camera is looking up; check WorldEnvironment exists |
|
|
||||||
| Clouds not visible | Assign textures to CloudLayerConfig or generate procedurally |
|
|
||||||
| Shadows not visible | Assign shadow_texture to ShadowProxySystem |
|
|
||||||
| Stars not visible | Set time to night (0.0 or 0.9+); check stars_visibility curve |
|
|
||||||
| Time not advancing | Check `paused` is false on DayNightController |
|
|
||||||
| Weather not changing | Check WeatherController has profiles; look at transition progress |
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
### Preset Skybox Nodes
|
|
||||||
- 6 presets: Clear Day, Sunset, Night, Overcast, Storm, Dawn
|
|
||||||
- Runtime preset switching with smooth transitions
|
|
||||||
- Non-destructive overrides
|
|
||||||
|
|
||||||
### Day/Night Cycle
|
|
||||||
- Configurable day length (1-1440 minutes)
|
|
||||||
- Sun/moon arc movement
|
|
||||||
- Color/intensity curves for sun, moon, ambient, fog
|
|
||||||
- Star visibility at night
|
|
||||||
- Time events (sunrise, sunset, noon)
|
|
||||||
|
|
||||||
### Weather System
|
|
||||||
- States: Clear, Cloudy, Overcast, Rain, Storm, Snow
|
|
||||||
- Smooth transitions between states
|
|
||||||
- Per-state cloud, wind, and VFX settings
|
|
||||||
- Random or scripted weather timelines
|
|
||||||
|
|
||||||
### 2D Cloudscapes
|
|
||||||
- 4 independent layers (low, mid, high, wisps)
|
|
||||||
- Per-layer texture, tiling, opacity, color
|
|
||||||
- Flow animation with wind influence
|
|
||||||
- Evolution/morphing over time
|
|
||||||
- Reactive to sun/moon lighting
|
|
||||||
|
|
||||||
### Post-Processing
|
|
||||||
- Sky gradient shading
|
|
||||||
- Height and distance fog
|
|
||||||
- Sun glow halo
|
|
||||||
- Dawn/dusk enhancement
|
|
||||||
- Procedural stars
|
|
||||||
|
|
||||||
### VFX
|
|
||||||
- Shooting stars (randomized)
|
|
||||||
- Meteor showers (event-triggered)
|
|
||||||
- Configurable appearance
|
|
||||||
|
|
||||||
### Cloud Shadows
|
|
||||||
- Projected shadow overlay
|
|
||||||
- Syncs with cloud movement
|
|
||||||
- Blur and opacity controls
|
|
||||||
|
|
||||||
### Kill Volumes
|
|
||||||
- Block precipitation in indoor areas
|
|
||||||
- Box, sphere, cylinder shapes
|
|
||||||
- Fade-out margins
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
1. Add `dynamic_sky.tscn` to your scene
|
|
||||||
2. Reference the DynamicSky node in your scripts
|
|
||||||
3. Use the API:
|
|
||||||
|
|
||||||
```gdscript
|
|
||||||
# Get reference
|
|
||||||
@onready var sky = $DynamicSky
|
|
||||||
|
|
||||||
# Set time (0.0-1.0, where 0.5 = noon)
|
|
||||||
sky.set_time_of_day(0.5)
|
|
||||||
|
|
||||||
# Change weather
|
|
||||||
sky.set_weather(WeatherProfile.WeatherState.RAIN)
|
|
||||||
|
|
||||||
# Apply preset
|
|
||||||
sky.apply_preset("Sunset")
|
|
||||||
|
|
||||||
# Trigger meteor shower
|
|
||||||
sky.trigger_meteor_shower(60.0)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Debug Panel
|
|
||||||
|
|
||||||
Add `SkyDebugPanel` to your UI and assign the DynamicSky reference to see:
|
|
||||||
- Current time and weather
|
|
||||||
- Cloud coverage
|
|
||||||
- Controls for testing
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
- `SkyConfig`: Global sky parameters
|
|
||||||
- `SkyPreset`: Complete preset configuration
|
|
||||||
- `WeatherProfile`: Per-weather-state settings
|
|
||||||
- `CloudLayerConfig`: Per-layer cloud settings
|
|
||||||
- `PostProcessProfile`: Post-processing parameters
|
|
||||||
|
|
||||||
## Performance
|
|
||||||
|
|
||||||
- Disable unused cloud layers
|
|
||||||
- Reduce cloud texture resolution
|
|
||||||
- Lower VFX update rates
|
|
||||||
- Disable shadow blur on low-end hardware
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
# Stylized Dynamic Sky Specification (Godot 4.6)
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
This document specifies a stylized dynamic sky system for Godot 4.6. It defines the required features, behavior, data structures, and integration points without prescribing implementation code.
|
|
||||||
|
|
||||||
## Goals
|
|
||||||
- Provide a visually stylized, dynamic sky suitable for stylized or semi-realistic games.
|
|
||||||
- Offer modular components that can be combined or replaced.
|
|
||||||
- Enable deterministic playback for cutscenes and synchronized multiplayer.
|
|
||||||
- Support art-direction via presets and editor-friendly controls.
|
|
||||||
|
|
||||||
## Non-Goals
|
|
||||||
- Physically accurate atmospheric scattering.
|
|
||||||
- Real-world meteorology simulation.
|
|
||||||
- Automated terrain-aware shadow projections.
|
|
||||||
|
|
||||||
## System Architecture
|
|
||||||
- **DynamicSkyRoot**: Top-level scene controlling time, weather, and global parameters.
|
|
||||||
- **SkyboxPresetLibrary**: Collection of preset skybox nodes (configured resources/scenes).
|
|
||||||
- **DayNightController**: Controls sun/moon movement, ambient light, and time-of-day curves.
|
|
||||||
- **WeatherController**: Drives weather states, transitions, and VFX spawning.
|
|
||||||
- **CloudSystem2D**: Handles layered 2D cloudscapes, flow, animation, and evolution.
|
|
||||||
- **PostProcessController**: Applies stylized gradients, fog shaping, and sun glow.
|
|
||||||
- **VFXController**: Shooting stars and meteor showers.
|
|
||||||
- **ShadowProxySystem**: Faked cloud shadows projected onto world.
|
|
||||||
|
|
||||||
## Feature Specifications
|
|
||||||
|
|
||||||
### Preset Skybox Nodes
|
|
||||||
**Description**: Pre-authored skybox configurations that can be swapped at runtime.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- At least 6 presets: Clear Day, Sunset, Night, Overcast, Storm, Dawn.
|
|
||||||
- Each preset includes:
|
|
||||||
- Skybox texture/gradient resources.
|
|
||||||
- Sun and moon color presets.
|
|
||||||
- Ambient and fog color presets.
|
|
||||||
- Default cloud layers and post-process settings.
|
|
||||||
- Presets can be overridden by runtime controllers without losing base values.
|
|
||||||
- Preset application is non-destructive and reversible.
|
|
||||||
|
|
||||||
**Editor UX**:
|
|
||||||
- Preset picker dropdown.
|
|
||||||
- “Apply Preset” button and “Revert to Preset” button.
|
|
||||||
|
|
||||||
### Day/Night Cycle
|
|
||||||
**Description**: Stylized, configurable cycle controlling lighting and sky appearance.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Time scale with configurable length (e.g., 10–240 minutes per day).
|
|
||||||
- Supports manual time-of-day override and pause.
|
|
||||||
- Sun and moon directional motion (arc across sky dome).
|
|
||||||
- Color and intensity curves:
|
|
||||||
- Sun color and intensity.
|
|
||||||
- Moon color and intensity.
|
|
||||||
- Ambient color and intensity.
|
|
||||||
- Fog color and density.
|
|
||||||
- Smooth transitions between time states.
|
|
||||||
- Optional star visibility curve.
|
|
||||||
|
|
||||||
**Data**:
|
|
||||||
- TimeOfDay (0.0–1.0 normalized)
|
|
||||||
- Curves for color/intensity across time.
|
|
||||||
|
|
||||||
### Weather System
|
|
||||||
**Description**: State-based weather controller with transitions and parameters.
|
|
||||||
|
|
||||||
**Weather States**:
|
|
||||||
- Clear
|
|
||||||
- Cloudy
|
|
||||||
- Overcast
|
|
||||||
- Rain
|
|
||||||
- Storm
|
|
||||||
- Snow (optional, can be disabled)
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- State machine with configurable transition durations.
|
|
||||||
- Each state defines:
|
|
||||||
- Cloud density, opacity, and coverage.
|
|
||||||
- Wind speed and direction (affects cloud flow).
|
|
||||||
- VFX sets (rain, lightning, snow).
|
|
||||||
- Ambient and fog adjustments.
|
|
||||||
- Randomized or scripted weather timeline support.
|
|
||||||
- Events/callbacks on state enter/exit.
|
|
||||||
|
|
||||||
### 2D Customizable Cloudscapes
|
|
||||||
**Description**: Layered 2D clouds rendered on the sky dome or as screen-space quads.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Up to 4 independent layers: low, mid, high, wisps.
|
|
||||||
- Per-layer settings:
|
|
||||||
- Texture/atlas selection.
|
|
||||||
- Tiling and scale.
|
|
||||||
- Opacity and color tint.
|
|
||||||
- Parallax depth factor.
|
|
||||||
- Flow direction and speed.
|
|
||||||
- Global cloud coverage control.
|
|
||||||
|
|
||||||
### Cloud Flow, Animation, and Evolution
|
|
||||||
**Description**: Dynamic motion and shape changes over time.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Continuous UV flow with wind influence.
|
|
||||||
- Optional noise-based distortion for stylized movement.
|
|
||||||
- Evolution parameter to morph coverage and shape (low-frequency drift).
|
|
||||||
- Time-based variation seed to keep deterministic playback when seeded.
|
|
||||||
|
|
||||||
### Cloud Lighting Reacts with Sun and Moon
|
|
||||||
**Description**: Cloud shading changes based on celestial light direction and intensity.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Light direction taken from sun/moon controller.
|
|
||||||
- Bright side and shadowed side color control.
|
|
||||||
- Night-time soft illumination from moon.
|
|
||||||
- Optional rim glow at dawn/dusk.
|
|
||||||
|
|
||||||
### Weather Particle Kill Volumes
|
|
||||||
**Description**: Volumes that stop precipitation or weather particles in indoor or sheltered spaces.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Axis-aligned and/or custom-shaped kill volumes.
|
|
||||||
- Particles inside kill volume are disabled or instantly culled.
|
|
||||||
- Priority/stacking rules when volumes overlap.
|
|
||||||
- Optional fade-out margin to avoid hard cutoffs.
|
|
||||||
|
|
||||||
### Stylized Post Process for Fog and Sun Gradients
|
|
||||||
**Description**: Screen-space effects to enhance gradients and fog stylization.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Adjustable sky gradient curve blending.
|
|
||||||
- Fog shaping controls (height fog, distance fog).
|
|
||||||
- Sun glow halo with stylized falloff.
|
|
||||||
- Dusk/dawn gradient emphasis.
|
|
||||||
- Option to toggle for performance profiles.
|
|
||||||
|
|
||||||
### Shooting Star and Meteor Shower VFX
|
|
||||||
**Description**: Procedural or timed visual effects visible in the sky.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Occasional shooting stars (randomized frequency).
|
|
||||||
- Meteor shower events with configurable duration and intensity.
|
|
||||||
- Trail length, brightness, and color control.
|
|
||||||
- Optional audio event hook for meteor shower start.
|
|
||||||
|
|
||||||
### Faked Cloud Shadows
|
|
||||||
**Description**: Stylized cloud shadow overlay projected onto the world.
|
|
||||||
|
|
||||||
**Requirements**:
|
|
||||||
- Shadow texture projected in world space or onto a large quad.
|
|
||||||
- Movement matches cloud flow direction and speed.
|
|
||||||
- Darkness/opacity controls and color tint.
|
|
||||||
- Optional blur for softer look.
|
|
||||||
|
|
||||||
## Data and Configuration
|
|
||||||
- **SkyConfig Resource**: Stores defaults for all controllers.
|
|
||||||
- **Preset Resource**: Encapsulates a SkyConfig plus skybox assets.
|
|
||||||
- **WeatherProfile**: Per-state settings and VFX parameters.
|
|
||||||
- **CloudLayerConfig**: Texture/flow/lighting settings per layer.
|
|
||||||
- **PostProcessProfile**: Gradient, fog, and sun glow parameters.
|
|
||||||
|
|
||||||
## Performance Targets
|
|
||||||
- Target 60 FPS on mid-range hardware.
|
|
||||||
- Cloud layers should allow selective disabling.
|
|
||||||
- VFX update rates configurable.
|
|
||||||
|
|
||||||
## Debug and Tooling
|
|
||||||
- On-screen debug panel showing time, weather state, cloud parameters.
|
|
||||||
- Seed display for deterministic playback.
|
|
||||||
- Editor gizmos for kill volumes.
|
|
||||||
|
|
||||||
## Acceptance Criteria
|
|
||||||
- All required features are present and configurable in editor.
|
|
||||||
- Presets can be applied and reverted without data loss.
|
|
||||||
- Day/night transitions are smooth with no visible jumps.
|
|
||||||
- Weather transitions alter clouds, lighting, and VFX consistently.
|
|
||||||
- Cloud lighting visibly reacts to sun/moon changes.
|
|
||||||
- Kill volumes prevent precipitation in indoor spaces.
|
|
||||||
- Post process improves gradients and fog stylization.
|
|
||||||
- Shooting stars and meteor showers visible at night.
|
|
||||||
- Cloud shadows visibly move across the world.
|
|
||||||
@@ -1,418 +0,0 @@
|
|||||||
[gd_scene format=3 uid="uid://doiojb8xxlp2s"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://8r3do6ow5nmn" path="res://dynamic-sky/scripts/dynamic_sky_root.gd" id="1_dynamic_sky"]
|
|
||||||
[ext_resource type="Script" uid="uid://cb8c6ug44jx4t" path="res://dynamic-sky/scripts/skybox_preset_library.gd" id="2_preset_library"]
|
|
||||||
[ext_resource type="Script" uid="uid://c48eq2y4ikok8" path="res://dynamic-sky/resources/sky_preset.gd" id="3_c6jpa"]
|
|
||||||
[ext_resource type="Script" uid="uid://gypnoh5ikwjn" path="res://dynamic-sky/scripts/day_night_controller.gd" id="3_day_night"]
|
|
||||||
[ext_resource type="Script" uid="uid://beu0xhk0rvpky" path="res://dynamic-sky/resources/cloud_layer_config.gd" id="4_ssi15"]
|
|
||||||
[ext_resource type="Script" uid="uid://blyx8v2gq8nlw" path="res://dynamic-sky/scripts/weather_controller.gd" id="4_weather"]
|
|
||||||
[ext_resource type="Script" uid="uid://c3iniqgu2l0ek" path="res://dynamic-sky/resources/sky_config.gd" id="5_2w5ig"]
|
|
||||||
[ext_resource type="Script" uid="uid://cwplvsarljsf" path="res://dynamic-sky/scripts/cloud_system_2d.gd" id="5_clouds"]
|
|
||||||
[ext_resource type="Script" uid="uid://cwqg0bg2m2bme" path="res://dynamic-sky/scripts/post_process_controller.gd" id="6_post_process"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://crrj260kiyoy" path="res://dynamic-sky/sky_44_2k.png" id="6_ssi15"]
|
|
||||||
[ext_resource type="Script" uid="uid://cnvj3m5fpsdtj" path="res://dynamic-sky/scripts/vfx_controller.gd" id="7_vfx"]
|
|
||||||
[ext_resource type="Script" uid="uid://d2srir3wsi045" path="res://dynamic-sky/resources/weather_profile.gd" id="8_cnx2n"]
|
|
||||||
[ext_resource type="Script" uid="uid://hvs2g6acqryq" path="res://dynamic-sky/scripts/shadow_proxy_system.gd" id="8_shadows"]
|
|
||||||
[ext_resource type="Script" uid="uid://ctrw2ycud36yd" path="res://dynamic-sky/resources/post_process_profile.gd" id="11_djhca"]
|
|
||||||
[ext_resource type="Environment" uid="uid://dq64sos14f8hu" path="res://dynamic-sky/environment.tres" id="13_2w5ig"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_c27no"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_color = Color(1, 0.95, 0.85, 1)
|
|
||||||
sun_intensity = 1.2
|
|
||||||
moon_intensity = 0.0
|
|
||||||
ambient_color = Color(0.5, 0.6, 0.8, 1)
|
|
||||||
ambient_intensity = 0.6
|
|
||||||
fog_color = Color(0.7, 0.8, 0.95, 1)
|
|
||||||
fog_density = 0.005
|
|
||||||
sky_top_color = Color(0.2, 0.4, 0.85, 1)
|
|
||||||
sky_horizon_color = Color(0.6, 0.75, 0.95, 1)
|
|
||||||
sky_bottom_color = Color(0.5, 0.6, 0.7, 1)
|
|
||||||
cloud_coverage = 0.2
|
|
||||||
cloud_opacity = 0.7
|
|
||||||
sun_glow_intensity = 0.3
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ssi15"]
|
|
||||||
script = ExtResource("11_djhca")
|
|
||||||
metadata/_custom_type_script = "uid://ctrw2ycud36yd"
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ajt3x"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Clear Day"
|
|
||||||
preset_type = 0
|
|
||||||
config = SubResource("Resource_c27no")
|
|
||||||
skybox_texture = ExtResource("6_ssi15")
|
|
||||||
post_process_profile = SubResource("Resource_ssi15")
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_cp2fs"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_color = Color(1, 0.5, 0.2, 1)
|
|
||||||
sun_intensity = 0.8
|
|
||||||
moon_intensity = 0.0
|
|
||||||
ambient_color = Color(0.8, 0.5, 0.4, 1)
|
|
||||||
ambient_intensity = 0.4
|
|
||||||
fog_color = Color(0.9, 0.6, 0.4, 1)
|
|
||||||
fog_density = 0.015
|
|
||||||
sky_top_color = Color(0.3, 0.2, 0.5, 1)
|
|
||||||
sky_horizon_color = Color(1, 0.5, 0.3, 1)
|
|
||||||
sky_bottom_color = Color(0.9, 0.4, 0.2, 1)
|
|
||||||
stars_visibility = 0.1
|
|
||||||
cloud_opacity = 0.9
|
|
||||||
cloud_color = Color(1, 0.7, 0.5, 1)
|
|
||||||
cloud_shadow_color = Color(0.4, 0.2, 0.3, 1)
|
|
||||||
sun_glow_intensity = 0.8
|
|
||||||
sun_glow_size = 0.4
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_sptlx"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Sunset"
|
|
||||||
preset_type = 1
|
|
||||||
config = SubResource("Resource_cp2fs")
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_bmqu2"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_intensity = 0.0
|
|
||||||
moon_color = Color(0.7, 0.8, 1, 1)
|
|
||||||
moon_intensity = 0.4
|
|
||||||
ambient_color = Color(0.1, 0.15, 0.25, 1)
|
|
||||||
ambient_intensity = 0.2
|
|
||||||
fog_color = Color(0.1, 0.12, 0.2, 1)
|
|
||||||
fog_density = 0.02
|
|
||||||
sky_top_color = Color(0.02, 0.03, 0.08, 1)
|
|
||||||
sky_horizon_color = Color(0.1, 0.12, 0.2, 1)
|
|
||||||
sky_bottom_color = Color(0.05, 0.06, 0.1, 1)
|
|
||||||
stars_visibility = 1.0
|
|
||||||
cloud_coverage = 0.15
|
|
||||||
cloud_opacity = 0.5
|
|
||||||
cloud_color = Color(0.2, 0.22, 0.3, 1)
|
|
||||||
cloud_shadow_color = Color(0.05, 0.05, 0.1, 1)
|
|
||||||
sun_glow_intensity = 0.0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_fqsrh"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Night"
|
|
||||||
preset_type = 2
|
|
||||||
config = SubResource("Resource_bmqu2")
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_4i5ra"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_color = Color(0.9, 0.9, 0.85, 1)
|
|
||||||
sun_intensity = 0.4
|
|
||||||
moon_intensity = 0.0
|
|
||||||
ambient_color = Color(0.5, 0.5, 0.55, 1)
|
|
||||||
ambient_intensity = 0.7
|
|
||||||
fog_color = Color(0.6, 0.62, 0.65, 1)
|
|
||||||
fog_density = 0.03
|
|
||||||
sky_top_color = Color(0.45, 0.48, 0.55, 1)
|
|
||||||
sky_horizon_color = Color(0.6, 0.62, 0.65, 1)
|
|
||||||
sky_bottom_color = Color(0.5, 0.52, 0.55, 1)
|
|
||||||
cloud_coverage = 0.9
|
|
||||||
cloud_opacity = 1.0
|
|
||||||
cloud_color = Color(0.7, 0.72, 0.75, 1)
|
|
||||||
cloud_shadow_color = Color(0.4, 0.42, 0.45, 1)
|
|
||||||
sun_glow_intensity = 0.1
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_drex5"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Overcast"
|
|
||||||
preset_type = 3
|
|
||||||
config = SubResource("Resource_4i5ra")
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_gm4lj"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_color = Color(0.7, 0.7, 0.75, 1)
|
|
||||||
sun_intensity = 0.2
|
|
||||||
moon_intensity = 0.0
|
|
||||||
ambient_color = Color(0.35, 0.38, 0.45, 1)
|
|
||||||
fog_color = Color(0.4, 0.42, 0.5, 1)
|
|
||||||
fog_density = 0.05
|
|
||||||
sky_top_color = Color(0.25, 0.28, 0.35, 1)
|
|
||||||
sky_horizon_color = Color(0.4, 0.42, 0.48, 1)
|
|
||||||
sky_bottom_color = Color(0.35, 0.38, 0.42, 1)
|
|
||||||
cloud_coverage = 1.0
|
|
||||||
cloud_opacity = 1.0
|
|
||||||
cloud_color = Color(0.4, 0.42, 0.5, 1)
|
|
||||||
cloud_shadow_color = Color(0.2, 0.22, 0.28, 1)
|
|
||||||
sun_glow_intensity = 0.0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_5lttf"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Storm"
|
|
||||||
preset_type = 4
|
|
||||||
config = SubResource("Resource_gm4lj")
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ym26c"]
|
|
||||||
script = ExtResource("5_2w5ig")
|
|
||||||
sun_color = Color(1, 0.7, 0.5, 1)
|
|
||||||
sun_intensity = 0.5
|
|
||||||
moon_intensity = 0.1
|
|
||||||
ambient_color = Color(0.4, 0.35, 0.45, 1)
|
|
||||||
ambient_intensity = 0.35
|
|
||||||
fog_color = Color(0.6, 0.5, 0.55, 1)
|
|
||||||
fog_density = 0.025
|
|
||||||
sky_top_color = Color(0.15, 0.2, 0.45, 1)
|
|
||||||
sky_horizon_color = Color(0.9, 0.6, 0.5, 1)
|
|
||||||
sky_bottom_color = Color(0.7, 0.45, 0.4, 1)
|
|
||||||
stars_visibility = 0.3
|
|
||||||
cloud_coverage = 0.25
|
|
||||||
cloud_color = Color(0.95, 0.7, 0.6, 1)
|
|
||||||
cloud_shadow_color = Color(0.3, 0.25, 0.35, 1)
|
|
||||||
sun_glow_intensity = 0.6
|
|
||||||
sun_glow_size = 0.35
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_umd7u"]
|
|
||||||
script = ExtResource("3_c6jpa")
|
|
||||||
preset_name = "Dawn"
|
|
||||||
preset_type = 5
|
|
||||||
config = SubResource("Resource_ym26c")
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_sxvon"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.25, 0.5, 0.75, 1)
|
|
||||||
colors = PackedColorArray(1, 0.6, 0.4, 1, 1, 0.5, 0.3, 1, 1, 1, 0.95, 1, 1, 0.7, 0.4, 1, 1, 1, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_fm80q"]
|
|
||||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 0), 0.0, 0.0, 0, 0, Vector2(0.3, 0.55), 0.0, 0.0, 0, 0, Vector2(0.5, 0.7), 0.0, 0.0, 0, 0, Vector2(0.7, 0.55), 0.0, 0.0, 0, 0, Vector2(0.85, 0), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 7
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_kcyr7"]
|
|
||||||
colors = PackedColorArray(0.7, 0.8, 1, 1, 0.7, 0.8, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_qti3v"]
|
|
||||||
_data = [Vector2(0, 0.4), 0.0, 0.0, 0, 0, Vector2(0.15, 0.3), 0.0, 0.0, 0, 0, Vector2(0.22, 0), 0.0, 0.0, 0, 0, Vector2(0.85, 0), 0.0, 0.0, 0, 0, Vector2(0.92, 0.3), 0.0, 0.0, 0, 0, Vector2(1, 0.4), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 6
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_bq8yq"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.25, 0.5, 0.75, 1)
|
|
||||||
colors = PackedColorArray(0.08, 0.1, 0.18, 1, 0.5, 0.55, 0.65, 1, 0.6, 0.65, 0.75, 1, 0.55, 0.5, 0.55, 1, 0.08, 0.1, 0.18, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_x6xf2"]
|
|
||||||
_data = [Vector2(0, 0.05), 0.0, 0.0, 0, 0, Vector2(0.2, 0.1), 0.0, 0.0, 0, 0, Vector2(0.3, 0.5), 0.0, 0.0, 0, 0, Vector2(0.5, 0.6), 0.0, 0.0, 0, 0, Vector2(0.7, 0.5), 0.0, 0.0, 0, 0, Vector2(0.85, 0.1), 0.0, 0.0, 0, 0, Vector2(1, 0.05), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 7
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_tn5up"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.25, 0.5, 0.75, 1)
|
|
||||||
colors = PackedColorArray(0.05, 0.06, 0.1, 1, 0.6, 0.65, 0.75, 1, 0.7, 0.75, 0.85, 1, 0.7, 0.55, 0.5, 1, 0.05, 0.06, 0.1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_ej5u1"]
|
|
||||||
_data = [Vector2(0, 0.02), 0.0, 0.0, 0, 0, Vector2(0.25, 0.015), 0.0, 0.0, 0, 0, Vector2(0.5, 0.01), 0.0, 0.0, 0, 0, Vector2(0.75, 0.015), 0.0, 0.0, 0, 0, Vector2(1, 0.02), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 5
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_2w5ig"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.2, 0.3, 0.5, 0.75, 0.85, 1)
|
|
||||||
colors = PackedColorArray(0.01, 0.01, 0.04, 1, 0.01, 0.01, 0.04, 1, 0.18, 0.35, 0.8, 1, 0.15, 0.35, 0.82, 1, 0.12, 0.15, 0.4, 1, 0.02, 0.02, 0.06, 1, 1, 1, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_cnx2n"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.2, 0.25, 0.35, 0.5, 0.75, 0.85, 1)
|
|
||||||
colors = PackedColorArray(0.03, 0.04, 0.08, 1, 0.03, 0.04, 0.08, 1, 0.85, 0.55, 0.45, 1, 0.45, 0.6, 0.85, 1, 0.5, 0.65, 0.88, 1, 0.95, 0.45, 0.25, 1, 0.06, 0.06, 0.1, 1, 1, 1, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_djhca"]
|
|
||||||
offsets = PackedFloat32Array(0, 0.2, 0.3, 0.5, 0.75, 0.85, 1)
|
|
||||||
colors = PackedColorArray(0.02, 0.02, 0.05, 1, 0.02, 0.02, 0.05, 1, 0.35, 0.45, 0.55, 1, 0.35, 0.45, 0.55, 1, 0.3, 0.2, 0.2, 1, 0.03, 0.03, 0.06, 1, 1, 1, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_ta3fj"]
|
|
||||||
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.2, 0.8), 0.0, 0.0, 0, 0, Vector2(0.3, 0), 0.0, 0.0, 0, 0, Vector2(0.7, 0), 0.0, 0.0, 0, 0, Vector2(0.85, 0.8), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 6
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_dfjcy"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
cloud_density = 0.1
|
|
||||||
cloud_opacity = 0.1
|
|
||||||
cloud_coverage = 0.1
|
|
||||||
wind_speed = 0.5
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_sjmt0"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
weather_state = 1
|
|
||||||
display_name = "Cloudy"
|
|
||||||
cloud_density = 0.5
|
|
||||||
cloud_opacity = 0.8
|
|
||||||
cloud_coverage = 0.5
|
|
||||||
ambient_intensity_multiplier = 0.9
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_uap2q"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
weather_state = 2
|
|
||||||
display_name = "Overcast"
|
|
||||||
cloud_density = 0.9
|
|
||||||
cloud_opacity = 1.0
|
|
||||||
cloud_coverage = 0.9
|
|
||||||
cloud_color = Color(0.7, 0.72, 0.75, 1)
|
|
||||||
wind_speed = 1.5
|
|
||||||
ambient_intensity_multiplier = 0.7
|
|
||||||
fog_density_multiplier = 1.5
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_mcoyn"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
weather_state = 3
|
|
||||||
display_name = "Rain"
|
|
||||||
cloud_density = 0.85
|
|
||||||
cloud_opacity = 0.95
|
|
||||||
cloud_coverage = 0.85
|
|
||||||
cloud_color = Color(0.55, 0.58, 0.65, 1)
|
|
||||||
wind_speed = 2.0
|
|
||||||
ambient_intensity_multiplier = 0.6
|
|
||||||
fog_density_multiplier = 2.0
|
|
||||||
rain_intensity = 0.7
|
|
||||||
lightning_enabled = true
|
|
||||||
lightning_frequency = 0.002
|
|
||||||
default_transition_duration = 8.0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_mr14h"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
weather_state = 4
|
|
||||||
display_name = "Storm"
|
|
||||||
cloud_density = 1.0
|
|
||||||
cloud_opacity = 1.0
|
|
||||||
cloud_coverage = 1.0
|
|
||||||
cloud_color = Color(0.4, 0.42, 0.5, 1)
|
|
||||||
cloud_shadow_color = Color(0.2, 0.22, 0.28, 1)
|
|
||||||
wind_speed = 4.0
|
|
||||||
wind_turbulence = 0.4
|
|
||||||
ambient_intensity_multiplier = 0.4
|
|
||||||
fog_density_multiplier = 3.0
|
|
||||||
rain_intensity = 1.0
|
|
||||||
lightning_enabled = true
|
|
||||||
lightning_frequency = 0.15
|
|
||||||
default_transition_duration = 10.0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ps44b"]
|
|
||||||
script = ExtResource("8_cnx2n")
|
|
||||||
weather_state = 5
|
|
||||||
display_name = "Snow"
|
|
||||||
cloud_density = 0.8
|
|
||||||
cloud_opacity = 0.9
|
|
||||||
cloud_coverage = 0.8
|
|
||||||
cloud_color = Color(0.85, 0.87, 0.92, 1)
|
|
||||||
ambient_color_multiplier = Color(0.9, 0.92, 1, 1)
|
|
||||||
ambient_intensity_multiplier = 0.75
|
|
||||||
fog_color_multiplier = Color(0.95, 0.97, 1, 1)
|
|
||||||
fog_density_multiplier = 1.8
|
|
||||||
snow_intensity = 0.8
|
|
||||||
default_transition_duration = 12.0
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_uhdsh"]
|
|
||||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.5, 0.5), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 3
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_xh4oc"]
|
|
||||||
script = ExtResource("4_ssi15")
|
|
||||||
layer_type = 0
|
|
||||||
tiling = Vector2(2, 2)
|
|
||||||
opacity = 0.9
|
|
||||||
flow_speed = 0.03
|
|
||||||
parallax_depth = 0.3
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ahi10"]
|
|
||||||
script = ExtResource("4_ssi15")
|
|
||||||
tiling = Vector2(3, 3)
|
|
||||||
opacity = 0.7
|
|
||||||
parallax_depth = 0.6
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_a5xai"]
|
|
||||||
script = ExtResource("4_ssi15")
|
|
||||||
layer_type = 2
|
|
||||||
opacity = 0.5
|
|
||||||
flow_speed = 0.01
|
|
||||||
parallax_depth = 0.9
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_uxs4q"]
|
|
||||||
script = ExtResource("4_ssi15")
|
|
||||||
layer_type = 3
|
|
||||||
tiling = Vector2(6, 6)
|
|
||||||
opacity = 0.3
|
|
||||||
flow_speed = 0.015
|
|
||||||
|
|
||||||
[sub_resource type="Compositor" id="Compositor_ssi15"]
|
|
||||||
|
|
||||||
[node name="DynamicSky" type="Node3D" unique_id=516593260 node_paths=PackedStringArray("preset_library", "day_night_controller", "weather_controller", "cloud_system", "post_process_controller", "vfx_controller", "shadow_proxy_system", "weather_vfx", "world_environment", "sun_light", "moon_light")]
|
|
||||||
script = ExtResource("1_dynamic_sky")
|
|
||||||
preset_library = NodePath("PresetLibrary")
|
|
||||||
day_night_controller = NodePath("DayNightController")
|
|
||||||
weather_controller = NodePath("WeatherController")
|
|
||||||
cloud_system = NodePath("CloudSystem")
|
|
||||||
post_process_controller = NodePath("PostProcessController")
|
|
||||||
vfx_controller = NodePath("VFXController")
|
|
||||||
shadow_proxy_system = NodePath("ShadowProxySystem")
|
|
||||||
weather_vfx = NodePath("WeatherVFX")
|
|
||||||
world_environment = NodePath("WorldEnvironment")
|
|
||||||
sun_light = NodePath("SunLight")
|
|
||||||
moon_light = NodePath("MoonLight")
|
|
||||||
deterministic_seed = 5
|
|
||||||
show_debug_panel = true
|
|
||||||
|
|
||||||
[node name="PresetLibrary" type="Node" parent="." unique_id=1947927418]
|
|
||||||
script = ExtResource("2_preset_library")
|
|
||||||
presets = Array[ExtResource("3_c6jpa")]([SubResource("Resource_ajt3x"), SubResource("Resource_sptlx"), SubResource("Resource_fqsrh"), SubResource("Resource_drex5"), SubResource("Resource_5lttf"), SubResource("Resource_umd7u")])
|
|
||||||
|
|
||||||
[node name="DayNightController" type="Node" parent="." unique_id=1083149574]
|
|
||||||
script = ExtResource("3_day_night")
|
|
||||||
time_of_day = 0.9185125217273991
|
|
||||||
current_day = 4
|
|
||||||
sun_color_curve = SubResource("Gradient_sxvon")
|
|
||||||
sun_intensity_curve = SubResource("Curve_fm80q")
|
|
||||||
moon_color_curve = SubResource("Gradient_kcyr7")
|
|
||||||
moon_intensity_curve = SubResource("Curve_qti3v")
|
|
||||||
ambient_color_curve = SubResource("Gradient_bq8yq")
|
|
||||||
ambient_intensity_curve = SubResource("Curve_x6xf2")
|
|
||||||
fog_color_curve = SubResource("Gradient_tn5up")
|
|
||||||
fog_density_curve = SubResource("Curve_ej5u1")
|
|
||||||
sky_top_color_curve = SubResource("Gradient_2w5ig")
|
|
||||||
sky_horizon_color_curve = SubResource("Gradient_cnx2n")
|
|
||||||
sky_bottom_color_curve = SubResource("Gradient_djhca")
|
|
||||||
stars_visibility_curve = SubResource("Curve_ta3fj")
|
|
||||||
|
|
||||||
[node name="WeatherController" type="Node" parent="." unique_id=1440281936]
|
|
||||||
script = ExtResource("4_weather")
|
|
||||||
weather_profiles = Array[ExtResource("8_cnx2n")]([SubResource("Resource_dfjcy"), SubResource("Resource_sjmt0"), SubResource("Resource_uap2q"), SubResource("Resource_mcoyn"), SubResource("Resource_mr14h"), SubResource("Resource_ps44b")])
|
|
||||||
transition_curve = SubResource("Curve_uhdsh")
|
|
||||||
|
|
||||||
[node name="CloudSystem" type="Node3D" parent="." unique_id=680200253]
|
|
||||||
script = ExtResource("5_clouds")
|
|
||||||
layer_configs = Array[ExtResource("4_ssi15")]([SubResource("Resource_xh4oc"), SubResource("Resource_ahi10"), SubResource("Resource_a5xai"), SubResource("Resource_uxs4q")])
|
|
||||||
global_coverage = 0.1
|
|
||||||
global_wind_speed = 0.5
|
|
||||||
sun_direction = Vector3(-0.46286085, -0.82338524, -0.32832408)
|
|
||||||
sun_color = Color(1, 0.95, 0.85, 1)
|
|
||||||
sun_intensity = 1.2
|
|
||||||
moon_direction = Vector3(-0.4780105, 0.85033494, 0.22008288)
|
|
||||||
moon_color = Color(0.8, 0.85, 1, 1)
|
|
||||||
moon_intensity = 0.0
|
|
||||||
|
|
||||||
[node name="PostProcessController" type="Node" parent="." unique_id=186747041]
|
|
||||||
script = ExtResource("6_post_process")
|
|
||||||
profile = SubResource("Resource_ssi15")
|
|
||||||
target_environment = ExtResource("13_2w5ig")
|
|
||||||
sky_top_color = Color(0.2, 0.4, 0.85, 1)
|
|
||||||
sky_horizon_color = Color(0.6, 0.75, 0.95, 1)
|
|
||||||
sky_bottom_color = Color(0.5, 0.6, 0.7, 1)
|
|
||||||
skybox_texture = ExtResource("6_ssi15")
|
|
||||||
fog_color = Color(0.26191625, 0.21975225, 0.23041001, 1)
|
|
||||||
fog_density = 0.018752154
|
|
||||||
sun_glow_intensity = 0.3
|
|
||||||
sun_glow_color = Color(1, 0.95, 0.85, 1)
|
|
||||||
sun_direction = Vector3(-0.46286085, -0.82338524, -0.32832408)
|
|
||||||
|
|
||||||
[node name="VFXController" type="Node3D" parent="." unique_id=207251300]
|
|
||||||
script = ExtResource("7_vfx")
|
|
||||||
|
|
||||||
[node name="ShadowProxySystem" type="Node3D" parent="." unique_id=1982828842]
|
|
||||||
script = ExtResource("8_shadows")
|
|
||||||
shadow_opacity = 0.05
|
|
||||||
flow_speed = 2.5
|
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=700760798]
|
|
||||||
environment = ExtResource("13_2w5ig")
|
|
||||||
compositor = SubResource("Compositor_ssi15")
|
|
||||||
|
|
||||||
[node name="SunLight" type="DirectionalLight3D" parent="." unique_id=1278065589]
|
|
||||||
transform = Transform3D(-0.5785618, 0.8155839, -0.009411784, 0, 0.011539156, 0.99993366, 0.8156382, 0.5785233, -0.00667612, 0, 50, 0)
|
|
||||||
visible = false
|
|
||||||
light_color = Color(1, 0.9021925, 0.804385, 1)
|
|
||||||
light_energy = 0.0
|
|
||||||
shadow_enabled = true
|
|
||||||
|
|
||||||
[node name="MoonLight" type="DirectionalLight3D" parent="." unique_id=52072807]
|
|
||||||
transform = Transform3D(0.41821608, 0.90829885, -0.009398041, 0, 0.010346303, 0.9999467, 0.90834737, -0.41819376, 0.004326992, 0, 50, 0)
|
|
||||||
light_color = Color(0.7, 0.8, 1, 1)
|
|
||||||
light_energy = 0.29958928
|
|
||||||
light_indirect_energy = 1.979
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
[gd_scene format=3 uid="uid://c0752ygxeq4rc"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://doiojb8xxlp2s" path="res://dynamic-sky/dynamic_sky.tscn" id="1_cuadp"]
|
|
||||||
[ext_resource type="Script" uid="uid://cimhpqq1qo80b" path="res://dynamic-sky/scripts/sky_debug_panel.gd" id="2_o3fwy"]
|
|
||||||
|
|
||||||
[node name="DynamicSkyToy" type="Node3D" unique_id=1968105337]
|
|
||||||
|
|
||||||
[node name="DynamicSky" parent="." unique_id=516593260 instance=ExtResource("1_cuadp")]
|
|
||||||
show_debug_panel = true
|
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="." unique_id=805686804]
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="." unique_id=83422594]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="SkyDebugPanel" type="Control" parent="Control" unique_id=1408698131]
|
|
||||||
anchors_preset = 0
|
|
||||||
offset_right = 40.0
|
|
||||||
offset_bottom = 40.0
|
|
||||||
script = ExtResource("2_o3fwy")
|
|
||||||
metadata/_custom_type_script = "uid://cimhpqq1qo80b"
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
[gd_resource type="Environment" format=3 uid="uid://dq64sos14f8hu"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://crrj260kiyoy" path="res://dynamic-sky/sky_44_2k.png" id="1_vd8dq"]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id="Shader_porxs"]
|
|
||||||
code = "
|
|
||||||
shader_type sky;
|
|
||||||
|
|
||||||
uniform sampler2D skybox_texture : source_color, filter_linear_mipmap, repeat_enable;
|
|
||||||
uniform bool skybox_enabled = false;
|
|
||||||
uniform float skybox_blend = 1.0;
|
|
||||||
|
|
||||||
uniform vec4 sky_top_color : source_color = vec4(0.2, 0.4, 0.8, 1.0);
|
|
||||||
uniform vec4 sky_horizon_color : source_color = vec4(0.6, 0.7, 0.9, 1.0);
|
|
||||||
uniform vec4 sky_bottom_color : source_color = vec4(0.4, 0.5, 0.6, 1.0);
|
|
||||||
uniform float gradient_intensity = 1.0;
|
|
||||||
uniform float horizon_blend = 0.5;
|
|
||||||
|
|
||||||
uniform bool sun_glow_enabled = true;
|
|
||||||
uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0);
|
|
||||||
uniform vec4 sun_glow_color : source_color = vec4(1.0, 0.95, 0.8, 1.0);
|
|
||||||
uniform float sun_glow_intensity = 0.5;
|
|
||||||
uniform float sun_glow_size = 0.2;
|
|
||||||
uniform float sun_glow_falloff = 2.0;
|
|
||||||
|
|
||||||
uniform bool dawn_dusk_enabled = true;
|
|
||||||
uniform vec4 dawn_dusk_color : source_color = vec4(1.0, 0.6, 0.4, 1.0);
|
|
||||||
uniform float dawn_dusk_intensity = 0.5;
|
|
||||||
uniform float dawn_dusk_blend = 0.0;
|
|
||||||
|
|
||||||
uniform float stars_visibility = 0.0;
|
|
||||||
uniform vec4 stars_tint : source_color = vec4(1.0);
|
|
||||||
|
|
||||||
float hash(vec2 p) {
|
|
||||||
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
float stars(vec3 dir) {
|
|
||||||
vec2 uv = dir.xz / (abs(dir.y) + 0.001) * 50.0;
|
|
||||||
vec2 cell = floor(uv);
|
|
||||||
vec2 local = fract(uv) - 0.5;
|
|
||||||
|
|
||||||
float star = 0.0;
|
|
||||||
float h = hash(cell);
|
|
||||||
if (h > 0.97) {
|
|
||||||
float dist = length(local);
|
|
||||||
star = smoothstep(0.1, 0.0, dist) * (h - 0.97) / 0.03;
|
|
||||||
star *= step(0.0, dir.y);
|
|
||||||
}
|
|
||||||
return star;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 pano_uv(vec3 dir) {
|
|
||||||
dir = normalize(dir);
|
|
||||||
float u = atan(dir.x, dir.z) / (2.0 * PI) + 0.5;
|
|
||||||
float v = acos(clamp(dir.y, -1.0, 1.0)) / PI;
|
|
||||||
return vec2(u, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sky() {
|
|
||||||
vec3 dir = EYEDIR;
|
|
||||||
float y = dir.y;
|
|
||||||
|
|
||||||
vec3 color;
|
|
||||||
if (y > 0.0) {
|
|
||||||
float t = pow(y, horizon_blend);
|
|
||||||
color = mix(sky_horizon_color.rgb, sky_top_color.rgb, t);
|
|
||||||
} else {
|
|
||||||
float t = pow(-y, horizon_blend);
|
|
||||||
color = mix(sky_horizon_color.rgb, sky_bottom_color.rgb, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = mix(vec3(0.5), color, gradient_intensity);
|
|
||||||
|
|
||||||
if (skybox_enabled) {
|
|
||||||
vec3 pano_color = texture(skybox_texture, pano_uv(dir)).rgb;
|
|
||||||
color = mix(color, pano_color, skybox_blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sun_glow_enabled && sun_direction.y > -0.2) {
|
|
||||||
float sun_dot = max(0.0, dot(dir, normalize(sun_direction)));
|
|
||||||
float glow = pow(sun_dot, 1.0 / max(0.001, sun_glow_size));
|
|
||||||
glow = pow(glow, sun_glow_falloff);
|
|
||||||
color += sun_glow_color.rgb * glow * sun_glow_intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dawn_dusk_enabled && dawn_dusk_blend > 0.0) {
|
|
||||||
float horizon_factor = 1.0 - abs(y);
|
|
||||||
horizon_factor = pow(horizon_factor, 2.0);
|
|
||||||
color = mix(color, dawn_dusk_color.rgb, horizon_factor * dawn_dusk_intensity * dawn_dusk_blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stars_visibility > 0.0 && y > 0.0) {
|
|
||||||
float star_value = stars(dir) * stars_visibility;
|
|
||||||
color += stars_tint.rgb * star_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
COLOR = color;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_jmmec"]
|
|
||||||
shader = SubResource("Shader_porxs")
|
|
||||||
shader_parameter/skybox_texture = ExtResource("1_vd8dq")
|
|
||||||
shader_parameter/skybox_enabled = true
|
|
||||||
shader_parameter/skybox_blend = 1.0
|
|
||||||
shader_parameter/sky_top_color = Color(0.2, 0.4, 0.85, 1)
|
|
||||||
shader_parameter/sky_horizon_color = Color(0.6, 0.75, 0.95, 1)
|
|
||||||
shader_parameter/sky_bottom_color = Color(0.5, 0.6, 0.7, 1)
|
|
||||||
shader_parameter/gradient_intensity = 1.0
|
|
||||||
shader_parameter/horizon_blend = 0.5
|
|
||||||
shader_parameter/sun_glow_enabled = true
|
|
||||||
shader_parameter/sun_direction = Vector3(-0.46286085, -0.82338524, -0.32832408)
|
|
||||||
shader_parameter/sun_glow_color = Color(1, 0.95, 0.85, 1)
|
|
||||||
shader_parameter/sun_glow_intensity = 0.3
|
|
||||||
shader_parameter/sun_glow_size = 0.2
|
|
||||||
shader_parameter/sun_glow_falloff = 2.0
|
|
||||||
shader_parameter/dawn_dusk_enabled = true
|
|
||||||
shader_parameter/dawn_dusk_color = Color(1, 0.6, 0.4, 1)
|
|
||||||
shader_parameter/dawn_dusk_intensity = 0.5
|
|
||||||
shader_parameter/dawn_dusk_blend = 0.0
|
|
||||||
shader_parameter/stars_visibility = 0.0
|
|
||||||
shader_parameter/stars_tint = Color(1, 1, 1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Sky" id="Sky_ssi15"]
|
|
||||||
sky_material = SubResource("ShaderMaterial_jmmec")
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
background_mode = 2
|
|
||||||
sky = SubResource("Sky_ssi15")
|
|
||||||
ambient_light_color = Color(0.23323175, 0.23041001, 0.30062926, 1)
|
|
||||||
ambient_light_energy = 0.078244984
|
|
||||||
fog_enabled = true
|
|
||||||
fog_light_color = Color(0.26191625, 0.21975225, 0.23041001, 1)
|
|
||||||
fog_density = 0.018752154
|
|
||||||
fog_height_density = 0.1
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" format=3 uid="uid://dose3mxe2snku"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c48eq2y4ikok8" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
[ext_resource type="Script" uid="uid://beu0xhk0rvpky" path="res://dynamic-sky/resources/cloud_layer_config.gd" id="1_5fmul"]
|
|
||||||
[ext_resource type="Script" uid="uid://c3iniqgu2l0ek" path="res://dynamic-sky/resources/sky_config.gd" id="2_2a7hp"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://crrj260kiyoy" path="res://dynamic-sky/sky_44_2k.png" id="4_a3ytv"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ktpc1"]
|
|
||||||
script = ExtResource("2_2a7hp")
|
|
||||||
metadata/_custom_type_script = "uid://c3iniqgu2l0ek"
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Clear Day"
|
|
||||||
preset_type = 0
|
|
||||||
config = SubResource("Resource_ktpc1")
|
|
||||||
skybox_texture = ExtResource("4_a3ytv")
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" format=3 uid="uid://cg0qi1v475fvo"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c48eq2y4ikok8" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
[ext_resource type="Script" uid="uid://beu0xhk0rvpky" path="res://dynamic-sky/resources/cloud_layer_config.gd" id="1_etfyk"]
|
|
||||||
[ext_resource type="Script" uid="uid://c3iniqgu2l0ek" path="res://dynamic-sky/resources/sky_config.gd" id="2_yd2ys"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://sl180wnwa3su" path="res://dynamic-sky/sky_25_2k.png" id="4_ckylf"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_o0y23"]
|
|
||||||
script = ExtResource("2_yd2ys")
|
|
||||||
metadata/_custom_type_script = "uid://c3iniqgu2l0ek"
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Dawn"
|
|
||||||
preset_type = 5
|
|
||||||
config = SubResource("Resource_o0y23")
|
|
||||||
skybox_texture = ExtResource("4_ckylf")
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" format=3 uid="uid://b08fj288b38q6"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c48eq2y4ikok8" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
[ext_resource type="Script" uid="uid://beu0xhk0rvpky" path="res://dynamic-sky/resources/cloud_layer_config.gd" id="1_eyyte"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cu4ogwg6537jc" path="res://dynamic-sky/sky_16_2k.png" id="3_75xut"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Night"
|
|
||||||
preset_type = 2
|
|
||||||
skybox_texture = ExtResource("3_75xut")
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" format=3 uid="uid://b6hytb5q01khi"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c48eq2y4ikok8" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
[ext_resource type="Script" uid="uid://beu0xhk0rvpky" path="res://dynamic-sky/resources/cloud_layer_config.gd" id="1_vtd2i"]
|
|
||||||
[ext_resource type="Script" uid="uid://c3iniqgu2l0ek" path="res://dynamic-sky/resources/sky_config.gd" id="2_1tetv"]
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_k34u2"]
|
|
||||||
script = ExtResource("2_1tetv")
|
|
||||||
metadata/_custom_type_script = "uid://c3iniqgu2l0ek"
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Overcast"
|
|
||||||
preset_type = 3
|
|
||||||
config = SubResource("Resource_k34u2")
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" load_steps=2 format=3]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Storm"
|
|
||||||
preset_type = 4
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
[gd_resource type="Resource" script_class="SkyPreset" load_steps=2 format=3]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://dynamic-sky/resources/sky_preset.gd" id="1"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1")
|
|
||||||
preset_name = "Sunset"
|
|
||||||
preset_type = 1
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name CloudLayerConfig
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
enum LayerType {
|
|
||||||
LOW,
|
|
||||||
MID,
|
|
||||||
HIGH,
|
|
||||||
WISPS
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var layer_type: LayerType = LayerType.MID
|
|
||||||
@export var enabled: bool = true
|
|
||||||
|
|
||||||
@export_group("Texture")
|
|
||||||
@export var texture: Texture2D
|
|
||||||
@export var texture_scale: Vector2 = Vector2(1.0, 1.0)
|
|
||||||
@export var tiling: Vector2 = Vector2(4.0, 4.0)
|
|
||||||
|
|
||||||
@export_group("Appearance")
|
|
||||||
@export var opacity: float = 0.8
|
|
||||||
@export var color_tint: Color = Color.WHITE
|
|
||||||
@export var shadow_color: Color = Color(0.6, 0.6, 0.7)
|
|
||||||
|
|
||||||
@export_group("Motion")
|
|
||||||
@export var flow_direction: Vector2 = Vector2(1.0, 0.0)
|
|
||||||
@export var flow_speed: float = 0.02
|
|
||||||
@export var parallax_depth: float = 1.0
|
|
||||||
|
|
||||||
@export_group("Lighting")
|
|
||||||
@export var receive_light: bool = true
|
|
||||||
@export var light_influence: float = 1.0
|
|
||||||
@export var rim_glow_intensity: float = 0.3
|
|
||||||
|
|
||||||
|
|
||||||
func get_layer_height() -> float:
|
|
||||||
match layer_type:
|
|
||||||
LayerType.LOW:
|
|
||||||
return 0.2
|
|
||||||
LayerType.MID:
|
|
||||||
return 0.5
|
|
||||||
LayerType.HIGH:
|
|
||||||
return 0.8
|
|
||||||
LayerType.WISPS:
|
|
||||||
return 0.9
|
|
||||||
return 0.5
|
|
||||||
|
|
||||||
|
|
||||||
func duplicate_config() -> CloudLayerConfig:
|
|
||||||
var copy := CloudLayerConfig.new()
|
|
||||||
copy.layer_type = layer_type
|
|
||||||
copy.enabled = enabled
|
|
||||||
copy.texture = texture
|
|
||||||
copy.texture_scale = texture_scale
|
|
||||||
copy.tiling = tiling
|
|
||||||
copy.opacity = opacity
|
|
||||||
copy.color_tint = color_tint
|
|
||||||
copy.shadow_color = shadow_color
|
|
||||||
copy.flow_direction = flow_direction
|
|
||||||
copy.flow_speed = flow_speed
|
|
||||||
copy.parallax_depth = parallax_depth
|
|
||||||
copy.receive_light = receive_light
|
|
||||||
copy.light_influence = light_influence
|
|
||||||
copy.rim_glow_intensity = rim_glow_intensity
|
|
||||||
return copy
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://beu0xhk0rvpky
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name PostProcessProfile
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
@export_group("Sky Gradient")
|
|
||||||
@export var gradient_enabled: bool = true
|
|
||||||
@export var gradient_intensity: float = 1.0
|
|
||||||
@export var gradient_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Fog Shaping")
|
|
||||||
@export var fog_enabled: bool = true
|
|
||||||
@export var height_fog_enabled: bool = true
|
|
||||||
@export var height_fog_start: float = 0.0
|
|
||||||
@export var height_fog_end: float = 100.0
|
|
||||||
@export var height_fog_curve: float = 1.0
|
|
||||||
@export var distance_fog_enabled: bool = true
|
|
||||||
@export var distance_fog_start: float = 50.0
|
|
||||||
@export var distance_fog_end: float = 500.0
|
|
||||||
|
|
||||||
@export_group("Sun Glow")
|
|
||||||
@export var sun_glow_enabled: bool = true
|
|
||||||
@export var sun_glow_intensity: float = 0.5
|
|
||||||
@export var sun_glow_size: float = 0.2
|
|
||||||
@export var sun_glow_falloff: float = 2.0
|
|
||||||
@export var sun_glow_color: Color = Color(1.0, 0.95, 0.8)
|
|
||||||
|
|
||||||
@export_group("Dawn/Dusk Enhancement")
|
|
||||||
@export var dawn_dusk_enabled: bool = true
|
|
||||||
@export var dawn_dusk_intensity: float = 0.5
|
|
||||||
@export var dawn_dusk_color: Color = Color(1.0, 0.6, 0.4)
|
|
||||||
@export var dawn_dusk_blend_range: float = 0.15
|
|
||||||
|
|
||||||
|
|
||||||
func lerp_to(other: PostProcessProfile, weight: float) -> PostProcessProfile:
|
|
||||||
var result := PostProcessProfile.new()
|
|
||||||
result.gradient_enabled = gradient_enabled if weight < 0.5 else other.gradient_enabled
|
|
||||||
result.gradient_intensity = lerpf(gradient_intensity, other.gradient_intensity, weight)
|
|
||||||
result.fog_enabled = fog_enabled if weight < 0.5 else other.fog_enabled
|
|
||||||
result.height_fog_enabled = height_fog_enabled if weight < 0.5 else other.height_fog_enabled
|
|
||||||
result.height_fog_start = lerpf(height_fog_start, other.height_fog_start, weight)
|
|
||||||
result.height_fog_end = lerpf(height_fog_end, other.height_fog_end, weight)
|
|
||||||
result.height_fog_curve = lerpf(height_fog_curve, other.height_fog_curve, weight)
|
|
||||||
result.distance_fog_enabled = distance_fog_enabled if weight < 0.5 else other.distance_fog_enabled
|
|
||||||
result.distance_fog_start = lerpf(distance_fog_start, other.distance_fog_start, weight)
|
|
||||||
result.distance_fog_end = lerpf(distance_fog_end, other.distance_fog_end, weight)
|
|
||||||
result.sun_glow_enabled = sun_glow_enabled if weight < 0.5 else other.sun_glow_enabled
|
|
||||||
result.sun_glow_intensity = lerpf(sun_glow_intensity, other.sun_glow_intensity, weight)
|
|
||||||
result.sun_glow_size = lerpf(sun_glow_size, other.sun_glow_size, weight)
|
|
||||||
result.sun_glow_falloff = lerpf(sun_glow_falloff, other.sun_glow_falloff, weight)
|
|
||||||
result.sun_glow_color = sun_glow_color.lerp(other.sun_glow_color, weight)
|
|
||||||
result.dawn_dusk_enabled = dawn_dusk_enabled if weight < 0.5 else other.dawn_dusk_enabled
|
|
||||||
result.dawn_dusk_intensity = lerpf(dawn_dusk_intensity, other.dawn_dusk_intensity, weight)
|
|
||||||
result.dawn_dusk_color = dawn_dusk_color.lerp(other.dawn_dusk_color, weight)
|
|
||||||
result.dawn_dusk_blend_range = lerpf(dawn_dusk_blend_range, other.dawn_dusk_blend_range, weight)
|
|
||||||
return result
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://ctrw2ycud36yd
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name SkyConfig
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
@export_group("Sun Settings")
|
|
||||||
@export var sun_color: Color = Color(1.0, 0.95, 0.8)
|
|
||||||
@export var sun_intensity: float = 1.0
|
|
||||||
@export var sun_size: float = 0.05
|
|
||||||
|
|
||||||
@export_group("Moon Settings")
|
|
||||||
@export var moon_color: Color = Color(0.8, 0.85, 1.0)
|
|
||||||
@export var moon_intensity: float = 0.8
|
|
||||||
@export var moon_size: float = 0.3
|
|
||||||
|
|
||||||
@export_group("Ambient Settings")
|
|
||||||
@export var ambient_color: Color = Color(0.4, 0.5, 0.6)
|
|
||||||
@export var ambient_intensity: float = 0.5
|
|
||||||
|
|
||||||
@export_group("Fog Settings")
|
|
||||||
@export var fog_color: Color = Color(0.7, 0.8, 0.9)
|
|
||||||
@export var fog_density: float = 0.01
|
|
||||||
@export var fog_height: float = 0.0
|
|
||||||
@export var fog_height_density: float = 0.1
|
|
||||||
|
|
||||||
@export_group("Sky Gradient")
|
|
||||||
@export var sky_top_color: Color = Color(0.2, 0.4, 0.8)
|
|
||||||
@export var sky_horizon_color: Color = Color(0.6, 0.7, 0.9)
|
|
||||||
@export var sky_bottom_color: Color = Color(0.4, 0.5, 0.6)
|
|
||||||
@export var horizon_blend: float = 0.5
|
|
||||||
|
|
||||||
@export_group("Stars")
|
|
||||||
@export var stars_visibility: float = 0.0
|
|
||||||
@export var stars_tint: Color = Color.WHITE
|
|
||||||
|
|
||||||
@export_group("Cloud Defaults")
|
|
||||||
@export var cloud_coverage: float = 0.3
|
|
||||||
@export var cloud_opacity: float = 0.8
|
|
||||||
@export var cloud_color: Color = Color.WHITE
|
|
||||||
@export var cloud_shadow_color: Color = Color(0.6, 0.6, 0.7)
|
|
||||||
|
|
||||||
@export_group("Post Process")
|
|
||||||
@export var sun_glow_intensity: float = 0.5
|
|
||||||
@export var sun_glow_size: float = 0.2
|
|
||||||
@export var gradient_intensity: float = 1.0
|
|
||||||
|
|
||||||
|
|
||||||
func lerp_to(other: SkyConfig, weight: float) -> SkyConfig:
|
|
||||||
var result := SkyConfig.new()
|
|
||||||
result.sun_color = sun_color.lerp(other.sun_color, weight)
|
|
||||||
result.sun_intensity = lerpf(sun_intensity, other.sun_intensity, weight)
|
|
||||||
result.sun_size = lerpf(sun_size, other.sun_size, weight)
|
|
||||||
result.moon_color = moon_color.lerp(other.moon_color, weight)
|
|
||||||
result.moon_intensity = lerpf(moon_intensity, other.moon_intensity, weight)
|
|
||||||
result.moon_size = lerpf(moon_size, other.moon_size, weight)
|
|
||||||
result.ambient_color = ambient_color.lerp(other.ambient_color, weight)
|
|
||||||
result.ambient_intensity = lerpf(ambient_intensity, other.ambient_intensity, weight)
|
|
||||||
result.fog_color = fog_color.lerp(other.fog_color, weight)
|
|
||||||
result.fog_density = lerpf(fog_density, other.fog_density, weight)
|
|
||||||
result.fog_height = lerpf(fog_height, other.fog_height, weight)
|
|
||||||
result.fog_height_density = lerpf(fog_height_density, other.fog_height_density, weight)
|
|
||||||
result.sky_top_color = sky_top_color.lerp(other.sky_top_color, weight)
|
|
||||||
result.sky_horizon_color = sky_horizon_color.lerp(other.sky_horizon_color, weight)
|
|
||||||
result.sky_bottom_color = sky_bottom_color.lerp(other.sky_bottom_color, weight)
|
|
||||||
result.horizon_blend = lerpf(horizon_blend, other.horizon_blend, weight)
|
|
||||||
result.stars_visibility = lerpf(stars_visibility, other.stars_visibility, weight)
|
|
||||||
result.stars_tint = stars_tint.lerp(other.stars_tint, weight)
|
|
||||||
result.cloud_coverage = lerpf(cloud_coverage, other.cloud_coverage, weight)
|
|
||||||
result.cloud_opacity = lerpf(cloud_opacity, other.cloud_opacity, weight)
|
|
||||||
result.cloud_color = cloud_color.lerp(other.cloud_color, weight)
|
|
||||||
result.cloud_shadow_color = cloud_shadow_color.lerp(other.cloud_shadow_color, weight)
|
|
||||||
result.sun_glow_intensity = lerpf(sun_glow_intensity, other.sun_glow_intensity, weight)
|
|
||||||
result.sun_glow_size = lerpf(sun_glow_size, other.sun_glow_size, weight)
|
|
||||||
result.gradient_intensity = lerpf(gradient_intensity, other.gradient_intensity, weight)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
func duplicate_config() -> SkyConfig:
|
|
||||||
var copy := SkyConfig.new()
|
|
||||||
copy.sun_color = sun_color
|
|
||||||
copy.sun_intensity = sun_intensity
|
|
||||||
copy.sun_size = sun_size
|
|
||||||
copy.moon_color = moon_color
|
|
||||||
copy.moon_intensity = moon_intensity
|
|
||||||
copy.moon_size = moon_size
|
|
||||||
copy.ambient_color = ambient_color
|
|
||||||
copy.ambient_intensity = ambient_intensity
|
|
||||||
copy.fog_color = fog_color
|
|
||||||
copy.fog_density = fog_density
|
|
||||||
copy.fog_height = fog_height
|
|
||||||
copy.fog_height_density = fog_height_density
|
|
||||||
copy.sky_top_color = sky_top_color
|
|
||||||
copy.sky_horizon_color = sky_horizon_color
|
|
||||||
copy.sky_bottom_color = sky_bottom_color
|
|
||||||
copy.horizon_blend = horizon_blend
|
|
||||||
copy.stars_visibility = stars_visibility
|
|
||||||
copy.stars_tint = stars_tint
|
|
||||||
copy.cloud_coverage = cloud_coverage
|
|
||||||
copy.cloud_opacity = cloud_opacity
|
|
||||||
copy.cloud_color = cloud_color
|
|
||||||
copy.cloud_shadow_color = cloud_shadow_color
|
|
||||||
copy.sun_glow_intensity = sun_glow_intensity
|
|
||||||
copy.sun_glow_size = sun_glow_size
|
|
||||||
copy.gradient_intensity = gradient_intensity
|
|
||||||
return copy
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c3iniqgu2l0ek
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name SkyPreset
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
enum PresetType {
|
|
||||||
CLEAR_DAY,
|
|
||||||
SUNSET,
|
|
||||||
NIGHT,
|
|
||||||
OVERCAST,
|
|
||||||
STORM,
|
|
||||||
DAWN,
|
|
||||||
CUSTOM
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var preset_name: String = "Custom"
|
|
||||||
@export var preset_type: PresetType = PresetType.CUSTOM
|
|
||||||
@export var config: SkyConfig
|
|
||||||
@export var skybox_texture: Texture2D
|
|
||||||
@export var cloud_layer_configs: Array[CloudLayerConfig]
|
|
||||||
@export var post_process_profile: PostProcessProfile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_clear_day() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Clear Day"
|
|
||||||
preset.preset_type = PresetType.CLEAR_DAY
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_color = Color(1.0, 0.95, 0.85)
|
|
||||||
preset.config.sun_intensity = 1.2
|
|
||||||
preset.config.moon_intensity = 0.0
|
|
||||||
preset.config.ambient_color = Color(0.5, 0.6, 0.8)
|
|
||||||
preset.config.ambient_intensity = 0.6
|
|
||||||
preset.config.fog_color = Color(0.7, 0.8, 0.95)
|
|
||||||
preset.config.fog_density = 0.005
|
|
||||||
preset.config.sky_top_color = Color(0.2, 0.4, 0.85)
|
|
||||||
preset.config.sky_horizon_color = Color(0.6, 0.75, 0.95)
|
|
||||||
preset.config.sky_bottom_color = Color(0.5, 0.6, 0.7)
|
|
||||||
preset.config.stars_visibility = 0.0
|
|
||||||
preset.config.cloud_coverage = 0.2
|
|
||||||
preset.config.cloud_opacity = 0.7
|
|
||||||
preset.config.sun_glow_intensity = 0.3
|
|
||||||
return preset
|
|
||||||
|
|
||||||
|
|
||||||
static func create_sunset() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Sunset"
|
|
||||||
preset.preset_type = PresetType.SUNSET
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_color = Color(1.0, 0.5, 0.2)
|
|
||||||
preset.config.sun_intensity = 0.8
|
|
||||||
preset.config.moon_intensity = 0.0
|
|
||||||
preset.config.ambient_color = Color(0.8, 0.5, 0.4)
|
|
||||||
preset.config.ambient_intensity = 0.4
|
|
||||||
preset.config.fog_color = Color(0.9, 0.6, 0.4)
|
|
||||||
preset.config.fog_density = 0.015
|
|
||||||
preset.config.sky_top_color = Color(0.3, 0.2, 0.5)
|
|
||||||
preset.config.sky_horizon_color = Color(1.0, 0.5, 0.3)
|
|
||||||
preset.config.sky_bottom_color = Color(0.9, 0.4, 0.2)
|
|
||||||
preset.config.stars_visibility = 0.1
|
|
||||||
preset.config.cloud_coverage = 0.3
|
|
||||||
preset.config.cloud_opacity = 0.9
|
|
||||||
preset.config.cloud_color = Color(1.0, 0.7, 0.5)
|
|
||||||
preset.config.cloud_shadow_color = Color(0.4, 0.2, 0.3)
|
|
||||||
preset.config.sun_glow_intensity = 0.8
|
|
||||||
preset.config.sun_glow_size = 0.4
|
|
||||||
return preset
|
|
||||||
|
|
||||||
|
|
||||||
static func create_night() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Night"
|
|
||||||
preset.preset_type = PresetType.NIGHT
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_intensity = 0.0
|
|
||||||
preset.config.moon_color = Color(0.7, 0.8, 1.0)
|
|
||||||
preset.config.moon_intensity = 0.4
|
|
||||||
preset.config.ambient_color = Color(0.1, 0.15, 0.25)
|
|
||||||
preset.config.ambient_intensity = 0.2
|
|
||||||
preset.config.fog_color = Color(0.1, 0.12, 0.2)
|
|
||||||
preset.config.fog_density = 0.02
|
|
||||||
preset.config.sky_top_color = Color(0.02, 0.03, 0.08)
|
|
||||||
preset.config.sky_horizon_color = Color(0.1, 0.12, 0.2)
|
|
||||||
preset.config.sky_bottom_color = Color(0.05, 0.06, 0.1)
|
|
||||||
preset.config.stars_visibility = 1.0
|
|
||||||
preset.config.cloud_coverage = 0.15
|
|
||||||
preset.config.cloud_opacity = 0.5
|
|
||||||
preset.config.cloud_color = Color(0.2, 0.22, 0.3)
|
|
||||||
preset.config.cloud_shadow_color = Color(0.05, 0.05, 0.1)
|
|
||||||
preset.config.sun_glow_intensity = 0.0
|
|
||||||
return preset
|
|
||||||
|
|
||||||
|
|
||||||
static func create_overcast() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Overcast"
|
|
||||||
preset.preset_type = PresetType.OVERCAST
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_color = Color(0.9, 0.9, 0.85)
|
|
||||||
preset.config.sun_intensity = 0.4
|
|
||||||
preset.config.moon_intensity = 0.0
|
|
||||||
preset.config.ambient_color = Color(0.5, 0.5, 0.55)
|
|
||||||
preset.config.ambient_intensity = 0.7
|
|
||||||
preset.config.fog_color = Color(0.6, 0.62, 0.65)
|
|
||||||
preset.config.fog_density = 0.03
|
|
||||||
preset.config.sky_top_color = Color(0.45, 0.48, 0.55)
|
|
||||||
preset.config.sky_horizon_color = Color(0.6, 0.62, 0.65)
|
|
||||||
preset.config.sky_bottom_color = Color(0.5, 0.52, 0.55)
|
|
||||||
preset.config.stars_visibility = 0.0
|
|
||||||
preset.config.cloud_coverage = 0.9
|
|
||||||
preset.config.cloud_opacity = 1.0
|
|
||||||
preset.config.cloud_color = Color(0.7, 0.72, 0.75)
|
|
||||||
preset.config.cloud_shadow_color = Color(0.4, 0.42, 0.45)
|
|
||||||
preset.config.sun_glow_intensity = 0.1
|
|
||||||
return preset
|
|
||||||
|
|
||||||
|
|
||||||
static func create_storm() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Storm"
|
|
||||||
preset.preset_type = PresetType.STORM
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_color = Color(0.7, 0.7, 0.75)
|
|
||||||
preset.config.sun_intensity = 0.2
|
|
||||||
preset.config.moon_intensity = 0.0
|
|
||||||
preset.config.ambient_color = Color(0.35, 0.38, 0.45)
|
|
||||||
preset.config.ambient_intensity = 0.5
|
|
||||||
preset.config.fog_color = Color(0.4, 0.42, 0.5)
|
|
||||||
preset.config.fog_density = 0.05
|
|
||||||
preset.config.sky_top_color = Color(0.25, 0.28, 0.35)
|
|
||||||
preset.config.sky_horizon_color = Color(0.4, 0.42, 0.48)
|
|
||||||
preset.config.sky_bottom_color = Color(0.35, 0.38, 0.42)
|
|
||||||
preset.config.stars_visibility = 0.0
|
|
||||||
preset.config.cloud_coverage = 1.0
|
|
||||||
preset.config.cloud_opacity = 1.0
|
|
||||||
preset.config.cloud_color = Color(0.4, 0.42, 0.5)
|
|
||||||
preset.config.cloud_shadow_color = Color(0.2, 0.22, 0.28)
|
|
||||||
preset.config.sun_glow_intensity = 0.0
|
|
||||||
return preset
|
|
||||||
|
|
||||||
|
|
||||||
static func create_dawn() -> SkyPreset:
|
|
||||||
var preset := SkyPreset.new()
|
|
||||||
preset.preset_name = "Dawn"
|
|
||||||
preset.preset_type = PresetType.DAWN
|
|
||||||
preset.config = SkyConfig.new()
|
|
||||||
preset.config.sun_color = Color(1.0, 0.7, 0.5)
|
|
||||||
preset.config.sun_intensity = 0.5
|
|
||||||
preset.config.moon_intensity = 0.1
|
|
||||||
preset.config.ambient_color = Color(0.4, 0.35, 0.45)
|
|
||||||
preset.config.ambient_intensity = 0.35
|
|
||||||
preset.config.fog_color = Color(0.6, 0.5, 0.55)
|
|
||||||
preset.config.fog_density = 0.025
|
|
||||||
preset.config.sky_top_color = Color(0.15, 0.2, 0.45)
|
|
||||||
preset.config.sky_horizon_color = Color(0.9, 0.6, 0.5)
|
|
||||||
preset.config.sky_bottom_color = Color(0.7, 0.45, 0.4)
|
|
||||||
preset.config.stars_visibility = 0.3
|
|
||||||
preset.config.cloud_coverage = 0.25
|
|
||||||
preset.config.cloud_opacity = 0.8
|
|
||||||
preset.config.cloud_color = Color(0.95, 0.7, 0.6)
|
|
||||||
preset.config.cloud_shadow_color = Color(0.3, 0.25, 0.35)
|
|
||||||
preset.config.sun_glow_intensity = 0.6
|
|
||||||
preset.config.sun_glow_size = 0.35
|
|
||||||
return preset
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c48eq2y4ikok8
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name WeatherProfile
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
enum WeatherState {
|
|
||||||
CLEAR,
|
|
||||||
CLOUDY,
|
|
||||||
OVERCAST,
|
|
||||||
RAIN,
|
|
||||||
STORM,
|
|
||||||
SNOW
|
|
||||||
}
|
|
||||||
|
|
||||||
@export var weather_state: WeatherState = WeatherState.CLEAR
|
|
||||||
@export var display_name: String = "Clear"
|
|
||||||
|
|
||||||
@export_group("Clouds")
|
|
||||||
@export var cloud_density: float = 0.2
|
|
||||||
@export var cloud_opacity: float = 0.7
|
|
||||||
@export var cloud_coverage: float = 0.3
|
|
||||||
@export var cloud_color: Color = Color.WHITE
|
|
||||||
@export var cloud_shadow_color: Color = Color(0.6, 0.6, 0.7)
|
|
||||||
|
|
||||||
@export_group("Wind")
|
|
||||||
@export var wind_speed: float = 1.0
|
|
||||||
@export var wind_direction: Vector2 = Vector2(1.0, 0.0)
|
|
||||||
@export var wind_turbulence: float = 0.1
|
|
||||||
|
|
||||||
@export_group("Ambient Adjustments")
|
|
||||||
@export var ambient_color_multiplier: Color = Color.WHITE
|
|
||||||
@export var ambient_intensity_multiplier: float = 1.0
|
|
||||||
|
|
||||||
@export_group("Fog Adjustments")
|
|
||||||
@export var fog_color_multiplier: Color = Color.WHITE
|
|
||||||
@export var fog_density_multiplier: float = 1.0
|
|
||||||
|
|
||||||
@export_group("VFX")
|
|
||||||
@export var rain_intensity: float = 0.0
|
|
||||||
@export var snow_intensity: float = 0.0
|
|
||||||
@export var lightning_enabled: bool = false
|
|
||||||
@export var lightning_frequency: float = 0.1
|
|
||||||
|
|
||||||
@export_group("Transition")
|
|
||||||
@export var default_transition_duration: float = 5.0
|
|
||||||
|
|
||||||
|
|
||||||
static func create_clear() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.CLEAR
|
|
||||||
profile.display_name = "Clear"
|
|
||||||
profile.cloud_density = 0.1
|
|
||||||
profile.cloud_opacity = 0.6
|
|
||||||
profile.cloud_coverage = 0.2
|
|
||||||
profile.wind_speed = 0.5
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_cloudy() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.CLOUDY
|
|
||||||
profile.display_name = "Cloudy"
|
|
||||||
profile.cloud_density = 0.5
|
|
||||||
profile.cloud_opacity = 0.8
|
|
||||||
profile.cloud_coverage = 0.5
|
|
||||||
profile.wind_speed = 1.0
|
|
||||||
profile.ambient_intensity_multiplier = 0.9
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_overcast() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.OVERCAST
|
|
||||||
profile.display_name = "Overcast"
|
|
||||||
profile.cloud_density = 0.9
|
|
||||||
profile.cloud_opacity = 1.0
|
|
||||||
profile.cloud_coverage = 0.9
|
|
||||||
profile.cloud_color = Color(0.7, 0.72, 0.75)
|
|
||||||
profile.wind_speed = 1.5
|
|
||||||
profile.ambient_intensity_multiplier = 0.7
|
|
||||||
profile.fog_density_multiplier = 1.5
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_rain() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.RAIN
|
|
||||||
profile.display_name = "Rain"
|
|
||||||
profile.cloud_density = 0.85
|
|
||||||
profile.cloud_opacity = 0.95
|
|
||||||
profile.cloud_coverage = 0.85
|
|
||||||
profile.cloud_color = Color(0.55, 0.58, 0.65)
|
|
||||||
profile.wind_speed = 2.0
|
|
||||||
profile.ambient_intensity_multiplier = 0.6
|
|
||||||
profile.fog_density_multiplier = 2.0
|
|
||||||
profile.rain_intensity = 0.7
|
|
||||||
profile.lightning_enabled = true
|
|
||||||
profile.lightning_frequency = 0.008
|
|
||||||
profile.default_transition_duration = 8.0
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_storm() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.STORM
|
|
||||||
profile.display_name = "Storm"
|
|
||||||
profile.cloud_density = 1.0
|
|
||||||
profile.cloud_opacity = 1.0
|
|
||||||
profile.cloud_coverage = 1.0
|
|
||||||
profile.cloud_color = Color(0.4, 0.42, 0.5)
|
|
||||||
profile.cloud_shadow_color = Color(0.2, 0.22, 0.28)
|
|
||||||
profile.wind_speed = 4.0
|
|
||||||
profile.wind_turbulence = 0.4
|
|
||||||
profile.ambient_intensity_multiplier = 0.4
|
|
||||||
profile.fog_density_multiplier = 3.0
|
|
||||||
profile.rain_intensity = 1.0
|
|
||||||
profile.lightning_enabled = true
|
|
||||||
profile.lightning_frequency = 0.15
|
|
||||||
profile.default_transition_duration = 10.0
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
static func create_snow() -> WeatherProfile:
|
|
||||||
var profile := WeatherProfile.new()
|
|
||||||
profile.weather_state = WeatherState.SNOW
|
|
||||||
profile.display_name = "Snow"
|
|
||||||
profile.cloud_density = 0.8
|
|
||||||
profile.cloud_opacity = 0.9
|
|
||||||
profile.cloud_coverage = 0.8
|
|
||||||
profile.cloud_color = Color(0.85, 0.87, 0.92)
|
|
||||||
profile.wind_speed = 1.0
|
|
||||||
profile.ambient_color_multiplier = Color(0.9, 0.92, 1.0)
|
|
||||||
profile.ambient_intensity_multiplier = 0.75
|
|
||||||
profile.fog_color_multiplier = Color(0.95, 0.97, 1.0)
|
|
||||||
profile.fog_density_multiplier = 1.8
|
|
||||||
profile.snow_intensity = 0.8
|
|
||||||
profile.default_transition_duration = 12.0
|
|
||||||
return profile
|
|
||||||
|
|
||||||
|
|
||||||
func lerp_to(other: WeatherProfile, weight: float) -> WeatherProfile:
|
|
||||||
var result := WeatherProfile.new()
|
|
||||||
result.weather_state = weather_state if weight < 0.5 else other.weather_state
|
|
||||||
result.display_name = display_name if weight < 0.5 else other.display_name
|
|
||||||
result.cloud_density = lerpf(cloud_density, other.cloud_density, weight)
|
|
||||||
result.cloud_opacity = lerpf(cloud_opacity, other.cloud_opacity, weight)
|
|
||||||
result.cloud_coverage = lerpf(cloud_coverage, other.cloud_coverage, weight)
|
|
||||||
result.cloud_color = cloud_color.lerp(other.cloud_color, weight)
|
|
||||||
result.cloud_shadow_color = cloud_shadow_color.lerp(other.cloud_shadow_color, weight)
|
|
||||||
result.wind_speed = lerpf(wind_speed, other.wind_speed, weight)
|
|
||||||
result.wind_direction = wind_direction.lerp(other.wind_direction, weight).normalized()
|
|
||||||
result.wind_turbulence = lerpf(wind_turbulence, other.wind_turbulence, weight)
|
|
||||||
result.ambient_color_multiplier = ambient_color_multiplier.lerp(other.ambient_color_multiplier, weight)
|
|
||||||
result.ambient_intensity_multiplier = lerpf(ambient_intensity_multiplier, other.ambient_intensity_multiplier, weight)
|
|
||||||
result.fog_color_multiplier = fog_color_multiplier.lerp(other.fog_color_multiplier, weight)
|
|
||||||
result.fog_density_multiplier = lerpf(fog_density_multiplier, other.fog_density_multiplier, weight)
|
|
||||||
result.rain_intensity = lerpf(rain_intensity, other.rain_intensity, weight)
|
|
||||||
result.snow_intensity = lerpf(snow_intensity, other.snow_intensity, weight)
|
|
||||||
result.lightning_enabled = lightning_enabled or other.lightning_enabled
|
|
||||||
result.lightning_frequency = lerpf(lightning_frequency, other.lightning_frequency, weight)
|
|
||||||
return result
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://d2srir3wsi045
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name CloudSystem2D
|
|
||||||
extends Node3D
|
|
||||||
|
|
||||||
signal cloud_coverage_changed(coverage: float)
|
|
||||||
|
|
||||||
const MAX_LAYERS := 4
|
|
||||||
|
|
||||||
@export_group("Cloud Layers")
|
|
||||||
@export var layer_configs: Array[CloudLayerConfig] = []
|
|
||||||
@export var global_coverage: float = 0.5:
|
|
||||||
set(value):
|
|
||||||
global_coverage = clampf(value, 0.0, 1.0)
|
|
||||||
_update_coverage()
|
|
||||||
cloud_coverage_changed.emit(global_coverage)
|
|
||||||
|
|
||||||
@export_group("Evolution")
|
|
||||||
@export var evolution_enabled: bool = true
|
|
||||||
@export var evolution_speed: float = 0.01
|
|
||||||
@export var evolution_scale: float = 1.0
|
|
||||||
@export var evolution_seed: int = 0
|
|
||||||
|
|
||||||
@export_group("Wind Override")
|
|
||||||
@export var use_global_wind: bool = true
|
|
||||||
@export var global_wind_direction: Vector2 = Vector2(1.0, 0.0)
|
|
||||||
@export var global_wind_speed: float = 1.0
|
|
||||||
|
|
||||||
@export_group("Lighting")
|
|
||||||
@export var sun_direction: Vector3 = Vector3(0.0, 1.0, 0.0)
|
|
||||||
@export var sun_color: Color = Color.WHITE
|
|
||||||
@export var sun_intensity: float = 1.0
|
|
||||||
@export var moon_direction: Vector3 = Vector3(0.0, -1.0, 0.0)
|
|
||||||
@export var moon_color: Color = Color(0.7, 0.8, 1.0)
|
|
||||||
@export var moon_intensity: float = 0.3
|
|
||||||
|
|
||||||
@export_group("Performance")
|
|
||||||
@export var update_rate: float = 60.0
|
|
||||||
|
|
||||||
var _cloud_materials: Array[ShaderMaterial] = []
|
|
||||||
var _cloud_meshes: Array[MeshInstance3D] = []
|
|
||||||
var _time_accumulator: float = 0.0
|
|
||||||
var _evolution_offset: float = 0.0
|
|
||||||
var _update_timer: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if layer_configs.is_empty():
|
|
||||||
_initialize_default_layers()
|
|
||||||
_create_cloud_meshes()
|
|
||||||
_update_all_layers()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
_update_timer += delta
|
|
||||||
var update_interval := 1.0 / update_rate
|
|
||||||
|
|
||||||
if _update_timer >= update_interval:
|
|
||||||
_update_timer = 0.0
|
|
||||||
_time_accumulator += delta * update_rate * update_interval
|
|
||||||
|
|
||||||
if evolution_enabled:
|
|
||||||
_evolution_offset += delta * evolution_speed
|
|
||||||
|
|
||||||
_update_flow(delta)
|
|
||||||
_update_lighting()
|
|
||||||
|
|
||||||
|
|
||||||
func _initialize_default_layers() -> void:
|
|
||||||
layer_configs.clear()
|
|
||||||
|
|
||||||
var low_layer := CloudLayerConfig.new()
|
|
||||||
low_layer.layer_type = CloudLayerConfig.LayerType.LOW
|
|
||||||
low_layer.opacity = 0.9
|
|
||||||
low_layer.flow_speed = 0.03
|
|
||||||
low_layer.parallax_depth = 0.3
|
|
||||||
low_layer.tiling = Vector2(2.0, 2.0)
|
|
||||||
layer_configs.append(low_layer)
|
|
||||||
|
|
||||||
var mid_layer := CloudLayerConfig.new()
|
|
||||||
mid_layer.layer_type = CloudLayerConfig.LayerType.MID
|
|
||||||
mid_layer.opacity = 0.7
|
|
||||||
mid_layer.flow_speed = 0.02
|
|
||||||
mid_layer.parallax_depth = 0.6
|
|
||||||
mid_layer.tiling = Vector2(3.0, 3.0)
|
|
||||||
layer_configs.append(mid_layer)
|
|
||||||
|
|
||||||
var high_layer := CloudLayerConfig.new()
|
|
||||||
high_layer.layer_type = CloudLayerConfig.LayerType.HIGH
|
|
||||||
high_layer.opacity = 0.5
|
|
||||||
high_layer.flow_speed = 0.01
|
|
||||||
high_layer.parallax_depth = 0.9
|
|
||||||
high_layer.tiling = Vector2(4.0, 4.0)
|
|
||||||
layer_configs.append(high_layer)
|
|
||||||
|
|
||||||
var wisps_layer := CloudLayerConfig.new()
|
|
||||||
wisps_layer.layer_type = CloudLayerConfig.LayerType.WISPS
|
|
||||||
wisps_layer.opacity = 0.3
|
|
||||||
wisps_layer.flow_speed = 0.015
|
|
||||||
wisps_layer.parallax_depth = 1.0
|
|
||||||
wisps_layer.tiling = Vector2(6.0, 6.0)
|
|
||||||
layer_configs.append(wisps_layer)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_cloud_meshes() -> void:
|
|
||||||
for mesh in _cloud_meshes:
|
|
||||||
if is_instance_valid(mesh):
|
|
||||||
mesh.queue_free()
|
|
||||||
_cloud_meshes.clear()
|
|
||||||
_cloud_materials.clear()
|
|
||||||
|
|
||||||
for i in layer_configs.size():
|
|
||||||
var config := layer_configs[i]
|
|
||||||
if not config.enabled:
|
|
||||||
continue
|
|
||||||
|
|
||||||
var mesh_instance := MeshInstance3D.new()
|
|
||||||
mesh_instance.name = "CloudLayer_%d" % i
|
|
||||||
|
|
||||||
var quad := QuadMesh.new()
|
|
||||||
quad.size = Vector2(1000.0, 1000.0)
|
|
||||||
quad.orientation = PlaneMesh.FACE_Y
|
|
||||||
mesh_instance.mesh = quad
|
|
||||||
|
|
||||||
var material := _create_cloud_material(config)
|
|
||||||
mesh_instance.material_override = material
|
|
||||||
|
|
||||||
var height := config.get_layer_height() * 100.0 + 50.0
|
|
||||||
mesh_instance.position.y = height
|
|
||||||
|
|
||||||
add_child(mesh_instance)
|
|
||||||
_cloud_meshes.append(mesh_instance)
|
|
||||||
_cloud_materials.append(material)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_cloud_material(config: CloudLayerConfig) -> ShaderMaterial:
|
|
||||||
var material := ShaderMaterial.new()
|
|
||||||
material.shader = _get_cloud_shader()
|
|
||||||
|
|
||||||
material.set_shader_parameter("tiling", config.tiling)
|
|
||||||
material.set_shader_parameter("opacity", config.opacity * global_coverage)
|
|
||||||
material.set_shader_parameter("color_tint", config.color_tint)
|
|
||||||
material.set_shader_parameter("shadow_color", config.shadow_color)
|
|
||||||
material.set_shader_parameter("flow_direction", config.flow_direction)
|
|
||||||
material.set_shader_parameter("flow_speed", config.flow_speed)
|
|
||||||
material.set_shader_parameter("light_influence", config.light_influence)
|
|
||||||
material.set_shader_parameter("rim_glow_intensity", config.rim_glow_intensity)
|
|
||||||
|
|
||||||
if config.texture:
|
|
||||||
material.set_shader_parameter("cloud_texture", config.texture)
|
|
||||||
else:
|
|
||||||
var procedural_tex := ProceduralCloudTexture.create_default_cloud_texture(config.layer_type)
|
|
||||||
material.set_shader_parameter("cloud_texture", procedural_tex)
|
|
||||||
|
|
||||||
return material
|
|
||||||
|
|
||||||
|
|
||||||
func _get_cloud_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type spatial;
|
|
||||||
render_mode unshaded, depth_draw_never, cull_disabled;
|
|
||||||
|
|
||||||
uniform sampler2D cloud_texture : source_color, filter_linear_mipmap, repeat_enable;
|
|
||||||
uniform vec2 tiling = vec2(4.0, 4.0);
|
|
||||||
uniform float opacity = 0.8;
|
|
||||||
uniform vec4 color_tint : source_color = vec4(1.0);
|
|
||||||
uniform vec4 shadow_color : source_color = vec4(0.6, 0.6, 0.7, 1.0);
|
|
||||||
uniform vec2 flow_direction = vec2(1.0, 0.0);
|
|
||||||
uniform float flow_speed = 0.02;
|
|
||||||
uniform float flow_offset = 0.0;
|
|
||||||
uniform vec3 light_direction = vec3(0.0, 1.0, 0.0);
|
|
||||||
uniform vec4 light_color : source_color = vec4(1.0);
|
|
||||||
uniform float light_intensity = 1.0;
|
|
||||||
uniform float light_influence = 1.0;
|
|
||||||
uniform float rim_glow_intensity = 0.3;
|
|
||||||
uniform float evolution_offset = 0.0;
|
|
||||||
uniform float coverage = 1.0;
|
|
||||||
|
|
||||||
varying vec2 world_uv;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
world_uv = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 uv = world_uv * tiling * 0.001;
|
|
||||||
uv += flow_direction * flow_offset;
|
|
||||||
|
|
||||||
vec2 distorted_uv = uv + vec2(sin(uv.y * 10.0 + evolution_offset) * 0.01, cos(uv.x * 10.0 + evolution_offset) * 0.01);
|
|
||||||
|
|
||||||
vec4 cloud_sample = texture(cloud_texture, distorted_uv);
|
|
||||||
float cloud_alpha = cloud_sample.r * opacity * coverage;
|
|
||||||
|
|
||||||
float light_dot = dot(normalize(light_direction), vec3(0.0, 1.0, 0.0));
|
|
||||||
float light_factor = mix(0.5, 1.0, (light_dot + 1.0) * 0.5) * light_influence;
|
|
||||||
|
|
||||||
vec3 lit_color = mix(shadow_color.rgb, color_tint.rgb, light_factor);
|
|
||||||
lit_color *= light_color.rgb * light_intensity;
|
|
||||||
|
|
||||||
float rim = pow(1.0 - cloud_sample.r, 2.0) * rim_glow_intensity;
|
|
||||||
lit_color += light_color.rgb * rim;
|
|
||||||
|
|
||||||
ALBEDO = lit_color;
|
|
||||||
ALPHA = cloud_alpha;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
|
|
||||||
|
|
||||||
func _update_flow(delta: float) -> void:
|
|
||||||
for i in _cloud_materials.size():
|
|
||||||
if i >= layer_configs.size():
|
|
||||||
continue
|
|
||||||
|
|
||||||
var config := layer_configs[i]
|
|
||||||
var material := _cloud_materials[i]
|
|
||||||
|
|
||||||
var wind_dir := global_wind_direction if use_global_wind else config.flow_direction
|
|
||||||
var wind_spd := global_wind_speed if use_global_wind else 1.0
|
|
||||||
var current_offset: Variant = material.get_shader_parameter("flow_offset")
|
|
||||||
var flow_offset: float = current_offset if current_offset != null else 0.0
|
|
||||||
flow_offset += config.flow_speed * wind_spd * delta
|
|
||||||
|
|
||||||
material.set_shader_parameter("flow_offset", flow_offset)
|
|
||||||
material.set_shader_parameter("flow_direction", wind_dir)
|
|
||||||
material.set_shader_parameter("evolution_offset", _evolution_offset)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_lighting() -> void:
|
|
||||||
for material in _cloud_materials:
|
|
||||||
material.set_shader_parameter("light_direction", sun_direction)
|
|
||||||
material.set_shader_parameter("light_color", sun_color)
|
|
||||||
material.set_shader_parameter("light_intensity", sun_intensity)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_coverage() -> void:
|
|
||||||
for i in _cloud_materials.size():
|
|
||||||
if i >= layer_configs.size():
|
|
||||||
continue
|
|
||||||
var config := layer_configs[i]
|
|
||||||
_cloud_materials[i].set_shader_parameter("coverage", global_coverage)
|
|
||||||
_cloud_materials[i].set_shader_parameter("opacity", config.opacity)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_all_layers() -> void:
|
|
||||||
for i in _cloud_materials.size():
|
|
||||||
if i >= layer_configs.size():
|
|
||||||
continue
|
|
||||||
var config := layer_configs[i]
|
|
||||||
var material := _cloud_materials[i]
|
|
||||||
|
|
||||||
material.set_shader_parameter("tiling", config.tiling)
|
|
||||||
material.set_shader_parameter("opacity", config.opacity)
|
|
||||||
material.set_shader_parameter("color_tint", config.color_tint)
|
|
||||||
material.set_shader_parameter("shadow_color", config.shadow_color)
|
|
||||||
material.set_shader_parameter("flow_direction", config.flow_direction)
|
|
||||||
material.set_shader_parameter("flow_speed", config.flow_speed)
|
|
||||||
material.set_shader_parameter("light_influence", config.light_influence)
|
|
||||||
material.set_shader_parameter("rim_glow_intensity", config.rim_glow_intensity)
|
|
||||||
material.set_shader_parameter("coverage", global_coverage)
|
|
||||||
|
|
||||||
|
|
||||||
func set_layer_enabled(layer_index: int, enabled: bool) -> void:
|
|
||||||
if layer_index < 0 or layer_index >= _cloud_meshes.size():
|
|
||||||
return
|
|
||||||
_cloud_meshes[layer_index].visible = enabled
|
|
||||||
|
|
||||||
|
|
||||||
func set_layer_opacity(layer_index: int, opacity: float) -> void:
|
|
||||||
if layer_index < 0 or layer_index >= _cloud_materials.size():
|
|
||||||
return
|
|
||||||
if layer_index < layer_configs.size():
|
|
||||||
layer_configs[layer_index].opacity = opacity
|
|
||||||
_cloud_materials[layer_index].set_shader_parameter("opacity", opacity)
|
|
||||||
|
|
||||||
|
|
||||||
func set_layer_color(layer_index: int, color: Color) -> void:
|
|
||||||
if layer_index < 0 or layer_index >= _cloud_materials.size():
|
|
||||||
return
|
|
||||||
if layer_index < layer_configs.size():
|
|
||||||
layer_configs[layer_index].color_tint = color
|
|
||||||
_cloud_materials[layer_index].set_shader_parameter("color_tint", color)
|
|
||||||
|
|
||||||
|
|
||||||
func set_global_wind(direction: Vector2, speed: float) -> void:
|
|
||||||
global_wind_direction = direction.normalized()
|
|
||||||
global_wind_speed = speed
|
|
||||||
|
|
||||||
|
|
||||||
func set_sun_lighting(direction: Vector3, color: Color, intensity: float) -> void:
|
|
||||||
sun_direction = direction.normalized()
|
|
||||||
sun_color = color
|
|
||||||
sun_intensity = intensity
|
|
||||||
_update_lighting()
|
|
||||||
|
|
||||||
|
|
||||||
func set_moon_lighting(direction: Vector3, color: Color, intensity: float) -> void:
|
|
||||||
moon_direction = direction.normalized()
|
|
||||||
moon_color = color
|
|
||||||
moon_intensity = intensity
|
|
||||||
|
|
||||||
|
|
||||||
func rebuild_layers() -> void:
|
|
||||||
_create_cloud_meshes()
|
|
||||||
_update_all_layers()
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cwplvsarljsf
|
|
||||||
@@ -1,369 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name DayNightController
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
signal time_changed(time_of_day: float)
|
|
||||||
signal hour_changed(hour: int)
|
|
||||||
signal day_changed(day: int)
|
|
||||||
signal sunrise_started()
|
|
||||||
signal sunset_started()
|
|
||||||
signal night_started()
|
|
||||||
signal noon_reached()
|
|
||||||
|
|
||||||
const HOURS_PER_DAY := 24.0
|
|
||||||
const SUNRISE_START := 0.2 # ~5 AM
|
|
||||||
const SUNRISE_END := 0.3 # ~7 AM
|
|
||||||
const SUNSET_START := 0.75 # ~6 PM
|
|
||||||
const SUNSET_END := 0.85 # ~8 PM
|
|
||||||
const NOON := 0.5
|
|
||||||
|
|
||||||
@export_group("Time Settings")
|
|
||||||
@export var time_of_day: float = 0.25:
|
|
||||||
set(value):
|
|
||||||
var old_hour := get_current_hour()
|
|
||||||
time_of_day = wrapf(value, 0.0, 1.0)
|
|
||||||
var new_hour := get_current_hour()
|
|
||||||
if old_hour != new_hour:
|
|
||||||
hour_changed.emit(new_hour)
|
|
||||||
time_changed.emit(time_of_day)
|
|
||||||
_check_time_events(old_hour, new_hour)
|
|
||||||
|
|
||||||
@export var day_length_minutes: float = 30.0:
|
|
||||||
set(value):
|
|
||||||
day_length_minutes = clampf(value, 1.0, 1440.0)
|
|
||||||
|
|
||||||
@export var paused: bool = false
|
|
||||||
@export var time_scale: float = 1.0
|
|
||||||
@export var current_day: int = 1
|
|
||||||
|
|
||||||
@export_group("Sun Arc")
|
|
||||||
@export var sun_arc_tilt: float = 23.5
|
|
||||||
@export var sun_arc_offset: float = 0.0
|
|
||||||
|
|
||||||
@export_group("Moon Arc")
|
|
||||||
@export var moon_arc_tilt: float = 15.0
|
|
||||||
@export var moon_arc_offset: float = 180.0
|
|
||||||
@export var moon_phase: float = 0.0
|
|
||||||
|
|
||||||
@export_group("Sun Curves")
|
|
||||||
@export var sun_color_curve: Gradient
|
|
||||||
@export var sun_intensity_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Moon Curves")
|
|
||||||
@export var moon_color_curve: Gradient
|
|
||||||
@export var moon_intensity_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Ambient Curves")
|
|
||||||
@export var ambient_color_curve: Gradient
|
|
||||||
@export var ambient_intensity_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Fog Curves")
|
|
||||||
@export var fog_color_curve: Gradient
|
|
||||||
@export var fog_density_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Sky Gradient Curves")
|
|
||||||
@export var sky_top_color_curve: Gradient
|
|
||||||
@export var sky_horizon_color_curve: Gradient
|
|
||||||
@export var sky_bottom_color_curve: Gradient
|
|
||||||
|
|
||||||
@export_group("Stars")
|
|
||||||
@export var stars_visibility_curve: Curve
|
|
||||||
|
|
||||||
var _last_hour: int = -1
|
|
||||||
var _sunrise_emitted := false
|
|
||||||
var _sunset_emitted := false
|
|
||||||
var _night_emitted := false
|
|
||||||
var _noon_emitted := false
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_initialize_default_curves()
|
|
||||||
_last_hour = get_current_hour()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if paused:
|
|
||||||
return
|
|
||||||
|
|
||||||
var time_increment := delta / (day_length_minutes * 60.0) * time_scale
|
|
||||||
var old_time := time_of_day
|
|
||||||
time_of_day += time_increment
|
|
||||||
|
|
||||||
if time_of_day < old_time:
|
|
||||||
current_day += 1
|
|
||||||
day_changed.emit(current_day)
|
|
||||||
_reset_time_events()
|
|
||||||
|
|
||||||
|
|
||||||
func _initialize_default_curves() -> void:
|
|
||||||
if sun_color_curve == null:
|
|
||||||
sun_color_curve = Gradient.new()
|
|
||||||
sun_color_curve.set_color(0, Color(1.0, 0.6, 0.4)) # Dawn
|
|
||||||
sun_color_curve.add_point(0.25, Color(1.0, 0.95, 0.85)) # Morning
|
|
||||||
sun_color_curve.add_point(0.5, Color(1.0, 1.0, 0.95)) # Noon
|
|
||||||
sun_color_curve.add_point(0.75, Color(1.0, 0.7, 0.4)) # Sunset
|
|
||||||
sun_color_curve.set_color(1, Color(1.0, 0.5, 0.3)) # Dusk
|
|
||||||
|
|
||||||
if sun_intensity_curve == null:
|
|
||||||
sun_intensity_curve = Curve.new()
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.0, 0.0))
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.2, 0.0))
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.3, 0.8))
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.5, 1.0))
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.7, 0.8))
|
|
||||||
sun_intensity_curve.add_point(Vector2(0.85, 0.0))
|
|
||||||
sun_intensity_curve.add_point(Vector2(1.0, 0.0))
|
|
||||||
|
|
||||||
if moon_color_curve == null:
|
|
||||||
moon_color_curve = Gradient.new()
|
|
||||||
moon_color_curve.set_color(0, Color(0.7, 0.8, 1.0))
|
|
||||||
moon_color_curve.set_color(1, Color(0.7, 0.8, 1.0))
|
|
||||||
|
|
||||||
if moon_intensity_curve == null:
|
|
||||||
moon_intensity_curve = Curve.new()
|
|
||||||
moon_intensity_curve.add_point(Vector2(0.0, 0.4))
|
|
||||||
moon_intensity_curve.add_point(Vector2(0.15, 0.3))
|
|
||||||
moon_intensity_curve.add_point(Vector2(0.22, 0.0))
|
|
||||||
moon_intensity_curve.add_point(Vector2(0.85, 0.0))
|
|
||||||
moon_intensity_curve.add_point(Vector2(0.92, 0.3))
|
|
||||||
moon_intensity_curve.add_point(Vector2(1.0, 0.4))
|
|
||||||
|
|
||||||
if ambient_color_curve == null:
|
|
||||||
ambient_color_curve = Gradient.new()
|
|
||||||
ambient_color_curve.set_color(0, Color(0.15, 0.18, 0.3)) # Night
|
|
||||||
ambient_color_curve.add_point(0.25, Color(0.5, 0.55, 0.65)) # Morning
|
|
||||||
ambient_color_curve.add_point(0.5, Color(0.6, 0.65, 0.75)) # Noon
|
|
||||||
ambient_color_curve.add_point(0.75, Color(0.55, 0.5, 0.55)) # Evening
|
|
||||||
ambient_color_curve.set_color(1, Color(0.15, 0.18, 0.3)) # Night
|
|
||||||
|
|
||||||
if ambient_intensity_curve == null:
|
|
||||||
ambient_intensity_curve = Curve.new()
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.0, 0.05))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.2, 0.1))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.3, 0.5))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.5, 0.6))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.7, 0.5))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(0.85, 0.1))
|
|
||||||
ambient_intensity_curve.add_point(Vector2(1.0, 0.05))
|
|
||||||
|
|
||||||
if fog_color_curve == null:
|
|
||||||
fog_color_curve = Gradient.new()
|
|
||||||
fog_color_curve.set_color(0, Color(0.1, 0.12, 0.2))
|
|
||||||
fog_color_curve.add_point(0.25, Color(0.6, 0.65, 0.75))
|
|
||||||
fog_color_curve.add_point(0.5, Color(0.7, 0.75, 0.85))
|
|
||||||
fog_color_curve.add_point(0.75, Color(0.7, 0.55, 0.5))
|
|
||||||
fog_color_curve.set_color(1, Color(0.1, 0.12, 0.2))
|
|
||||||
|
|
||||||
if fog_density_curve == null:
|
|
||||||
fog_density_curve = Curve.new()
|
|
||||||
fog_density_curve.add_point(Vector2(0.0, 0.02))
|
|
||||||
fog_density_curve.add_point(Vector2(0.25, 0.015))
|
|
||||||
fog_density_curve.add_point(Vector2(0.5, 0.01))
|
|
||||||
fog_density_curve.add_point(Vector2(0.75, 0.015))
|
|
||||||
fog_density_curve.add_point(Vector2(1.0, 0.02))
|
|
||||||
|
|
||||||
if sky_top_color_curve == null:
|
|
||||||
sky_top_color_curve = Gradient.new()
|
|
||||||
sky_top_color_curve.set_color(0, Color(0.01, 0.01, 0.04)) # Midnight
|
|
||||||
sky_top_color_curve.add_point(0.2, Color(0.03, 0.05, 0.1)) # Pre-dawn
|
|
||||||
sky_top_color_curve.add_point(0.3, Color(0.18, 0.35, 0.8)) # Morning
|
|
||||||
sky_top_color_curve.add_point(0.5, Color(0.15, 0.35, 0.82)) # Noon
|
|
||||||
sky_top_color_curve.add_point(0.75, Color(0.12, 0.15, 0.4)) # Sunset
|
|
||||||
sky_top_color_curve.add_point(0.85, Color(0.02, 0.02, 0.06)) # Dusk end
|
|
||||||
sky_top_color_curve.set_color(1, Color(0.01, 0.01, 0.04)) # Midnight
|
|
||||||
|
|
||||||
if sky_horizon_color_curve == null:
|
|
||||||
sky_horizon_color_curve = Gradient.new()
|
|
||||||
sky_horizon_color_curve.set_color(0, Color(0.03, 0.04, 0.08)) # Midnight
|
|
||||||
sky_horizon_color_curve.add_point(0.2, Color(0.3, 0.22, 0.28)) # Pre-dawn
|
|
||||||
sky_horizon_color_curve.add_point(0.25, Color(0.85, 0.55, 0.45))# Dawn
|
|
||||||
sky_horizon_color_curve.add_point(0.35, Color(0.45, 0.6, 0.85))# Morning
|
|
||||||
sky_horizon_color_curve.add_point(0.5, Color(0.5, 0.65, 0.88)) # Noon
|
|
||||||
sky_horizon_color_curve.add_point(0.75, Color(0.95, 0.45, 0.25))# Sunset
|
|
||||||
sky_horizon_color_curve.add_point(0.85, Color(0.06, 0.06, 0.1))# Dusk end
|
|
||||||
sky_horizon_color_curve.set_color(1, Color(0.03, 0.04, 0.08)) # Midnight
|
|
||||||
|
|
||||||
if sky_bottom_color_curve == null:
|
|
||||||
sky_bottom_color_curve = Gradient.new()
|
|
||||||
sky_bottom_color_curve.set_color(0, Color(0.02, 0.02, 0.05)) # Midnight
|
|
||||||
sky_bottom_color_curve.add_point(0.2, Color(0.12, 0.1, 0.15)) # Pre-dawn
|
|
||||||
sky_bottom_color_curve.add_point(0.3, Color(0.35, 0.45, 0.55)) # Morning
|
|
||||||
sky_bottom_color_curve.add_point(0.5, Color(0.35, 0.45, 0.55)) # Noon
|
|
||||||
sky_bottom_color_curve.add_point(0.75, Color(0.3, 0.2, 0.2)) # Sunset
|
|
||||||
sky_bottom_color_curve.add_point(0.85, Color(0.03, 0.03, 0.06))# Dusk end
|
|
||||||
sky_bottom_color_curve.set_color(1, Color(0.02, 0.02, 0.05)) # Midnight
|
|
||||||
|
|
||||||
if stars_visibility_curve == null:
|
|
||||||
stars_visibility_curve = Curve.new()
|
|
||||||
stars_visibility_curve.add_point(Vector2(0.0, 1.0))
|
|
||||||
stars_visibility_curve.add_point(Vector2(0.2, 0.8))
|
|
||||||
stars_visibility_curve.add_point(Vector2(0.3, 0.0))
|
|
||||||
stars_visibility_curve.add_point(Vector2(0.7, 0.0))
|
|
||||||
stars_visibility_curve.add_point(Vector2(0.85, 0.8))
|
|
||||||
stars_visibility_curve.add_point(Vector2(1.0, 1.0))
|
|
||||||
|
|
||||||
|
|
||||||
func _check_time_events(old_hour: int, new_hour: int) -> void:
|
|
||||||
if time_of_day >= SUNRISE_START and time_of_day < SUNRISE_END and not _sunrise_emitted:
|
|
||||||
_sunrise_emitted = true
|
|
||||||
sunrise_started.emit()
|
|
||||||
|
|
||||||
if time_of_day >= SUNSET_START and time_of_day < SUNSET_END and not _sunset_emitted:
|
|
||||||
_sunset_emitted = true
|
|
||||||
sunset_started.emit()
|
|
||||||
|
|
||||||
if time_of_day >= SUNSET_END and not _night_emitted:
|
|
||||||
_night_emitted = true
|
|
||||||
night_started.emit()
|
|
||||||
|
|
||||||
if time_of_day >= NOON - 0.01 and time_of_day < NOON + 0.01 and not _noon_emitted:
|
|
||||||
_noon_emitted = true
|
|
||||||
noon_reached.emit()
|
|
||||||
|
|
||||||
|
|
||||||
func _reset_time_events() -> void:
|
|
||||||
_sunrise_emitted = false
|
|
||||||
_sunset_emitted = false
|
|
||||||
_night_emitted = false
|
|
||||||
_noon_emitted = false
|
|
||||||
|
|
||||||
|
|
||||||
func get_current_hour() -> int:
|
|
||||||
return int(time_of_day * HOURS_PER_DAY)
|
|
||||||
|
|
||||||
|
|
||||||
func get_current_hour_float() -> float:
|
|
||||||
return time_of_day * HOURS_PER_DAY
|
|
||||||
|
|
||||||
|
|
||||||
func set_time_from_hours(hours: float) -> void:
|
|
||||||
time_of_day = fmod(hours, HOURS_PER_DAY) / HOURS_PER_DAY
|
|
||||||
|
|
||||||
|
|
||||||
func get_sun_direction() -> Vector3:
|
|
||||||
var angle := (time_of_day - 0.25) * TAU
|
|
||||||
var tilt_rad := deg_to_rad(sun_arc_tilt)
|
|
||||||
var offset_rad := deg_to_rad(sun_arc_offset)
|
|
||||||
|
|
||||||
var direction := Vector3(
|
|
||||||
cos(angle + offset_rad),
|
|
||||||
sin(angle),
|
|
||||||
sin(angle) * sin(tilt_rad)
|
|
||||||
).normalized()
|
|
||||||
|
|
||||||
return direction
|
|
||||||
|
|
||||||
|
|
||||||
func get_moon_direction() -> Vector3:
|
|
||||||
var angle := (time_of_day + 0.25) * TAU
|
|
||||||
var tilt_rad := deg_to_rad(moon_arc_tilt)
|
|
||||||
var offset_rad := deg_to_rad(moon_arc_offset)
|
|
||||||
|
|
||||||
var direction := Vector3(
|
|
||||||
cos(angle + offset_rad),
|
|
||||||
sin(angle),
|
|
||||||
sin(angle) * sin(tilt_rad)
|
|
||||||
).normalized()
|
|
||||||
|
|
||||||
return direction
|
|
||||||
|
|
||||||
|
|
||||||
func get_sun_color() -> Color:
|
|
||||||
if sun_color_curve:
|
|
||||||
return sun_color_curve.sample(time_of_day)
|
|
||||||
return Color.WHITE
|
|
||||||
|
|
||||||
|
|
||||||
func get_sun_intensity() -> float:
|
|
||||||
if sun_intensity_curve:
|
|
||||||
return sun_intensity_curve.sample(time_of_day)
|
|
||||||
return 1.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_moon_color() -> Color:
|
|
||||||
if moon_color_curve:
|
|
||||||
return moon_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.7, 0.8, 1.0)
|
|
||||||
|
|
||||||
|
|
||||||
func get_moon_intensity() -> float:
|
|
||||||
var base_intensity := 1.0
|
|
||||||
if moon_intensity_curve:
|
|
||||||
base_intensity = moon_intensity_curve.sample(time_of_day)
|
|
||||||
var phase_factor := 0.5 + 0.5 * cos(moon_phase * TAU)
|
|
||||||
return base_intensity * phase_factor
|
|
||||||
|
|
||||||
|
|
||||||
func get_ambient_color() -> Color:
|
|
||||||
if ambient_color_curve:
|
|
||||||
return ambient_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.5, 0.55, 0.65)
|
|
||||||
|
|
||||||
|
|
||||||
func get_ambient_intensity() -> float:
|
|
||||||
if ambient_intensity_curve:
|
|
||||||
return ambient_intensity_curve.sample(time_of_day)
|
|
||||||
return 0.5
|
|
||||||
|
|
||||||
|
|
||||||
func get_fog_color() -> Color:
|
|
||||||
if fog_color_curve:
|
|
||||||
return fog_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.7, 0.75, 0.85)
|
|
||||||
|
|
||||||
|
|
||||||
func get_fog_density() -> float:
|
|
||||||
if fog_density_curve:
|
|
||||||
return fog_density_curve.sample(time_of_day)
|
|
||||||
return 0.01
|
|
||||||
|
|
||||||
|
|
||||||
func get_stars_visibility() -> float:
|
|
||||||
if stars_visibility_curve:
|
|
||||||
return stars_visibility_curve.sample(time_of_day)
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_sky_top_color() -> Color:
|
|
||||||
if sky_top_color_curve:
|
|
||||||
return sky_top_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.2, 0.4, 0.8)
|
|
||||||
|
|
||||||
|
|
||||||
func get_sky_horizon_color() -> Color:
|
|
||||||
if sky_horizon_color_curve:
|
|
||||||
return sky_horizon_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.6, 0.7, 0.9)
|
|
||||||
|
|
||||||
|
|
||||||
func get_sky_bottom_color() -> Color:
|
|
||||||
if sky_bottom_color_curve:
|
|
||||||
return sky_bottom_color_curve.sample(time_of_day)
|
|
||||||
return Color(0.4, 0.5, 0.6)
|
|
||||||
|
|
||||||
|
|
||||||
func is_daytime() -> bool:
|
|
||||||
return time_of_day >= SUNRISE_END and time_of_day < SUNSET_START
|
|
||||||
|
|
||||||
|
|
||||||
func is_nighttime() -> bool:
|
|
||||||
return time_of_day < SUNRISE_START or time_of_day >= SUNSET_END
|
|
||||||
|
|
||||||
|
|
||||||
func is_dawn() -> bool:
|
|
||||||
return time_of_day >= SUNRISE_START and time_of_day < SUNRISE_END
|
|
||||||
|
|
||||||
|
|
||||||
func is_dusk() -> bool:
|
|
||||||
return time_of_day >= SUNSET_START and time_of_day < SUNSET_END
|
|
||||||
|
|
||||||
|
|
||||||
func get_time_period() -> String:
|
|
||||||
if is_dawn():
|
|
||||||
return "dawn"
|
|
||||||
elif is_dusk():
|
|
||||||
return "dusk"
|
|
||||||
elif is_daytime():
|
|
||||||
return "day"
|
|
||||||
else:
|
|
||||||
return "night"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://gypnoh5ikwjn
|
|
||||||
@@ -1,550 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name DynamicSkyRoot
|
|
||||||
extends Node3D
|
|
||||||
|
|
||||||
signal time_of_day_changed(time: float)
|
|
||||||
signal weather_changed(state: WeatherProfile.WeatherState)
|
|
||||||
signal preset_changed(preset: SkyPreset)
|
|
||||||
|
|
||||||
@export_group("Controllers")
|
|
||||||
@export var preset_library: SkyboxPresetLibrary
|
|
||||||
@export var day_night_controller: DayNightController
|
|
||||||
@export var weather_controller: WeatherController
|
|
||||||
@export var cloud_system: CloudSystem2D
|
|
||||||
@export var post_process_controller: PostProcessController
|
|
||||||
@export var vfx_controller: VFXController
|
|
||||||
@export var shadow_proxy_system: ShadowProxySystem
|
|
||||||
@export var weather_vfx: WeatherVFX
|
|
||||||
|
|
||||||
@export_group("Environment")
|
|
||||||
@export var world_environment: WorldEnvironment
|
|
||||||
@export var sun_light: DirectionalLight3D
|
|
||||||
@export var moon_light: DirectionalLight3D
|
|
||||||
|
|
||||||
@export_group("Moon Visual")
|
|
||||||
@export var moon_size: float = 0.045
|
|
||||||
@export var moon_height: float = 45.0
|
|
||||||
|
|
||||||
@export_group("Global Settings")
|
|
||||||
@export var auto_create_controllers: bool = true
|
|
||||||
@export var deterministic_seed: int = 0:
|
|
||||||
set(value):
|
|
||||||
deterministic_seed = value
|
|
||||||
_apply_seed()
|
|
||||||
|
|
||||||
@export_group("Debug")
|
|
||||||
@export var show_debug_panel: bool = false
|
|
||||||
@export var debug_time_override: float = -1.0
|
|
||||||
|
|
||||||
var _current_config: SkyConfig
|
|
||||||
var preset_name: String = ""
|
|
||||||
var _updating_preset_name: bool = false
|
|
||||||
var _debug_panel: SkyDebugPanel
|
|
||||||
var _debug_canvas_layer: CanvasLayer
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if show_debug_panel && _debug_panel == null:
|
|
||||||
_create_debug_panel()
|
|
||||||
|
|
||||||
if auto_create_controllers:
|
|
||||||
_ensure_controllers_exist()
|
|
||||||
|
|
||||||
_connect_signals()
|
|
||||||
_apply_seed()
|
|
||||||
_ensure_post_process_environment()
|
|
||||||
_load_initial_preset()
|
|
||||||
notify_property_list_changed()
|
|
||||||
_sync_all_systems()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
_sync_all_systems()
|
|
||||||
|
|
||||||
if show_debug_panel:
|
|
||||||
_update_debug_info()
|
|
||||||
elif _debug_panel != null:
|
|
||||||
_debug_panel.visible = false
|
|
||||||
|
|
||||||
|
|
||||||
func _ensure_controllers_exist() -> void:
|
|
||||||
if preset_library == null:
|
|
||||||
preset_library = SkyboxPresetLibrary.new()
|
|
||||||
preset_library.name = "PresetLibrary"
|
|
||||||
add_child(preset_library)
|
|
||||||
|
|
||||||
if day_night_controller == null:
|
|
||||||
day_night_controller = DayNightController.new()
|
|
||||||
day_night_controller.name = "DayNightController"
|
|
||||||
add_child(day_night_controller)
|
|
||||||
|
|
||||||
if weather_controller == null:
|
|
||||||
weather_controller = WeatherController.new()
|
|
||||||
weather_controller.name = "WeatherController"
|
|
||||||
add_child(weather_controller)
|
|
||||||
|
|
||||||
if cloud_system == null:
|
|
||||||
cloud_system = CloudSystem2D.new()
|
|
||||||
cloud_system.name = "CloudSystem"
|
|
||||||
add_child(cloud_system)
|
|
||||||
|
|
||||||
if post_process_controller == null:
|
|
||||||
post_process_controller = PostProcessController.new()
|
|
||||||
post_process_controller.name = "PostProcessController"
|
|
||||||
add_child(post_process_controller)
|
|
||||||
|
|
||||||
if vfx_controller == null:
|
|
||||||
vfx_controller = VFXController.new()
|
|
||||||
vfx_controller.name = "VFXController"
|
|
||||||
add_child(vfx_controller)
|
|
||||||
|
|
||||||
if shadow_proxy_system == null:
|
|
||||||
shadow_proxy_system = ShadowProxySystem.new()
|
|
||||||
shadow_proxy_system.name = "ShadowProxySystem"
|
|
||||||
add_child(shadow_proxy_system)
|
|
||||||
|
|
||||||
if weather_vfx == null:
|
|
||||||
weather_vfx = WeatherVFX.new()
|
|
||||||
weather_vfx.name = "WeatherVFX"
|
|
||||||
add_child(weather_vfx)
|
|
||||||
|
|
||||||
if world_environment == null:
|
|
||||||
_create_default_environment()
|
|
||||||
|
|
||||||
if sun_light == null:
|
|
||||||
_create_sun_light()
|
|
||||||
|
|
||||||
if moon_light == null:
|
|
||||||
_create_moon_light()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_default_environment() -> void:
|
|
||||||
world_environment = WorldEnvironment.new()
|
|
||||||
world_environment.name = "WorldEnvironment"
|
|
||||||
world_environment.environment = Environment.new()
|
|
||||||
world_environment.environment.background_mode = Environment.BG_SKY
|
|
||||||
world_environment.environment.sky = Sky.new()
|
|
||||||
add_child(world_environment)
|
|
||||||
|
|
||||||
if post_process_controller:
|
|
||||||
post_process_controller.target_environment = world_environment.environment
|
|
||||||
|
|
||||||
|
|
||||||
func _create_sun_light() -> void:
|
|
||||||
sun_light = DirectionalLight3D.new()
|
|
||||||
sun_light.name = "SunLight"
|
|
||||||
sun_light.light_color = Color(1.0, 0.95, 0.85)
|
|
||||||
sun_light.light_energy = 1.0
|
|
||||||
sun_light.shadow_enabled = true
|
|
||||||
add_child(sun_light)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_moon_light() -> void:
|
|
||||||
moon_light = DirectionalLight3D.new()
|
|
||||||
moon_light.name = "MoonLight"
|
|
||||||
moon_light.light_color = Color(0.7, 0.8, 1.0)
|
|
||||||
moon_light.light_energy = 0.3
|
|
||||||
moon_light.shadow_enabled = false
|
|
||||||
add_child(moon_light)
|
|
||||||
|
|
||||||
|
|
||||||
func _connect_signals() -> void:
|
|
||||||
if day_night_controller:
|
|
||||||
day_night_controller.time_changed.connect(_on_time_changed)
|
|
||||||
|
|
||||||
if weather_controller:
|
|
||||||
weather_controller.weather_state_changed.connect(_on_weather_state_changed)
|
|
||||||
|
|
||||||
if preset_library:
|
|
||||||
preset_library.preset_changed.connect(_on_preset_changed)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_time_changed(time: float) -> void:
|
|
||||||
time_of_day_changed.emit(time)
|
|
||||||
|
|
||||||
if vfx_controller:
|
|
||||||
vfx_controller.set_night_mode(day_night_controller.is_nighttime())
|
|
||||||
|
|
||||||
|
|
||||||
func _on_weather_state_changed(old_state: WeatherProfile.WeatherState, new_state: WeatherProfile.WeatherState) -> void:
|
|
||||||
weather_changed.emit(new_state)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_preset_changed(preset: SkyPreset) -> void:
|
|
||||||
preset_changed.emit(preset)
|
|
||||||
if preset.config:
|
|
||||||
_current_config = preset.config
|
|
||||||
_sync_preset_name()
|
|
||||||
|
|
||||||
_apply_preset_assets(preset)
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_seed() -> void:
|
|
||||||
if deterministic_seed != 0:
|
|
||||||
seed(deterministic_seed)
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_all_systems() -> void:
|
|
||||||
if day_night_controller == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var time := day_night_controller.time_of_day
|
|
||||||
if debug_time_override >= 0:
|
|
||||||
time = debug_time_override
|
|
||||||
|
|
||||||
_sync_sun_moon()
|
|
||||||
_sync_clouds()
|
|
||||||
_sync_post_process()
|
|
||||||
_sync_shadows()
|
|
||||||
_sync_weather_vfx()
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_sun_moon() -> void:
|
|
||||||
if day_night_controller == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var sun_dir := day_night_controller.get_sun_direction()
|
|
||||||
var moon_dir := day_night_controller.get_moon_direction()
|
|
||||||
|
|
||||||
var sun_color: Color
|
|
||||||
var sun_energy: float
|
|
||||||
var moon_color: Color
|
|
||||||
var moon_energy: float
|
|
||||||
var ambient_color: Color
|
|
||||||
var ambient_energy: float
|
|
||||||
|
|
||||||
sun_color = day_night_controller.get_sun_color()
|
|
||||||
sun_energy = day_night_controller.get_sun_intensity()
|
|
||||||
moon_color = day_night_controller.get_moon_color()
|
|
||||||
moon_energy = day_night_controller.get_moon_intensity()
|
|
||||||
ambient_color = day_night_controller.get_ambient_color()
|
|
||||||
ambient_energy = day_night_controller.get_ambient_intensity()
|
|
||||||
if weather_controller:
|
|
||||||
var wp := weather_controller.get_current_profile()
|
|
||||||
if wp:
|
|
||||||
ambient_color *= wp.ambient_color_multiplier
|
|
||||||
ambient_energy *= wp.ambient_intensity_multiplier
|
|
||||||
|
|
||||||
if sun_light:
|
|
||||||
sun_light.look_at(global_position - sun_dir, Vector3.UP)
|
|
||||||
sun_light.light_color = sun_color
|
|
||||||
sun_light.light_energy = sun_energy
|
|
||||||
sun_light.visible = sun_energy > 0.01
|
|
||||||
|
|
||||||
if moon_light:
|
|
||||||
moon_light.look_at(global_position - moon_dir, Vector3.UP)
|
|
||||||
moon_light.light_color = moon_color
|
|
||||||
moon_light.light_energy = moon_energy
|
|
||||||
moon_light.visible = moon_energy > 0.01
|
|
||||||
|
|
||||||
if world_environment and world_environment.environment:
|
|
||||||
world_environment.environment.ambient_light_color = ambient_color
|
|
||||||
world_environment.environment.ambient_light_energy = ambient_energy
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_clouds() -> void:
|
|
||||||
if cloud_system == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if day_night_controller:
|
|
||||||
var sun_color: Color
|
|
||||||
var sun_intensity: float
|
|
||||||
var moon_color: Color
|
|
||||||
var moon_intensity: float
|
|
||||||
|
|
||||||
if _current_config:
|
|
||||||
sun_color = _current_config.sun_color
|
|
||||||
sun_intensity = _current_config.sun_intensity
|
|
||||||
moon_color = _current_config.moon_color
|
|
||||||
moon_intensity = _current_config.moon_intensity
|
|
||||||
else:
|
|
||||||
sun_color = day_night_controller.get_sun_color()
|
|
||||||
sun_intensity = day_night_controller.get_sun_intensity()
|
|
||||||
moon_color = day_night_controller.get_moon_color()
|
|
||||||
moon_intensity = day_night_controller.get_moon_intensity()
|
|
||||||
|
|
||||||
cloud_system.set_sun_lighting(
|
|
||||||
day_night_controller.get_sun_direction(),
|
|
||||||
sun_color,
|
|
||||||
sun_intensity
|
|
||||||
)
|
|
||||||
cloud_system.set_moon_lighting(
|
|
||||||
day_night_controller.get_moon_direction(),
|
|
||||||
moon_color,
|
|
||||||
moon_intensity
|
|
||||||
)
|
|
||||||
|
|
||||||
if weather_controller:
|
|
||||||
cloud_system.global_coverage = weather_controller.get_cloud_coverage()
|
|
||||||
elif _current_config:
|
|
||||||
cloud_system.global_coverage = _current_config.cloud_coverage
|
|
||||||
|
|
||||||
if weather_controller:
|
|
||||||
cloud_system.set_global_wind(
|
|
||||||
weather_controller.get_wind_direction(),
|
|
||||||
weather_controller.get_wind_speed()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_post_process() -> void:
|
|
||||||
if post_process_controller == null or day_night_controller == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var sun_dir := day_night_controller.get_sun_direction()
|
|
||||||
|
|
||||||
if _current_config:
|
|
||||||
post_process_controller.set_sun_glow(
|
|
||||||
sun_dir,
|
|
||||||
_current_config.sun_color,
|
|
||||||
_current_config.sun_glow_intensity,
|
|
||||||
_current_config.sun_glow_size
|
|
||||||
)
|
|
||||||
post_process_controller.apply_config(_current_config)
|
|
||||||
post_process_controller.set_dawn_dusk_blend(0.0)
|
|
||||||
var cfg_fog_color := day_night_controller.get_fog_color()
|
|
||||||
var cfg_fog_density := day_night_controller.get_fog_density()
|
|
||||||
if weather_controller:
|
|
||||||
var wp := weather_controller.get_current_profile()
|
|
||||||
if wp:
|
|
||||||
cfg_fog_color *= wp.fog_color_multiplier
|
|
||||||
cfg_fog_density *= wp.fog_density_multiplier
|
|
||||||
post_process_controller.set_fog_settings(cfg_fog_color, cfg_fog_density)
|
|
||||||
else:
|
|
||||||
var sun_color := day_night_controller.get_sun_color()
|
|
||||||
post_process_controller.set_sun_glow(
|
|
||||||
sun_dir,
|
|
||||||
sun_color,
|
|
||||||
day_night_controller.get_sun_intensity() * 0.5,
|
|
||||||
0.2
|
|
||||||
)
|
|
||||||
var fog_color := day_night_controller.get_fog_color()
|
|
||||||
var fog_density := day_night_controller.get_fog_density()
|
|
||||||
if weather_controller:
|
|
||||||
var wp := weather_controller.get_current_profile()
|
|
||||||
if wp:
|
|
||||||
fog_color *= wp.fog_color_multiplier
|
|
||||||
fog_density *= wp.fog_density_multiplier
|
|
||||||
post_process_controller.set_fog_settings(fog_color, fog_density)
|
|
||||||
var dawn_dusk_blend := 0.0
|
|
||||||
if day_night_controller.is_dawn() or day_night_controller.is_dusk():
|
|
||||||
dawn_dusk_blend = 1.0
|
|
||||||
post_process_controller.set_dawn_dusk_blend(dawn_dusk_blend)
|
|
||||||
post_process_controller.set_stars_visibility(
|
|
||||||
day_night_controller.get_stars_visibility()
|
|
||||||
)
|
|
||||||
post_process_controller.set_sky_colors(
|
|
||||||
day_night_controller.get_sky_top_color(),
|
|
||||||
day_night_controller.get_sky_horizon_color(),
|
|
||||||
day_night_controller.get_sky_bottom_color()
|
|
||||||
)
|
|
||||||
|
|
||||||
var moon_energy := day_night_controller.get_moon_intensity()
|
|
||||||
var visual_intensity := moon_energy * 4.0
|
|
||||||
var mh: float = moon_height if moon_height > 0.0 else 45.0
|
|
||||||
var ms: float = moon_size if moon_size > 0.0 else 0.045
|
|
||||||
var moon_angle := (day_night_controller.time_of_day + 0.25) * TAU
|
|
||||||
var elevation := sin(moon_angle) * deg_to_rad(mh)
|
|
||||||
var moon_visual_dir := Vector3(
|
|
||||||
cos(moon_angle + PI),
|
|
||||||
sin(elevation) * 2.0,
|
|
||||||
sin(moon_angle) * 0.3
|
|
||||||
).normalized()
|
|
||||||
post_process_controller.set_moon(moon_visual_dir, Color.WHITE, visual_intensity, ms)
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_preset_assets(preset: SkyPreset) -> void:
|
|
||||||
if preset == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if post_process_controller:
|
|
||||||
post_process_controller.skybox_texture = preset.skybox_texture
|
|
||||||
if preset.post_process_profile:
|
|
||||||
post_process_controller.profile = preset.post_process_profile
|
|
||||||
|
|
||||||
if cloud_system and preset.cloud_layer_configs.size() > 0:
|
|
||||||
cloud_system.layer_configs = preset.cloud_layer_configs
|
|
||||||
cloud_system.rebuild_layers()
|
|
||||||
|
|
||||||
|
|
||||||
func _resolve_preset_library() -> SkyboxPresetLibrary:
|
|
||||||
if preset_library != null:
|
|
||||||
return preset_library
|
|
||||||
if has_node(NodePath("PresetLibrary")):
|
|
||||||
return get_node(NodePath("PresetLibrary")) as SkyboxPresetLibrary
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func _get_property_list() -> Array:
|
|
||||||
var properties := []
|
|
||||||
var names: PackedStringArray = []
|
|
||||||
var lib := _resolve_preset_library()
|
|
||||||
if lib:
|
|
||||||
names = lib.get_preset_names()
|
|
||||||
|
|
||||||
var hint_string := ""
|
|
||||||
if names.size() > 0:
|
|
||||||
hint_string = ",".join(names)
|
|
||||||
|
|
||||||
properties.append({
|
|
||||||
"name": "preset_name",
|
|
||||||
"type": TYPE_STRING,
|
|
||||||
"usage": PROPERTY_USAGE_EDITOR,
|
|
||||||
"hint": PROPERTY_HINT_ENUM,
|
|
||||||
"hint_string": hint_string,
|
|
||||||
})
|
|
||||||
return properties
|
|
||||||
|
|
||||||
|
|
||||||
func _set(property: StringName, value: Variant) -> bool:
|
|
||||||
if property == "preset_name":
|
|
||||||
if preset_name == value:
|
|
||||||
return true
|
|
||||||
preset_name = value
|
|
||||||
if _updating_preset_name:
|
|
||||||
return true
|
|
||||||
var lib := _resolve_preset_library()
|
|
||||||
if lib and String(preset_name) != "":
|
|
||||||
lib.apply_preset(String(preset_name))
|
|
||||||
var p := lib.get_current_preset()
|
|
||||||
if p:
|
|
||||||
_on_preset_changed(p)
|
|
||||||
_sync_all_systems()
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func _get(property: StringName) -> Variant:
|
|
||||||
if property == "preset_name":
|
|
||||||
return preset_name
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_preset_name() -> void:
|
|
||||||
if preset_library == null:
|
|
||||||
return
|
|
||||||
var current := preset_library.get_current_preset()
|
|
||||||
if current == null:
|
|
||||||
return
|
|
||||||
_updating_preset_name = true
|
|
||||||
preset_name = current.preset_name
|
|
||||||
_updating_preset_name = false
|
|
||||||
|
|
||||||
|
|
||||||
func _ensure_post_process_environment() -> void:
|
|
||||||
if post_process_controller and world_environment and world_environment.environment:
|
|
||||||
if post_process_controller.target_environment == null:
|
|
||||||
post_process_controller.target_environment = world_environment.environment
|
|
||||||
post_process_controller._setup_environment()
|
|
||||||
|
|
||||||
|
|
||||||
func _load_initial_preset() -> void:
|
|
||||||
if preset_library == null:
|
|
||||||
return
|
|
||||||
var current := preset_library.get_current_preset()
|
|
||||||
if current == null:
|
|
||||||
return
|
|
||||||
_sync_preset_name()
|
|
||||||
if current.config:
|
|
||||||
_current_config = current.config
|
|
||||||
_apply_preset_assets(current)
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_shadows() -> void:
|
|
||||||
if shadow_proxy_system == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if weather_controller:
|
|
||||||
shadow_proxy_system.set_cloud_coverage(weather_controller.get_cloud_coverage())
|
|
||||||
|
|
||||||
if cloud_system:
|
|
||||||
shadow_proxy_system.sync_with_cloud_system(cloud_system)
|
|
||||||
|
|
||||||
|
|
||||||
func _sync_weather_vfx() -> void:
|
|
||||||
if weather_vfx == null or weather_controller == null:
|
|
||||||
return
|
|
||||||
weather_vfx.set_rain_intensity(weather_controller.get_rain_intensity())
|
|
||||||
weather_vfx.set_snow_intensity(weather_controller.get_snow_intensity())
|
|
||||||
weather_vfx.set_lightning(
|
|
||||||
weather_controller.is_lightning_active(),
|
|
||||||
weather_controller.get_lightning_frequency()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_debug_info() -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
_debug_panel.visible = true
|
|
||||||
|
|
||||||
|
|
||||||
func _create_debug_panel() -> void:
|
|
||||||
_debug_canvas_layer = CanvasLayer.new()
|
|
||||||
_debug_canvas_layer.name = "DebugCanvasLayer"
|
|
||||||
_debug_canvas_layer.layer = 100
|
|
||||||
add_child(_debug_canvas_layer)
|
|
||||||
|
|
||||||
_debug_panel = SkyDebugPanel.new()
|
|
||||||
_debug_panel.name = "SkyDebugPanel"
|
|
||||||
_debug_panel.dynamic_sky = self
|
|
||||||
_debug_panel.anchor_left = 1.0
|
|
||||||
_debug_panel.anchor_top = 0.0
|
|
||||||
_debug_panel.anchor_right = 1.0
|
|
||||||
_debug_panel.anchor_bottom = 0.0
|
|
||||||
_debug_panel.offset_left = -310.0
|
|
||||||
_debug_panel.offset_top = 10.0
|
|
||||||
_debug_canvas_layer.add_child(_debug_panel)
|
|
||||||
|
|
||||||
|
|
||||||
func set_time_of_day(time: float) -> void:
|
|
||||||
_current_config = null
|
|
||||||
if day_night_controller:
|
|
||||||
day_night_controller.time_of_day = time
|
|
||||||
|
|
||||||
|
|
||||||
func set_weather(state: WeatherProfile.WeatherState, transition_time: float = -1.0) -> void:
|
|
||||||
if weather_controller:
|
|
||||||
weather_controller.set_weather(state, transition_time)
|
|
||||||
|
|
||||||
|
|
||||||
func apply_preset(preset_name: String) -> void:
|
|
||||||
if preset_library:
|
|
||||||
preset_library.apply_preset(preset_name)
|
|
||||||
|
|
||||||
|
|
||||||
func pause_time() -> void:
|
|
||||||
if day_night_controller:
|
|
||||||
day_night_controller.paused = true
|
|
||||||
|
|
||||||
|
|
||||||
func resume_time() -> void:
|
|
||||||
if day_night_controller:
|
|
||||||
day_night_controller.paused = false
|
|
||||||
|
|
||||||
|
|
||||||
func trigger_meteor_shower(duration: float = 60.0) -> void:
|
|
||||||
if vfx_controller:
|
|
||||||
vfx_controller.start_meteor_shower(duration)
|
|
||||||
|
|
||||||
|
|
||||||
func get_time_of_day() -> float:
|
|
||||||
if day_night_controller:
|
|
||||||
return day_night_controller.time_of_day
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_current_weather() -> WeatherProfile.WeatherState:
|
|
||||||
if weather_controller:
|
|
||||||
return weather_controller.current_weather
|
|
||||||
return WeatherProfile.WeatherState.CLEAR
|
|
||||||
|
|
||||||
|
|
||||||
func is_daytime() -> bool:
|
|
||||||
if day_night_controller:
|
|
||||||
return day_night_controller.is_daytime()
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
func is_nighttime() -> bool:
|
|
||||||
if day_night_controller:
|
|
||||||
return day_night_controller.is_nighttime()
|
|
||||||
return false
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://8r3do6ow5nmn
|
|
||||||
@@ -1,339 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name PostProcessController
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
@export_group("Profile")
|
|
||||||
@export var profile: PostProcessProfile:
|
|
||||||
set(value):
|
|
||||||
profile = value
|
|
||||||
_apply_profile()
|
|
||||||
|
|
||||||
@export_group("Environment")
|
|
||||||
@export var target_environment: Environment
|
|
||||||
|
|
||||||
@export_group("Sky Gradient")
|
|
||||||
@export var sky_top_color: Color = Color(0.2, 0.4, 0.8)
|
|
||||||
@export var sky_horizon_color: Color = Color(0.6, 0.7, 0.9)
|
|
||||||
@export var sky_bottom_color: Color = Color(0.4, 0.5, 0.6)
|
|
||||||
@export var gradient_intensity: float = 1.0
|
|
||||||
|
|
||||||
@export_group("Skybox")
|
|
||||||
@export var skybox_texture: Texture2D:
|
|
||||||
set(value):
|
|
||||||
skybox_texture = value
|
|
||||||
_update_sky_material()
|
|
||||||
@export var skybox_blend: float = 1.0:
|
|
||||||
set(value):
|
|
||||||
skybox_blend = clampf(value, 0.0, 1.0)
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
@export_group("Fog Shaping")
|
|
||||||
@export var fog_enabled: bool = true
|
|
||||||
@export var fog_color: Color = Color(0.7, 0.8, 0.9)
|
|
||||||
@export var fog_density: float = 0.01
|
|
||||||
@export var height_fog_enabled: bool = true
|
|
||||||
@export var height_fog_min: float = 0.0
|
|
||||||
@export var height_fog_max: float = 100.0
|
|
||||||
@export var height_fog_curve: float = 1.0
|
|
||||||
|
|
||||||
@export_group("Sun Glow")
|
|
||||||
@export var sun_glow_enabled: bool = true
|
|
||||||
@export var sun_glow_intensity: float = 0.5
|
|
||||||
@export var sun_glow_size: float = 0.2
|
|
||||||
@export var sun_glow_falloff: float = 2.0
|
|
||||||
@export var sun_glow_color: Color = Color(1.0, 0.95, 0.8)
|
|
||||||
@export var sun_direction: Vector3 = Vector3(0.0, 1.0, 0.0)
|
|
||||||
|
|
||||||
@export_group("Dawn/Dusk Enhancement")
|
|
||||||
@export var dawn_dusk_enabled: bool = true
|
|
||||||
@export var dawn_dusk_intensity: float = 0.5
|
|
||||||
@export var dawn_dusk_blend: float = 0.0
|
|
||||||
|
|
||||||
@export_group("Performance")
|
|
||||||
@export var effects_enabled: bool = true
|
|
||||||
|
|
||||||
var _sky_material: ShaderMaterial
|
|
||||||
var _moon_direction: Vector3 = Vector3(0.0, -1.0, 0.0)
|
|
||||||
var _moon_color: Color = Color(0.9, 0.92, 1.0)
|
|
||||||
var _moon_intensity: float = 0.0
|
|
||||||
var _moon_size: float = 0.03
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if profile == null:
|
|
||||||
profile = PostProcessProfile.new()
|
|
||||||
_apply_profile()
|
|
||||||
_setup_environment()
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_profile() -> void:
|
|
||||||
if profile == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
gradient_intensity = profile.gradient_intensity
|
|
||||||
fog_enabled = profile.fog_enabled
|
|
||||||
height_fog_enabled = profile.height_fog_enabled
|
|
||||||
height_fog_min = profile.height_fog_start
|
|
||||||
height_fog_max = profile.height_fog_end
|
|
||||||
height_fog_curve = profile.height_fog_curve
|
|
||||||
sun_glow_enabled = profile.sun_glow_enabled
|
|
||||||
sun_glow_intensity = profile.sun_glow_intensity
|
|
||||||
sun_glow_size = profile.sun_glow_size
|
|
||||||
sun_glow_falloff = profile.sun_glow_falloff
|
|
||||||
sun_glow_color = profile.sun_glow_color
|
|
||||||
dawn_dusk_enabled = profile.dawn_dusk_enabled
|
|
||||||
dawn_dusk_intensity = profile.dawn_dusk_intensity
|
|
||||||
|
|
||||||
|
|
||||||
func _setup_environment() -> void:
|
|
||||||
if target_environment == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
_update_fog()
|
|
||||||
_update_sky()
|
|
||||||
|
|
||||||
|
|
||||||
func _update_fog() -> void:
|
|
||||||
if target_environment == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
target_environment.fog_enabled = fog_enabled and effects_enabled
|
|
||||||
|
|
||||||
if fog_enabled:
|
|
||||||
target_environment.fog_light_color = fog_color
|
|
||||||
target_environment.fog_density = fog_density
|
|
||||||
|
|
||||||
if height_fog_enabled:
|
|
||||||
target_environment.fog_height = height_fog_min
|
|
||||||
target_environment.fog_height_density = height_fog_curve * 0.1
|
|
||||||
|
|
||||||
|
|
||||||
func _update_sky() -> void:
|
|
||||||
if target_environment == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if target_environment.sky == null:
|
|
||||||
target_environment.sky = Sky.new()
|
|
||||||
|
|
||||||
if target_environment.sky.sky_material == null or not target_environment.sky.sky_material is ShaderMaterial:
|
|
||||||
_create_sky_material()
|
|
||||||
|
|
||||||
_sky_material = target_environment.sky.sky_material as ShaderMaterial
|
|
||||||
if _sky_material:
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_sky_material() -> void:
|
|
||||||
_sky_material = ShaderMaterial.new()
|
|
||||||
_sky_material.shader = _get_sky_shader()
|
|
||||||
|
|
||||||
if target_environment and target_environment.sky:
|
|
||||||
target_environment.sky.sky_material = _sky_material
|
|
||||||
|
|
||||||
|
|
||||||
func _get_sky_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type sky;
|
|
||||||
|
|
||||||
uniform sampler2D skybox_texture : source_color, filter_linear_mipmap, repeat_enable;
|
|
||||||
uniform bool skybox_enabled = false;
|
|
||||||
uniform float skybox_blend = 1.0;
|
|
||||||
|
|
||||||
uniform vec4 sky_top_color : source_color = vec4(0.2, 0.4, 0.8, 1.0);
|
|
||||||
uniform vec4 sky_horizon_color : source_color = vec4(0.6, 0.7, 0.9, 1.0);
|
|
||||||
uniform vec4 sky_bottom_color : source_color = vec4(0.4, 0.5, 0.6, 1.0);
|
|
||||||
uniform float gradient_intensity = 1.0;
|
|
||||||
uniform float horizon_blend = 0.5;
|
|
||||||
|
|
||||||
uniform bool sun_glow_enabled = true;
|
|
||||||
uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0);
|
|
||||||
uniform vec4 sun_glow_color : source_color = vec4(1.0, 0.95, 0.8, 1.0);
|
|
||||||
uniform float sun_glow_intensity = 0.5;
|
|
||||||
uniform float sun_glow_size = 0.2;
|
|
||||||
uniform float sun_glow_falloff = 2.0;
|
|
||||||
|
|
||||||
uniform bool dawn_dusk_enabled = true;
|
|
||||||
uniform vec4 dawn_dusk_color : source_color = vec4(1.0, 0.6, 0.4, 1.0);
|
|
||||||
uniform float dawn_dusk_intensity = 0.5;
|
|
||||||
uniform float dawn_dusk_blend = 0.0;
|
|
||||||
|
|
||||||
uniform vec3 moon_direction = vec3(0.0, -1.0, 0.0);
|
|
||||||
uniform vec4 moon_color : source_color = vec4(0.9, 0.92, 1.0, 1.0);
|
|
||||||
uniform float moon_intensity = 0.0;
|
|
||||||
uniform float moon_size = 0.03;
|
|
||||||
|
|
||||||
uniform float stars_visibility = 0.0;
|
|
||||||
uniform vec4 stars_tint : source_color = vec4(1.0);
|
|
||||||
|
|
||||||
float hash(vec2 p) {
|
|
||||||
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
float stars(vec3 dir) {
|
|
||||||
vec2 uv = dir.xz / (abs(dir.y) + 0.001) * 50.0;
|
|
||||||
vec2 cell = floor(uv);
|
|
||||||
vec2 local = fract(uv) - 0.5;
|
|
||||||
|
|
||||||
float star = 0.0;
|
|
||||||
float h = hash(cell);
|
|
||||||
if (h > 0.97) {
|
|
||||||
float dist = length(local);
|
|
||||||
star = smoothstep(0.1, 0.0, dist) * (h - 0.97) / 0.03;
|
|
||||||
star *= step(0.0, dir.y);
|
|
||||||
}
|
|
||||||
return star;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 pano_uv(vec3 dir) {
|
|
||||||
dir = normalize(dir);
|
|
||||||
float u = atan(dir.x, dir.z) / (2.0 * PI) + 0.5;
|
|
||||||
float v = acos(clamp(dir.y, -1.0, 1.0)) / PI;
|
|
||||||
return vec2(u, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sky() {
|
|
||||||
vec3 dir = EYEDIR;
|
|
||||||
float y = dir.y;
|
|
||||||
|
|
||||||
vec3 color;
|
|
||||||
if (y > 0.0) {
|
|
||||||
float t = pow(y, horizon_blend);
|
|
||||||
color = mix(sky_horizon_color.rgb, sky_top_color.rgb, t);
|
|
||||||
} else {
|
|
||||||
float t = pow(-y, horizon_blend);
|
|
||||||
color = mix(sky_horizon_color.rgb, sky_bottom_color.rgb, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
color = mix(vec3(0.5), color, gradient_intensity);
|
|
||||||
|
|
||||||
if (skybox_enabled) {
|
|
||||||
vec3 pano_color = texture(skybox_texture, pano_uv(dir)).rgb;
|
|
||||||
color = mix(color, pano_color, skybox_blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sun_glow_enabled && sun_direction.y > -0.2) {
|
|
||||||
float sun_dot = max(0.0, dot(dir, normalize(sun_direction)));
|
|
||||||
float glow = pow(sun_dot, 1.0 / max(0.001, sun_glow_size));
|
|
||||||
glow = pow(glow, sun_glow_falloff);
|
|
||||||
color += sun_glow_color.rgb * glow * sun_glow_intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dawn_dusk_enabled && dawn_dusk_blend > 0.0) {
|
|
||||||
float horizon_factor = 1.0 - abs(y);
|
|
||||||
horizon_factor = pow(horizon_factor, 2.0);
|
|
||||||
color = mix(color, dawn_dusk_color.rgb, horizon_factor * dawn_dusk_intensity * dawn_dusk_blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stars_visibility > 0.0 && y > 0.0) {
|
|
||||||
float star_value = stars(dir) * stars_visibility;
|
|
||||||
color += stars_tint.rgb * star_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moon_intensity > 0.0 && moon_direction.y > 0.0) {
|
|
||||||
vec3 moon_dir = normalize(moon_direction);
|
|
||||||
float moon_dot = dot(dir, moon_dir);
|
|
||||||
float disc = smoothstep(1.0 - moon_size, 1.0 - moon_size * 0.6, moon_dot);
|
|
||||||
float glow = pow(max(0.0, moon_dot), 32.0) * 0.15;
|
|
||||||
color += moon_color.rgb * disc * moon_intensity + moon_color.rgb * glow * moon_intensity * 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
COLOR = color;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
|
|
||||||
|
|
||||||
func _update_sky_material() -> void:
|
|
||||||
if _sky_material == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if skybox_texture:
|
|
||||||
_sky_material.set_shader_parameter("skybox_enabled", true)
|
|
||||||
_sky_material.set_shader_parameter("skybox_texture", skybox_texture)
|
|
||||||
_sky_material.set_shader_parameter("skybox_blend", skybox_blend)
|
|
||||||
else:
|
|
||||||
_sky_material.set_shader_parameter("skybox_enabled", false)
|
|
||||||
_sky_material.set_shader_parameter("skybox_blend", skybox_blend)
|
|
||||||
|
|
||||||
_sky_material.set_shader_parameter("sky_top_color", sky_top_color)
|
|
||||||
_sky_material.set_shader_parameter("sky_horizon_color", sky_horizon_color)
|
|
||||||
_sky_material.set_shader_parameter("sky_bottom_color", sky_bottom_color)
|
|
||||||
_sky_material.set_shader_parameter("gradient_intensity", gradient_intensity)
|
|
||||||
|
|
||||||
_sky_material.set_shader_parameter("sun_glow_enabled", sun_glow_enabled and effects_enabled)
|
|
||||||
_sky_material.set_shader_parameter("sun_direction", sun_direction)
|
|
||||||
_sky_material.set_shader_parameter("sun_glow_color", sun_glow_color)
|
|
||||||
_sky_material.set_shader_parameter("sun_glow_intensity", sun_glow_intensity)
|
|
||||||
_sky_material.set_shader_parameter("sun_glow_size", sun_glow_size)
|
|
||||||
_sky_material.set_shader_parameter("sun_glow_falloff", sun_glow_falloff)
|
|
||||||
|
|
||||||
_sky_material.set_shader_parameter("dawn_dusk_enabled", dawn_dusk_enabled and effects_enabled)
|
|
||||||
_sky_material.set_shader_parameter("dawn_dusk_blend", dawn_dusk_blend)
|
|
||||||
_sky_material.set_shader_parameter("dawn_dusk_intensity", dawn_dusk_intensity)
|
|
||||||
|
|
||||||
_sky_material.set_shader_parameter("moon_direction", _moon_direction)
|
|
||||||
_sky_material.set_shader_parameter("moon_color", _moon_color)
|
|
||||||
_sky_material.set_shader_parameter("moon_intensity", _moon_intensity)
|
|
||||||
_sky_material.set_shader_parameter("moon_size", _moon_size)
|
|
||||||
|
|
||||||
|
|
||||||
func set_sky_colors(top: Color, horizon: Color, bottom: Color) -> void:
|
|
||||||
sky_top_color = top
|
|
||||||
sky_horizon_color = horizon
|
|
||||||
sky_bottom_color = bottom
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func set_fog_settings(color: Color, density: float) -> void:
|
|
||||||
fog_color = color
|
|
||||||
fog_density = density
|
|
||||||
_update_fog()
|
|
||||||
|
|
||||||
|
|
||||||
func set_sun_glow(direction: Vector3, color: Color, intensity: float, size: float) -> void:
|
|
||||||
sun_direction = direction.normalized()
|
|
||||||
sun_glow_color = color
|
|
||||||
sun_glow_intensity = intensity
|
|
||||||
sun_glow_size = size
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func set_dawn_dusk_blend(blend: float) -> void:
|
|
||||||
dawn_dusk_blend = clampf(blend, 0.0, 1.0)
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func set_moon(direction: Vector3, color: Color, intensity: float, size: float = 0.03) -> void:
|
|
||||||
_moon_direction = direction.normalized()
|
|
||||||
_moon_color = color
|
|
||||||
_moon_intensity = intensity
|
|
||||||
_moon_size = size
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func set_stars_visibility(visibility: float, tint: Color = Color.WHITE) -> void:
|
|
||||||
if _sky_material:
|
|
||||||
_sky_material.set_shader_parameter("stars_visibility", visibility)
|
|
||||||
_sky_material.set_shader_parameter("stars_tint", tint)
|
|
||||||
|
|
||||||
|
|
||||||
func set_effects_enabled(enabled: bool) -> void:
|
|
||||||
effects_enabled = enabled
|
|
||||||
_update_fog()
|
|
||||||
_update_sky_material()
|
|
||||||
|
|
||||||
|
|
||||||
func apply_config(config: SkyConfig) -> void:
|
|
||||||
sky_top_color = config.sky_top_color
|
|
||||||
sky_horizon_color = config.sky_horizon_color
|
|
||||||
sky_bottom_color = config.sky_bottom_color
|
|
||||||
fog_color = config.fog_color
|
|
||||||
fog_density = config.fog_density
|
|
||||||
sun_glow_intensity = config.sun_glow_intensity
|
|
||||||
sun_glow_size = config.sun_glow_size
|
|
||||||
gradient_intensity = config.gradient_intensity
|
|
||||||
|
|
||||||
_update_fog()
|
|
||||||
_update_sky_material()
|
|
||||||
set_stars_visibility(config.stars_visibility, config.stars_tint)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cwqg0bg2m2bme
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name ProceduralCloudTexture
|
|
||||||
extends Resource
|
|
||||||
|
|
||||||
@export var size: int = 512
|
|
||||||
@export var octaves: int = 6
|
|
||||||
@export var persistence: float = 0.5
|
|
||||||
@export var lacunarity: float = 2.0
|
|
||||||
@export var scale: float = 4.0
|
|
||||||
@export var seed_value: int = 0
|
|
||||||
@export var cloud_threshold: float = 0.4
|
|
||||||
@export var cloud_softness: float = 0.3
|
|
||||||
|
|
||||||
var _noise: FastNoiseLite
|
|
||||||
var _texture: ImageTexture
|
|
||||||
|
|
||||||
|
|
||||||
func _init() -> void:
|
|
||||||
_setup_noise()
|
|
||||||
|
|
||||||
|
|
||||||
func _setup_noise() -> void:
|
|
||||||
_noise = FastNoiseLite.new()
|
|
||||||
_noise.noise_type = FastNoiseLite.TYPE_SIMPLEX
|
|
||||||
_noise.seed = seed_value
|
|
||||||
_noise.frequency = 1.0 / (scale * 64.0)
|
|
||||||
_noise.fractal_type = FastNoiseLite.FRACTAL_FBM
|
|
||||||
_noise.fractal_octaves = octaves
|
|
||||||
_noise.fractal_lacunarity = lacunarity
|
|
||||||
_noise.fractal_gain = persistence
|
|
||||||
|
|
||||||
|
|
||||||
func generate() -> ImageTexture:
|
|
||||||
_setup_noise()
|
|
||||||
|
|
||||||
var image := Image.create(size, size, false, Image.FORMAT_RGBA8)
|
|
||||||
|
|
||||||
for y in size:
|
|
||||||
for x in size:
|
|
||||||
var noise_value := (_noise.get_noise_2d(float(x), float(y)) + 1.0) * 0.5
|
|
||||||
|
|
||||||
var cloud_value := smoothstep(cloud_threshold - cloud_softness, cloud_threshold + cloud_softness, noise_value)
|
|
||||||
|
|
||||||
var color := Color(cloud_value, cloud_value, cloud_value, cloud_value)
|
|
||||||
image.set_pixel(x, y, color)
|
|
||||||
|
|
||||||
_texture = ImageTexture.create_from_image(image)
|
|
||||||
return _texture
|
|
||||||
|
|
||||||
|
|
||||||
func get_texture() -> ImageTexture:
|
|
||||||
if _texture == null:
|
|
||||||
return generate()
|
|
||||||
return _texture
|
|
||||||
|
|
||||||
|
|
||||||
static func create_default_cloud_texture(layer_type: int = 0) -> ImageTexture:
|
|
||||||
var generator := ProceduralCloudTexture.new()
|
|
||||||
generator.size = 512
|
|
||||||
|
|
||||||
match layer_type:
|
|
||||||
0: # Low clouds - larger, denser
|
|
||||||
generator.scale = 3.0
|
|
||||||
generator.octaves = 4
|
|
||||||
generator.cloud_threshold = 0.35
|
|
||||||
generator.cloud_softness = 0.25
|
|
||||||
1: # Mid clouds - medium
|
|
||||||
generator.scale = 4.0
|
|
||||||
generator.octaves = 5
|
|
||||||
generator.cloud_threshold = 0.4
|
|
||||||
generator.cloud_softness = 0.3
|
|
||||||
2: # High clouds - wispy
|
|
||||||
generator.scale = 6.0
|
|
||||||
generator.octaves = 6
|
|
||||||
generator.cloud_threshold = 0.5
|
|
||||||
generator.cloud_softness = 0.35
|
|
||||||
3: # Wisps - very thin
|
|
||||||
generator.scale = 8.0
|
|
||||||
generator.octaves = 7
|
|
||||||
generator.cloud_threshold = 0.55
|
|
||||||
generator.cloud_softness = 0.4
|
|
||||||
|
|
||||||
return generator.generate()
|
|
||||||
|
|
||||||
|
|
||||||
static func create_shadow_texture() -> ImageTexture:
|
|
||||||
var generator := ProceduralCloudTexture.new()
|
|
||||||
generator.size = 256
|
|
||||||
generator.scale = 4.0
|
|
||||||
generator.octaves = 4
|
|
||||||
generator.cloud_threshold = 0.3
|
|
||||||
generator.cloud_softness = 0.4
|
|
||||||
return generator.generate()
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://dyjrdeqft0xlk
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name ShadowProxySystem
|
|
||||||
extends Node3D
|
|
||||||
|
|
||||||
@export_group("Shadow Settings")
|
|
||||||
@export var enabled: bool = true:
|
|
||||||
set(value):
|
|
||||||
enabled = value
|
|
||||||
if _shadow_mesh:
|
|
||||||
_shadow_mesh.visible = enabled
|
|
||||||
|
|
||||||
@export var shadow_texture: Texture2D:
|
|
||||||
set(value):
|
|
||||||
shadow_texture = value
|
|
||||||
_update_shadow_texture()
|
|
||||||
|
|
||||||
@export var shadow_opacity: float = 0.3:
|
|
||||||
set(value):
|
|
||||||
shadow_opacity = clampf(value, 0.0, 1.0)
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
@export var shadow_color: Color = Color(0.0, 0.0, 0.1):
|
|
||||||
set(value):
|
|
||||||
shadow_color = value
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
@export_group("Movement")
|
|
||||||
@export var flow_direction: Vector2 = Vector2(1.0, 0.0)
|
|
||||||
@export var flow_speed: float = 5.0
|
|
||||||
@export var sync_with_clouds: bool = true
|
|
||||||
|
|
||||||
@export_group("Projection")
|
|
||||||
@export var projection_size: float = 500.0:
|
|
||||||
set(value):
|
|
||||||
projection_size = value
|
|
||||||
_update_projection_size()
|
|
||||||
|
|
||||||
@export var projection_height: float = 0.1
|
|
||||||
@export var tiling: Vector2 = Vector2(2.0, 2.0):
|
|
||||||
set(value):
|
|
||||||
tiling = value
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
@export_group("Blur")
|
|
||||||
@export var blur_enabled: bool = true
|
|
||||||
@export var blur_amount: float = 0.5:
|
|
||||||
set(value):
|
|
||||||
blur_amount = clampf(value, 0.0, 1.0)
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
@export_group("Performance")
|
|
||||||
@export var follow_camera: bool = true
|
|
||||||
@export var update_distance: float = 50.0
|
|
||||||
|
|
||||||
var _shadow_mesh: MeshInstance3D
|
|
||||||
var _shadow_material: ShaderMaterial
|
|
||||||
var _uv_offset: Vector2 = Vector2.ZERO
|
|
||||||
var _last_camera_position: Vector3 = Vector3.ZERO
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_create_shadow_mesh()
|
|
||||||
_create_shadow_material()
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if not enabled:
|
|
||||||
return
|
|
||||||
|
|
||||||
_update_flow(delta)
|
|
||||||
|
|
||||||
if follow_camera:
|
|
||||||
_follow_camera()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_shadow_mesh() -> void:
|
|
||||||
if _shadow_mesh:
|
|
||||||
_shadow_mesh.queue_free()
|
|
||||||
|
|
||||||
_shadow_mesh = MeshInstance3D.new()
|
|
||||||
_shadow_mesh.name = "CloudShadowMesh"
|
|
||||||
|
|
||||||
var plane := PlaneMesh.new()
|
|
||||||
plane.size = Vector2(projection_size, projection_size)
|
|
||||||
_shadow_mesh.mesh = plane
|
|
||||||
|
|
||||||
_shadow_mesh.position.y = projection_height
|
|
||||||
_shadow_mesh.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
|
||||||
|
|
||||||
add_child(_shadow_mesh)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_shadow_material() -> void:
|
|
||||||
_shadow_material = ShaderMaterial.new()
|
|
||||||
_shadow_material.shader = _get_shadow_shader()
|
|
||||||
|
|
||||||
if _shadow_mesh:
|
|
||||||
_shadow_mesh.material_override = _shadow_material
|
|
||||||
|
|
||||||
|
|
||||||
func _get_shadow_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type spatial;
|
|
||||||
render_mode unshaded, depth_draw_opaque, cull_disabled, shadows_disabled;
|
|
||||||
|
|
||||||
uniform sampler2D shadow_texture : source_color, filter_linear_mipmap, repeat_enable;
|
|
||||||
uniform vec4 shadow_color : source_color = vec4(0.0, 0.0, 0.1, 1.0);
|
|
||||||
uniform float opacity = 0.3;
|
|
||||||
uniform vec2 tiling = vec2(2.0, 2.0);
|
|
||||||
uniform vec2 uv_offset = vec2(0.0, 0.0);
|
|
||||||
uniform float blur_amount = 0.5;
|
|
||||||
uniform float edge_fade = 0.1;
|
|
||||||
|
|
||||||
varying vec2 world_uv;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
world_uv = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 uv = world_uv * tiling * 0.001 + uv_offset;
|
|
||||||
|
|
||||||
vec4 shadow_sample;
|
|
||||||
if (blur_amount > 0.01) {
|
|
||||||
float blur = blur_amount * 0.01;
|
|
||||||
shadow_sample = texture(shadow_texture, uv) * 0.25;
|
|
||||||
shadow_sample += texture(shadow_texture, uv + vec2(blur, 0.0)) * 0.125;
|
|
||||||
shadow_sample += texture(shadow_texture, uv - vec2(blur, 0.0)) * 0.125;
|
|
||||||
shadow_sample += texture(shadow_texture, uv + vec2(0.0, blur)) * 0.125;
|
|
||||||
shadow_sample += texture(shadow_texture, uv - vec2(0.0, blur)) * 0.125;
|
|
||||||
shadow_sample += texture(shadow_texture, uv + vec2(blur, blur)) * 0.0625;
|
|
||||||
shadow_sample += texture(shadow_texture, uv - vec2(blur, blur)) * 0.0625;
|
|
||||||
shadow_sample += texture(shadow_texture, uv + vec2(blur, -blur)) * 0.0625;
|
|
||||||
shadow_sample += texture(shadow_texture, uv + vec2(-blur, blur)) * 0.0625;
|
|
||||||
} else {
|
|
||||||
shadow_sample = texture(shadow_texture, uv);
|
|
||||||
}
|
|
||||||
|
|
||||||
float shadow_value = shadow_sample.r;
|
|
||||||
|
|
||||||
vec2 local_uv = fract(world_uv * 0.001);
|
|
||||||
float edge = smoothstep(0.0, edge_fade, local_uv.x);
|
|
||||||
edge *= smoothstep(0.0, edge_fade, local_uv.y);
|
|
||||||
edge *= smoothstep(0.0, edge_fade, 1.0 - local_uv.x);
|
|
||||||
edge *= smoothstep(0.0, edge_fade, 1.0 - local_uv.y);
|
|
||||||
|
|
||||||
ALBEDO = shadow_color.rgb;
|
|
||||||
ALPHA = shadow_value * opacity * edge;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
|
|
||||||
|
|
||||||
func _update_shadow_material() -> void:
|
|
||||||
if _shadow_material == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
_shadow_material.set_shader_parameter("shadow_color", shadow_color)
|
|
||||||
_shadow_material.set_shader_parameter("opacity", shadow_opacity)
|
|
||||||
_shadow_material.set_shader_parameter("tiling", tiling)
|
|
||||||
_shadow_material.set_shader_parameter("blur_amount", blur_amount if blur_enabled else 0.0)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_shadow_texture() -> void:
|
|
||||||
if _shadow_material and shadow_texture:
|
|
||||||
_shadow_material.set_shader_parameter("shadow_texture", shadow_texture)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_projection_size() -> void:
|
|
||||||
if _shadow_mesh and _shadow_mesh.mesh is PlaneMesh:
|
|
||||||
var plane := _shadow_mesh.mesh as PlaneMesh
|
|
||||||
plane.size = Vector2(projection_size, projection_size)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_flow(delta: float) -> void:
|
|
||||||
_uv_offset += flow_direction * flow_speed * delta * 0.001
|
|
||||||
_uv_offset.x = fmod(_uv_offset.x, 1.0)
|
|
||||||
_uv_offset.y = fmod(_uv_offset.y, 1.0)
|
|
||||||
|
|
||||||
if _shadow_material:
|
|
||||||
_shadow_material.set_shader_parameter("uv_offset", _uv_offset)
|
|
||||||
|
|
||||||
|
|
||||||
func _follow_camera() -> void:
|
|
||||||
var camera := get_viewport().get_camera_3d()
|
|
||||||
if camera == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var camera_pos := camera.global_position
|
|
||||||
var distance := camera_pos.distance_to(_last_camera_position)
|
|
||||||
|
|
||||||
if distance >= update_distance:
|
|
||||||
_last_camera_position = camera_pos
|
|
||||||
global_position.x = camera_pos.x
|
|
||||||
global_position.z = camera_pos.z
|
|
||||||
|
|
||||||
|
|
||||||
func set_flow(direction: Vector2, speed: float) -> void:
|
|
||||||
flow_direction = direction.normalized()
|
|
||||||
flow_speed = speed
|
|
||||||
|
|
||||||
|
|
||||||
func set_shadow_appearance(color: Color, opacity_value: float, blur: float) -> void:
|
|
||||||
shadow_color = color
|
|
||||||
shadow_opacity = opacity_value
|
|
||||||
blur_amount = blur
|
|
||||||
_update_shadow_material()
|
|
||||||
|
|
||||||
|
|
||||||
func sync_with_cloud_system(cloud_system: CloudSystem2D) -> void:
|
|
||||||
if sync_with_clouds and cloud_system:
|
|
||||||
flow_direction = cloud_system.global_wind_direction
|
|
||||||
flow_speed = cloud_system.global_wind_speed * 5.0
|
|
||||||
|
|
||||||
|
|
||||||
func set_cloud_coverage(coverage: float) -> void:
|
|
||||||
shadow_opacity = coverage * 0.5
|
|
||||||
_update_shadow_material()
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://hvs2g6acqryq
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name SkyDebugPanel
|
|
||||||
extends Control
|
|
||||||
|
|
||||||
@export var dynamic_sky: DynamicSkyRoot
|
|
||||||
|
|
||||||
var _panel: PanelContainer
|
|
||||||
var _vbox: VBoxContainer
|
|
||||||
var _time_label: Label
|
|
||||||
var _period_label: Label
|
|
||||||
var _preset_label: Label
|
|
||||||
var _weather_label: Label
|
|
||||||
var _sun_label: Label
|
|
||||||
var _moon_label: Label
|
|
||||||
var _ambient_label: Label
|
|
||||||
var _cloud_label: Label
|
|
||||||
var _fog_label: Label
|
|
||||||
var _rain_label: Label
|
|
||||||
var _seed_label: Label
|
|
||||||
var _time_slider: HSlider
|
|
||||||
var _weather_dropdown: OptionButton
|
|
||||||
var _pause_button: Button
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_create_ui()
|
|
||||||
_connect_signals()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
|
||||||
if dynamic_sky == null:
|
|
||||||
return
|
|
||||||
_update_labels()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_ui() -> void:
|
|
||||||
_panel = PanelContainer.new()
|
|
||||||
_panel.name = "DebugPanel"
|
|
||||||
_panel.custom_minimum_size = Vector2(300, 200)
|
|
||||||
add_child(_panel)
|
|
||||||
|
|
||||||
var margin := MarginContainer.new()
|
|
||||||
margin.add_theme_constant_override("margin_left", 10)
|
|
||||||
margin.add_theme_constant_override("margin_right", 10)
|
|
||||||
margin.add_theme_constant_override("margin_top", 10)
|
|
||||||
margin.add_theme_constant_override("margin_bottom", 10)
|
|
||||||
_panel.add_child(margin)
|
|
||||||
|
|
||||||
_vbox = VBoxContainer.new()
|
|
||||||
_vbox.add_theme_constant_override("separation", 8)
|
|
||||||
margin.add_child(_vbox)
|
|
||||||
|
|
||||||
var title := Label.new()
|
|
||||||
title.text = "Dynamic Sky Debug"
|
|
||||||
title.add_theme_font_size_override("font_size", 18)
|
|
||||||
_vbox.add_child(title)
|
|
||||||
|
|
||||||
_vbox.add_child(HSeparator.new())
|
|
||||||
|
|
||||||
_preset_label = Label.new()
|
|
||||||
_preset_label.text = "Preset: —"
|
|
||||||
_vbox.add_child(_preset_label)
|
|
||||||
|
|
||||||
_time_label = Label.new()
|
|
||||||
_time_label.text = "Time: 00:00 (0.00)"
|
|
||||||
_vbox.add_child(_time_label)
|
|
||||||
|
|
||||||
_period_label = Label.new()
|
|
||||||
_period_label.text = "Period: —"
|
|
||||||
_vbox.add_child(_period_label)
|
|
||||||
|
|
||||||
var time_hbox := HBoxContainer.new()
|
|
||||||
_vbox.add_child(time_hbox)
|
|
||||||
|
|
||||||
var time_label := Label.new()
|
|
||||||
time_label.text = "Time:"
|
|
||||||
time_label.custom_minimum_size.x = 60
|
|
||||||
time_hbox.add_child(time_label)
|
|
||||||
|
|
||||||
_time_slider = HSlider.new()
|
|
||||||
_time_slider.min_value = 0.0
|
|
||||||
_time_slider.max_value = 1.0
|
|
||||||
_time_slider.step = 0.001
|
|
||||||
_time_slider.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
||||||
time_hbox.add_child(_time_slider)
|
|
||||||
|
|
||||||
_pause_button = Button.new()
|
|
||||||
_pause_button.text = "Pause"
|
|
||||||
_pause_button.toggle_mode = true
|
|
||||||
_vbox.add_child(_pause_button)
|
|
||||||
|
|
||||||
_vbox.add_child(HSeparator.new())
|
|
||||||
|
|
||||||
_sun_label = Label.new()
|
|
||||||
_sun_label.text = "Sun: —"
|
|
||||||
_vbox.add_child(_sun_label)
|
|
||||||
|
|
||||||
_moon_label = Label.new()
|
|
||||||
_moon_label.text = "Moon: —"
|
|
||||||
_vbox.add_child(_moon_label)
|
|
||||||
|
|
||||||
_ambient_label = Label.new()
|
|
||||||
_ambient_label.text = "Ambient: —"
|
|
||||||
_vbox.add_child(_ambient_label)
|
|
||||||
|
|
||||||
_vbox.add_child(HSeparator.new())
|
|
||||||
|
|
||||||
_weather_label = Label.new()
|
|
||||||
_weather_label.text = "Weather: Clear"
|
|
||||||
_vbox.add_child(_weather_label)
|
|
||||||
|
|
||||||
var weather_hbox := HBoxContainer.new()
|
|
||||||
_vbox.add_child(weather_hbox)
|
|
||||||
|
|
||||||
var weather_label := Label.new()
|
|
||||||
weather_label.text = "Set:"
|
|
||||||
weather_label.custom_minimum_size.x = 60
|
|
||||||
weather_hbox.add_child(weather_label)
|
|
||||||
|
|
||||||
_weather_dropdown = OptionButton.new()
|
|
||||||
_weather_dropdown.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
||||||
for state_name in WeatherProfile.WeatherState.keys():
|
|
||||||
_weather_dropdown.add_item(state_name)
|
|
||||||
weather_hbox.add_child(_weather_dropdown)
|
|
||||||
|
|
||||||
_vbox.add_child(HSeparator.new())
|
|
||||||
|
|
||||||
_cloud_label = Label.new()
|
|
||||||
_cloud_label.text = "Clouds: 0%"
|
|
||||||
_vbox.add_child(_cloud_label)
|
|
||||||
|
|
||||||
_fog_label = Label.new()
|
|
||||||
_fog_label.text = "Fog: —"
|
|
||||||
_vbox.add_child(_fog_label)
|
|
||||||
|
|
||||||
_rain_label = Label.new()
|
|
||||||
_rain_label.text = "Rain: 0% | Snow: 0%"
|
|
||||||
_vbox.add_child(_rain_label)
|
|
||||||
|
|
||||||
_seed_label = Label.new()
|
|
||||||
_seed_label.text = "Seed: 0 | Day: 1"
|
|
||||||
_vbox.add_child(_seed_label)
|
|
||||||
|
|
||||||
#var meteor_button := Button.new()
|
|
||||||
#meteor_button.text = "Trigger Meteor Shower"
|
|
||||||
#meteor_button.pressed.connect(_on_meteor_pressed)
|
|
||||||
#_vbox.add_child(meteor_button)
|
|
||||||
|
|
||||||
|
|
||||||
func _connect_signals() -> void:
|
|
||||||
_time_slider.value_changed.connect(_on_time_slider_changed)
|
|
||||||
_pause_button.toggled.connect(_on_pause_toggled)
|
|
||||||
_weather_dropdown.item_selected.connect(_on_weather_selected)
|
|
||||||
|
|
||||||
|
|
||||||
func _update_labels() -> void:
|
|
||||||
if dynamic_sky == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
_preset_label.text = "Preset: %s" % dynamic_sky.preset_name if dynamic_sky.preset_name != "" else "Preset: (none)"
|
|
||||||
|
|
||||||
var time := dynamic_sky.get_time_of_day()
|
|
||||||
var hours := int(time * 24.0)
|
|
||||||
var minutes := int(fmod(time * 24.0 * 60.0, 60.0))
|
|
||||||
_time_label.text = "Time: %02d:%02d (%.3f)" % [hours, minutes, time]
|
|
||||||
|
|
||||||
if not _time_slider.has_focus():
|
|
||||||
_time_slider.set_value_no_signal(time)
|
|
||||||
|
|
||||||
if dynamic_sky.day_night_controller:
|
|
||||||
_period_label.text = "Period: %s" % dynamic_sky.day_night_controller.get_time_period().to_upper()
|
|
||||||
_pause_button.set_pressed_no_signal(dynamic_sky.day_night_controller.paused)
|
|
||||||
|
|
||||||
if dynamic_sky.sun_light:
|
|
||||||
_sun_label.text = "Sun: %.2f %s" % [
|
|
||||||
dynamic_sky.sun_light.light_energy,
|
|
||||||
"visible" if dynamic_sky.sun_light.visible else "hidden"
|
|
||||||
]
|
|
||||||
|
|
||||||
if dynamic_sky.moon_light:
|
|
||||||
_moon_label.text = "Moon: %.2f %s" % [
|
|
||||||
dynamic_sky.moon_light.light_energy,
|
|
||||||
"visible" if dynamic_sky.moon_light.visible else "hidden"
|
|
||||||
]
|
|
||||||
|
|
||||||
if dynamic_sky.world_environment and dynamic_sky.world_environment.environment:
|
|
||||||
var env := dynamic_sky.world_environment.environment
|
|
||||||
_ambient_label.text = "Ambient: %.2f" % env.ambient_light_energy
|
|
||||||
_fog_label.text = "Fog: %s density=%.4f" % [
|
|
||||||
"ON" if env.fog_enabled else "OFF",
|
|
||||||
env.fog_density
|
|
||||||
]
|
|
||||||
|
|
||||||
var weather := dynamic_sky.get_current_weather()
|
|
||||||
var weather_name: String = WeatherProfile.WeatherState.keys()[weather]
|
|
||||||
_weather_label.text = "Weather: %s" % weather_name
|
|
||||||
|
|
||||||
if dynamic_sky.weather_controller:
|
|
||||||
var coverage := dynamic_sky.weather_controller.get_cloud_coverage()
|
|
||||||
_cloud_label.text = "Clouds: %d%%" % int(coverage * 100)
|
|
||||||
|
|
||||||
if dynamic_sky.weather_controller.is_transitioning():
|
|
||||||
var progress := dynamic_sky.weather_controller.get_transition_progress()
|
|
||||||
_weather_label.text += " (transition %.0f%%)" % (progress * 100)
|
|
||||||
|
|
||||||
if dynamic_sky.weather_controller:
|
|
||||||
var rain := dynamic_sky.weather_controller.get_rain_intensity()
|
|
||||||
var snow := dynamic_sky.weather_controller.get_snow_intensity()
|
|
||||||
_rain_label.text = "Rain: %d%% | Snow: %d%%" % [int(rain * 100), int(snow * 100)]
|
|
||||||
|
|
||||||
var day_num := 1
|
|
||||||
if dynamic_sky.day_night_controller:
|
|
||||||
day_num = dynamic_sky.day_night_controller.current_day
|
|
||||||
_seed_label.text = "Seed: %d | Day: %d" % [dynamic_sky.deterministic_seed, day_num]
|
|
||||||
|
|
||||||
|
|
||||||
func _on_time_slider_changed(value: float) -> void:
|
|
||||||
if dynamic_sky:
|
|
||||||
dynamic_sky.set_time_of_day(value)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_pause_toggled(pressed: bool) -> void:
|
|
||||||
if dynamic_sky:
|
|
||||||
if pressed:
|
|
||||||
dynamic_sky.pause_time()
|
|
||||||
else:
|
|
||||||
dynamic_sky.resume_time()
|
|
||||||
_pause_button.text = "Resume" if pressed else "Pause"
|
|
||||||
|
|
||||||
|
|
||||||
func _on_weather_selected(index: int) -> void:
|
|
||||||
if dynamic_sky:
|
|
||||||
var state: WeatherProfile.WeatherState = index as WeatherProfile.WeatherState
|
|
||||||
dynamic_sky.set_weather(state)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_meteor_pressed() -> void:
|
|
||||||
if dynamic_sky:
|
|
||||||
dynamic_sky.trigger_meteor_shower(30.0)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cimhpqq1qo80b
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name SkyboxPresetLibrary
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
signal preset_changed(preset: SkyPreset)
|
|
||||||
signal preset_applied(preset_name: String)
|
|
||||||
signal preset_reverted(preset_name: String)
|
|
||||||
|
|
||||||
@export var presets: Array[SkyPreset] = []
|
|
||||||
@export var current_preset_index: int = 0:
|
|
||||||
set(value):
|
|
||||||
current_preset_index = clampi(value, 0, maxi(0, presets.size() - 1))
|
|
||||||
if current_preset_index < presets.size():
|
|
||||||
_on_preset_selected(presets[current_preset_index])
|
|
||||||
|
|
||||||
var _base_preset: SkyPreset
|
|
||||||
var _runtime_overrides: SkyConfig
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if presets.is_empty():
|
|
||||||
_initialize_default_presets()
|
|
||||||
if current_preset_index < presets.size():
|
|
||||||
_base_preset = presets[current_preset_index]
|
|
||||||
|
|
||||||
|
|
||||||
func _initialize_default_presets() -> void:
|
|
||||||
presets.clear()
|
|
||||||
presets.append(SkyPreset.create_clear_day())
|
|
||||||
presets.append(SkyPreset.create_sunset())
|
|
||||||
presets.append(SkyPreset.create_night())
|
|
||||||
presets.append(SkyPreset.create_overcast())
|
|
||||||
presets.append(SkyPreset.create_storm())
|
|
||||||
presets.append(SkyPreset.create_dawn())
|
|
||||||
|
|
||||||
|
|
||||||
func get_preset_names() -> PackedStringArray:
|
|
||||||
var names := PackedStringArray()
|
|
||||||
for preset in presets:
|
|
||||||
names.append(preset.preset_name)
|
|
||||||
return names
|
|
||||||
|
|
||||||
|
|
||||||
func get_current_preset() -> SkyPreset:
|
|
||||||
if current_preset_index < presets.size():
|
|
||||||
return presets[current_preset_index]
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func get_preset_by_name(preset_name: String) -> SkyPreset:
|
|
||||||
for preset in presets:
|
|
||||||
if preset.preset_name == preset_name:
|
|
||||||
return preset
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func get_preset_by_type(preset_type: SkyPreset.PresetType) -> SkyPreset:
|
|
||||||
for preset in presets:
|
|
||||||
if preset.preset_type == preset_type:
|
|
||||||
return preset
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func apply_preset(preset_name: String) -> bool:
|
|
||||||
var preset := get_preset_by_name(preset_name)
|
|
||||||
if preset == null:
|
|
||||||
push_warning("SkyboxPresetLibrary: Preset '%s' not found" % preset_name)
|
|
||||||
return false
|
|
||||||
|
|
||||||
for i in presets.size():
|
|
||||||
if presets[i] == preset:
|
|
||||||
current_preset_index = i
|
|
||||||
break
|
|
||||||
|
|
||||||
_base_preset = preset
|
|
||||||
_runtime_overrides = null
|
|
||||||
preset_applied.emit(preset_name)
|
|
||||||
preset_changed.emit(preset)
|
|
||||||
return true
|
|
||||||
|
|
||||||
|
|
||||||
func apply_preset_by_type(preset_type: SkyPreset.PresetType) -> bool:
|
|
||||||
var preset := get_preset_by_type(preset_type)
|
|
||||||
if preset == null:
|
|
||||||
push_warning("SkyboxPresetLibrary: Preset type '%s' not found" % SkyPreset.PresetType.keys()[preset_type])
|
|
||||||
return false
|
|
||||||
return apply_preset(preset.preset_name)
|
|
||||||
|
|
||||||
|
|
||||||
func revert_to_preset() -> void:
|
|
||||||
_runtime_overrides = null
|
|
||||||
if _base_preset:
|
|
||||||
preset_reverted.emit(_base_preset.preset_name)
|
|
||||||
preset_changed.emit(_base_preset)
|
|
||||||
|
|
||||||
|
|
||||||
func set_runtime_override(config: SkyConfig) -> void:
|
|
||||||
_runtime_overrides = config
|
|
||||||
|
|
||||||
|
|
||||||
func get_effective_config() -> SkyConfig:
|
|
||||||
if _runtime_overrides != null:
|
|
||||||
return _runtime_overrides
|
|
||||||
if _base_preset != null and _base_preset.config != null:
|
|
||||||
return _base_preset.config
|
|
||||||
return SkyConfig.new()
|
|
||||||
|
|
||||||
|
|
||||||
func has_runtime_overrides() -> bool:
|
|
||||||
return _runtime_overrides != null
|
|
||||||
|
|
||||||
|
|
||||||
func add_preset(preset: SkyPreset) -> void:
|
|
||||||
if preset not in presets:
|
|
||||||
presets.append(preset)
|
|
||||||
|
|
||||||
|
|
||||||
func remove_preset(preset_name: String) -> bool:
|
|
||||||
for i in presets.size():
|
|
||||||
if presets[i].preset_name == preset_name:
|
|
||||||
presets.remove_at(i)
|
|
||||||
if current_preset_index >= presets.size():
|
|
||||||
current_preset_index = maxi(0, presets.size() - 1)
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func _on_preset_selected(preset: SkyPreset) -> void:
|
|
||||||
_base_preset = preset
|
|
||||||
_runtime_overrides = null
|
|
||||||
preset_changed.emit(preset)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cb8c6ug44jx4t
|
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name VFXController
|
|
||||||
extends Node3D
|
|
||||||
|
|
||||||
signal shooting_star_spawned(position: Vector3, direction: Vector3)
|
|
||||||
signal meteor_shower_started()
|
|
||||||
signal meteor_shower_ended()
|
|
||||||
|
|
||||||
@export_group("Shooting Stars")
|
|
||||||
@export var shooting_stars_enabled: bool = true
|
|
||||||
@export var shooting_star_frequency: float = 0.05
|
|
||||||
@export var min_spawn_interval: float = 5.0
|
|
||||||
@export var max_spawn_interval: float = 30.0
|
|
||||||
|
|
||||||
@export_group("Shooting Star Appearance")
|
|
||||||
@export var trail_length: float = 2.0
|
|
||||||
@export var trail_width: float = 0.05
|
|
||||||
@export var star_brightness: float = 1.5
|
|
||||||
@export var star_color: Color = Color(1.0, 1.0, 0.9)
|
|
||||||
@export var trail_fade_time: float = 0.5
|
|
||||||
|
|
||||||
@export_group("Meteor Shower")
|
|
||||||
@export var meteor_shower_active: bool = false
|
|
||||||
@export var meteor_shower_intensity: float = 1.0
|
|
||||||
@export var meteors_per_second: float = 3.0
|
|
||||||
@export var meteor_shower_duration: float = 60.0
|
|
||||||
|
|
||||||
@export_group("Meteor Appearance")
|
|
||||||
@export var meteor_trail_length: float = 4.0
|
|
||||||
@export var meteor_brightness: float = 2.0
|
|
||||||
@export var meteor_color: Color = Color(1.0, 0.8, 0.5)
|
|
||||||
|
|
||||||
@export_group("Spawn Area")
|
|
||||||
@export var spawn_radius: float = 500.0
|
|
||||||
@export var spawn_height_min: float = 100.0
|
|
||||||
@export var spawn_height_max: float = 200.0
|
|
||||||
@export var spawn_direction_variance: float = 30.0
|
|
||||||
|
|
||||||
@export_group("Audio")
|
|
||||||
@export var meteor_shower_audio_event: String = ""
|
|
||||||
|
|
||||||
var _spawn_timer: float = 0.0
|
|
||||||
var _next_spawn_time: float = 0.0
|
|
||||||
var _meteor_spawn_accumulator: float = 0.0
|
|
||||||
var _meteor_shower_elapsed: float = 0.0
|
|
||||||
var _active_stars: Array[Dictionary] = []
|
|
||||||
var _star_material: ShaderMaterial
|
|
||||||
var _is_night: bool = false
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_setup_star_mesh()
|
|
||||||
_schedule_next_shooting_star()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if not _is_night:
|
|
||||||
return
|
|
||||||
|
|
||||||
if shooting_stars_enabled:
|
|
||||||
_process_shooting_stars(delta)
|
|
||||||
|
|
||||||
if meteor_shower_active:
|
|
||||||
_process_meteor_shower(delta)
|
|
||||||
|
|
||||||
_update_active_stars(delta)
|
|
||||||
|
|
||||||
|
|
||||||
func _setup_star_mesh() -> void:
|
|
||||||
_star_material = ShaderMaterial.new()
|
|
||||||
_star_material.shader = _get_star_shader()
|
|
||||||
_star_material.set_shader_parameter("color", star_color)
|
|
||||||
_star_material.set_shader_parameter("brightness", star_brightness)
|
|
||||||
|
|
||||||
|
|
||||||
func _get_star_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type spatial;
|
|
||||||
render_mode unshaded, depth_draw_never, cull_disabled, blend_add;
|
|
||||||
|
|
||||||
uniform vec4 color : source_color = vec4(1.0, 1.0, 0.9, 1.0);
|
|
||||||
uniform float brightness = 1.5;
|
|
||||||
uniform float fade = 1.0;
|
|
||||||
uniform float trail_progress = 0.0;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
VERTEX.y *= mix(0.1, 1.0, trail_progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
float gradient = UV.y;
|
|
||||||
float alpha = gradient * fade;
|
|
||||||
ALBEDO = color.rgb * brightness;
|
|
||||||
ALPHA = alpha * color.a;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
|
|
||||||
|
|
||||||
func _schedule_next_shooting_star() -> void:
|
|
||||||
_next_spawn_time = randf_range(min_spawn_interval, max_spawn_interval)
|
|
||||||
_next_spawn_time /= maxf(0.01, shooting_star_frequency)
|
|
||||||
_spawn_timer = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func _process_shooting_stars(delta: float) -> void:
|
|
||||||
_spawn_timer += delta
|
|
||||||
|
|
||||||
if _spawn_timer >= _next_spawn_time:
|
|
||||||
_spawn_shooting_star()
|
|
||||||
_schedule_next_shooting_star()
|
|
||||||
|
|
||||||
|
|
||||||
func _process_meteor_shower(delta: float) -> void:
|
|
||||||
_meteor_shower_elapsed += delta
|
|
||||||
|
|
||||||
if _meteor_shower_elapsed >= meteor_shower_duration:
|
|
||||||
stop_meteor_shower()
|
|
||||||
return
|
|
||||||
|
|
||||||
_meteor_spawn_accumulator += meteors_per_second * meteor_shower_intensity * delta
|
|
||||||
|
|
||||||
while _meteor_spawn_accumulator >= 1.0:
|
|
||||||
_meteor_spawn_accumulator -= 1.0
|
|
||||||
_spawn_meteor()
|
|
||||||
|
|
||||||
|
|
||||||
func _spawn_shooting_star() -> void:
|
|
||||||
var spawn_pos := _get_random_sky_position()
|
|
||||||
var direction := _get_random_fall_direction()
|
|
||||||
|
|
||||||
var star_data := {
|
|
||||||
"position": spawn_pos,
|
|
||||||
"direction": direction,
|
|
||||||
"speed": randf_range(50.0, 100.0),
|
|
||||||
"lifetime": 0.0,
|
|
||||||
"max_lifetime": trail_fade_time + randf_range(0.2, 0.5),
|
|
||||||
"trail_length": trail_length * randf_range(0.8, 1.2),
|
|
||||||
"brightness": star_brightness * randf_range(0.8, 1.2),
|
|
||||||
"color": star_color,
|
|
||||||
"mesh": _create_star_trail(spawn_pos, direction),
|
|
||||||
"is_meteor": false
|
|
||||||
}
|
|
||||||
|
|
||||||
_active_stars.append(star_data)
|
|
||||||
shooting_star_spawned.emit(spawn_pos, direction)
|
|
||||||
|
|
||||||
|
|
||||||
func _spawn_meteor() -> void:
|
|
||||||
var spawn_pos := _get_random_sky_position()
|
|
||||||
var direction := _get_random_fall_direction()
|
|
||||||
|
|
||||||
var star_data := {
|
|
||||||
"position": spawn_pos,
|
|
||||||
"direction": direction,
|
|
||||||
"speed": randf_range(80.0, 150.0),
|
|
||||||
"lifetime": 0.0,
|
|
||||||
"max_lifetime": trail_fade_time + randf_range(0.3, 0.7),
|
|
||||||
"trail_length": meteor_trail_length * randf_range(0.8, 1.2),
|
|
||||||
"brightness": meteor_brightness * randf_range(0.8, 1.2),
|
|
||||||
"color": meteor_color,
|
|
||||||
"mesh": _create_star_trail(spawn_pos, direction, true),
|
|
||||||
"is_meteor": true
|
|
||||||
}
|
|
||||||
|
|
||||||
_active_stars.append(star_data)
|
|
||||||
|
|
||||||
|
|
||||||
func _get_random_sky_position() -> Vector3:
|
|
||||||
var angle := randf() * TAU
|
|
||||||
var radius := randf_range(spawn_radius * 0.3, spawn_radius)
|
|
||||||
var height := randf_range(spawn_height_min, spawn_height_max)
|
|
||||||
|
|
||||||
return Vector3(
|
|
||||||
cos(angle) * radius,
|
|
||||||
height,
|
|
||||||
sin(angle) * radius
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func _get_random_fall_direction() -> Vector3:
|
|
||||||
var base_dir := Vector3(-0.5, -0.8, -0.3).normalized()
|
|
||||||
|
|
||||||
var variance := deg_to_rad(spawn_direction_variance)
|
|
||||||
var curr_rotation := Basis(Vector3.UP, randf() * TAU)
|
|
||||||
curr_rotation = curr_rotation.rotated(Vector3.RIGHT, randf_range(-variance, variance))
|
|
||||||
|
|
||||||
return (curr_rotation * base_dir).normalized()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_star_trail(position: Vector3, direction: Vector3, is_meteor: bool = false) -> MeshInstance3D:
|
|
||||||
var mesh_instance := MeshInstance3D.new()
|
|
||||||
|
|
||||||
var length := meteor_trail_length if is_meteor else trail_length
|
|
||||||
var width := trail_width * (1.5 if is_meteor else 1.0)
|
|
||||||
|
|
||||||
var quad := QuadMesh.new()
|
|
||||||
quad.size = Vector2(width, length)
|
|
||||||
mesh_instance.mesh = quad
|
|
||||||
|
|
||||||
var material := _star_material.duplicate() as ShaderMaterial
|
|
||||||
material.set_shader_parameter("color", meteor_color if is_meteor else star_color)
|
|
||||||
material.set_shader_parameter("brightness", meteor_brightness if is_meteor else star_brightness)
|
|
||||||
mesh_instance.material_override = material
|
|
||||||
|
|
||||||
mesh_instance.position = position
|
|
||||||
add_child(mesh_instance)
|
|
||||||
mesh_instance.look_at(position + direction, Vector3.UP)
|
|
||||||
mesh_instance.rotate_object_local(Vector3.RIGHT, PI / 2.0)
|
|
||||||
return mesh_instance
|
|
||||||
|
|
||||||
|
|
||||||
func _update_active_stars(delta: float) -> void:
|
|
||||||
var stars_to_remove: Array[int] = []
|
|
||||||
|
|
||||||
for i in _active_stars.size():
|
|
||||||
var star: Dictionary = _active_stars[i]
|
|
||||||
star["lifetime"] += delta
|
|
||||||
|
|
||||||
var progress: float = star["lifetime"] / star["max_lifetime"]
|
|
||||||
|
|
||||||
if progress >= 1.0:
|
|
||||||
stars_to_remove.append(i)
|
|
||||||
continue
|
|
||||||
|
|
||||||
var mesh: MeshInstance3D = star["mesh"]
|
|
||||||
if is_instance_valid(mesh):
|
|
||||||
star["position"] += star["direction"] * star["speed"] * delta
|
|
||||||
mesh.position = star["position"]
|
|
||||||
|
|
||||||
var fade := 1.0 - smoothstep(0.5, 1.0, progress)
|
|
||||||
var material := mesh.material_override as ShaderMaterial
|
|
||||||
if material:
|
|
||||||
material.set_shader_parameter("fade", fade)
|
|
||||||
material.set_shader_parameter("trail_progress", minf(progress * 3.0, 1.0))
|
|
||||||
|
|
||||||
for i in range(stars_to_remove.size() - 1, -1, -1):
|
|
||||||
var idx: int = stars_to_remove[i]
|
|
||||||
var star: Dictionary = _active_stars[idx]
|
|
||||||
var mesh: MeshInstance3D = star["mesh"]
|
|
||||||
if is_instance_valid(mesh):
|
|
||||||
mesh.queue_free()
|
|
||||||
_active_stars.remove_at(idx)
|
|
||||||
|
|
||||||
|
|
||||||
func set_night_mode(is_night: bool) -> void:
|
|
||||||
_is_night = is_night
|
|
||||||
|
|
||||||
if not is_night:
|
|
||||||
_clear_all_stars()
|
|
||||||
|
|
||||||
|
|
||||||
func _clear_all_stars() -> void:
|
|
||||||
for star in _active_stars:
|
|
||||||
var mesh: MeshInstance3D = star["mesh"]
|
|
||||||
if is_instance_valid(mesh):
|
|
||||||
mesh.queue_free()
|
|
||||||
_active_stars.clear()
|
|
||||||
|
|
||||||
|
|
||||||
func start_meteor_shower(duration: float = -1.0) -> void:
|
|
||||||
if duration > 0:
|
|
||||||
meteor_shower_duration = duration
|
|
||||||
|
|
||||||
meteor_shower_active = true
|
|
||||||
_meteor_shower_elapsed = 0.0
|
|
||||||
_meteor_spawn_accumulator = 0.0
|
|
||||||
|
|
||||||
meteor_shower_started.emit()
|
|
||||||
|
|
||||||
if meteor_shower_audio_event != "":
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func stop_meteor_shower() -> void:
|
|
||||||
meteor_shower_active = false
|
|
||||||
_meteor_shower_elapsed = 0.0
|
|
||||||
meteor_shower_ended.emit()
|
|
||||||
|
|
||||||
|
|
||||||
func trigger_shooting_star() -> void:
|
|
||||||
if _is_night:
|
|
||||||
_spawn_shooting_star()
|
|
||||||
|
|
||||||
|
|
||||||
func set_shooting_star_appearance(color: Color, brightness: float, length: float) -> void:
|
|
||||||
star_color = color
|
|
||||||
star_brightness = brightness
|
|
||||||
trail_length = length
|
|
||||||
|
|
||||||
|
|
||||||
func set_meteor_appearance(color: Color, brightness: float, length: float) -> void:
|
|
||||||
meteor_color = color
|
|
||||||
meteor_brightness = brightness
|
|
||||||
meteor_trail_length = length
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cnvj3m5fpsdtj
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name WeatherController
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
signal weather_state_changed(old_state: WeatherProfile.WeatherState, new_state: WeatherProfile.WeatherState)
|
|
||||||
signal weather_transition_started(from: WeatherProfile.WeatherState, to: WeatherProfile.WeatherState)
|
|
||||||
signal weather_transition_completed(state: WeatherProfile.WeatherState)
|
|
||||||
signal weather_state_entered(state: WeatherProfile.WeatherState)
|
|
||||||
signal weather_state_exited(state: WeatherProfile.WeatherState)
|
|
||||||
|
|
||||||
@export_group("Weather Profiles")
|
|
||||||
@export var weather_profiles: Array[WeatherProfile] = []
|
|
||||||
@export var current_weather: WeatherProfile.WeatherState = WeatherProfile.WeatherState.CLEAR:
|
|
||||||
set(value):
|
|
||||||
if _changing_weather:
|
|
||||||
current_weather = value
|
|
||||||
return
|
|
||||||
if value != current_weather:
|
|
||||||
_request_weather_change(value)
|
|
||||||
|
|
||||||
@export_group("Transition Settings")
|
|
||||||
@export var default_transition_duration: float = 5.0
|
|
||||||
@export var transition_curve: Curve
|
|
||||||
|
|
||||||
@export_group("Random Weather")
|
|
||||||
@export var enable_random_weather: bool = false
|
|
||||||
@export var min_weather_duration: float = 60.0
|
|
||||||
@export var max_weather_duration: float = 300.0
|
|
||||||
@export var snow_enabled: bool = true
|
|
||||||
|
|
||||||
@export_group("Scripted Timeline")
|
|
||||||
@export var use_scripted_timeline: bool = false
|
|
||||||
@export var weather_timeline: Array[Dictionary] = []
|
|
||||||
|
|
||||||
var _current_profile: WeatherProfile
|
|
||||||
var _target_profile: WeatherProfile
|
|
||||||
var _transition_weight: float = 1.0
|
|
||||||
var _is_transitioning: bool = false
|
|
||||||
var _transition_duration: float = 0.0
|
|
||||||
var _transition_elapsed: float = 0.0
|
|
||||||
var _random_weather_timer: float = 0.0
|
|
||||||
var _next_weather_change: float = 0.0
|
|
||||||
var _timeline_index: int = 0
|
|
||||||
var _timeline_timer: float = 0.0
|
|
||||||
var _changing_weather: bool = false
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if weather_profiles.is_empty():
|
|
||||||
_initialize_default_profiles()
|
|
||||||
|
|
||||||
if transition_curve == null:
|
|
||||||
transition_curve = Curve.new()
|
|
||||||
transition_curve.add_point(Vector2(0.0, 0.0))
|
|
||||||
transition_curve.add_point(Vector2(0.5, 0.5))
|
|
||||||
transition_curve.add_point(Vector2(1.0, 1.0))
|
|
||||||
|
|
||||||
_current_profile = get_profile_for_state(current_weather)
|
|
||||||
_target_profile = _current_profile
|
|
||||||
_schedule_next_random_weather()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if _is_transitioning:
|
|
||||||
_process_transition(delta)
|
|
||||||
|
|
||||||
if enable_random_weather and not use_scripted_timeline:
|
|
||||||
_process_random_weather(delta)
|
|
||||||
|
|
||||||
if use_scripted_timeline:
|
|
||||||
_process_scripted_timeline(delta)
|
|
||||||
|
|
||||||
|
|
||||||
func _initialize_default_profiles() -> void:
|
|
||||||
weather_profiles.clear()
|
|
||||||
weather_profiles.append(WeatherProfile.create_clear())
|
|
||||||
weather_profiles.append(WeatherProfile.create_cloudy())
|
|
||||||
weather_profiles.append(WeatherProfile.create_overcast())
|
|
||||||
weather_profiles.append(WeatherProfile.create_rain())
|
|
||||||
weather_profiles.append(WeatherProfile.create_storm())
|
|
||||||
weather_profiles.append(WeatherProfile.create_snow())
|
|
||||||
|
|
||||||
|
|
||||||
func _process_transition(delta: float) -> void:
|
|
||||||
_transition_elapsed += delta
|
|
||||||
var t := clampf(_transition_elapsed / _transition_duration, 0.0, 1.0)
|
|
||||||
|
|
||||||
if transition_curve:
|
|
||||||
_transition_weight = transition_curve.sample(t)
|
|
||||||
else:
|
|
||||||
_transition_weight = t
|
|
||||||
|
|
||||||
if t >= 1.0:
|
|
||||||
_complete_transition()
|
|
||||||
|
|
||||||
|
|
||||||
func _complete_transition() -> void:
|
|
||||||
_is_transitioning = false
|
|
||||||
_transition_weight = 1.0
|
|
||||||
_current_profile = _target_profile
|
|
||||||
var new_state := _current_profile.weather_state
|
|
||||||
weather_transition_completed.emit(new_state)
|
|
||||||
weather_state_entered.emit(new_state)
|
|
||||||
|
|
||||||
|
|
||||||
func _process_random_weather(delta: float) -> void:
|
|
||||||
_random_weather_timer += delta
|
|
||||||
|
|
||||||
if _random_weather_timer >= _next_weather_change:
|
|
||||||
_random_weather_timer = 0.0
|
|
||||||
_trigger_random_weather_change()
|
|
||||||
_schedule_next_random_weather()
|
|
||||||
|
|
||||||
|
|
||||||
func _schedule_next_random_weather() -> void:
|
|
||||||
_next_weather_change = randf_range(min_weather_duration, max_weather_duration)
|
|
||||||
|
|
||||||
|
|
||||||
func _trigger_random_weather_change() -> void:
|
|
||||||
var available_states: Array[WeatherProfile.WeatherState] = []
|
|
||||||
for state in WeatherProfile.WeatherState.values():
|
|
||||||
if state == current_weather:
|
|
||||||
continue
|
|
||||||
if state == WeatherProfile.WeatherState.SNOW and not snow_enabled:
|
|
||||||
continue
|
|
||||||
available_states.append(state)
|
|
||||||
|
|
||||||
if available_states.is_empty():
|
|
||||||
return
|
|
||||||
|
|
||||||
var new_state: WeatherProfile.WeatherState = available_states.pick_random()
|
|
||||||
set_weather(new_state)
|
|
||||||
|
|
||||||
|
|
||||||
func _process_scripted_timeline(delta: float) -> void:
|
|
||||||
if weather_timeline.is_empty():
|
|
||||||
return
|
|
||||||
|
|
||||||
_timeline_timer += delta
|
|
||||||
|
|
||||||
if _timeline_index < weather_timeline.size():
|
|
||||||
var entry: Dictionary = weather_timeline[_timeline_index]
|
|
||||||
var trigger_time: float = entry.get("time", 0.0)
|
|
||||||
|
|
||||||
if _timeline_timer >= trigger_time:
|
|
||||||
var state_name: String = entry.get("state", "CLEAR")
|
|
||||||
var duration: float = entry.get("duration", default_transition_duration)
|
|
||||||
|
|
||||||
if WeatherProfile.WeatherState.has(state_name):
|
|
||||||
var state: WeatherProfile.WeatherState = WeatherProfile.WeatherState.get(state_name)
|
|
||||||
set_weather(state, duration)
|
|
||||||
|
|
||||||
_timeline_index += 1
|
|
||||||
|
|
||||||
|
|
||||||
func _request_weather_change(new_state: WeatherProfile.WeatherState) -> void:
|
|
||||||
var profile := get_profile_for_state(new_state)
|
|
||||||
if profile == null:
|
|
||||||
push_warning("WeatherController: No profile for state %s" % WeatherProfile.WeatherState.keys()[new_state])
|
|
||||||
return
|
|
||||||
|
|
||||||
set_weather(new_state, profile.default_transition_duration)
|
|
||||||
|
|
||||||
|
|
||||||
func get_profile_for_state(state: WeatherProfile.WeatherState) -> WeatherProfile:
|
|
||||||
for profile in weather_profiles:
|
|
||||||
if profile.weather_state == state:
|
|
||||||
return profile
|
|
||||||
return null
|
|
||||||
|
|
||||||
|
|
||||||
func set_weather(state: WeatherProfile.WeatherState, transition_duration: float = -1.0) -> void:
|
|
||||||
var profile := get_profile_for_state(state)
|
|
||||||
if profile == null:
|
|
||||||
push_warning("WeatherController: No profile for state %s" % WeatherProfile.WeatherState.keys()[state])
|
|
||||||
return
|
|
||||||
|
|
||||||
if _current_profile:
|
|
||||||
weather_state_exited.emit(_current_profile.weather_state)
|
|
||||||
|
|
||||||
var old_state := current_weather
|
|
||||||
_changing_weather = true
|
|
||||||
current_weather = state
|
|
||||||
_changing_weather = false
|
|
||||||
_target_profile = profile
|
|
||||||
|
|
||||||
if transition_duration < 0:
|
|
||||||
transition_duration = profile.default_transition_duration
|
|
||||||
|
|
||||||
_transition_duration = transition_duration
|
|
||||||
_transition_elapsed = 0.0
|
|
||||||
_is_transitioning = true
|
|
||||||
_transition_weight = 0.0
|
|
||||||
|
|
||||||
weather_transition_started.emit(old_state, state)
|
|
||||||
weather_state_changed.emit(old_state, state)
|
|
||||||
|
|
||||||
|
|
||||||
func set_weather_immediate(state: WeatherProfile.WeatherState) -> void:
|
|
||||||
var profile := get_profile_for_state(state)
|
|
||||||
if profile == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
if _current_profile:
|
|
||||||
weather_state_exited.emit(_current_profile.weather_state)
|
|
||||||
|
|
||||||
var old_state := current_weather
|
|
||||||
_changing_weather = true
|
|
||||||
current_weather = state
|
|
||||||
_changing_weather = false
|
|
||||||
_current_profile = profile
|
|
||||||
_target_profile = profile
|
|
||||||
_is_transitioning = false
|
|
||||||
_transition_weight = 1.0
|
|
||||||
|
|
||||||
weather_state_changed.emit(old_state, state)
|
|
||||||
weather_state_entered.emit(state)
|
|
||||||
|
|
||||||
|
|
||||||
func get_current_profile() -> WeatherProfile:
|
|
||||||
if _is_transitioning and _current_profile and _target_profile:
|
|
||||||
return _current_profile.lerp_to(_target_profile, _transition_weight)
|
|
||||||
return _current_profile
|
|
||||||
|
|
||||||
|
|
||||||
func get_cloud_density() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.cloud_density if profile else 0.2
|
|
||||||
|
|
||||||
|
|
||||||
func get_cloud_opacity() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.cloud_opacity if profile else 0.7
|
|
||||||
|
|
||||||
|
|
||||||
func get_cloud_coverage() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.cloud_coverage if profile else 0.3
|
|
||||||
|
|
||||||
|
|
||||||
func get_cloud_color() -> Color:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.cloud_color if profile else Color.WHITE
|
|
||||||
|
|
||||||
|
|
||||||
func get_wind_speed() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.wind_speed if profile else 1.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_wind_direction() -> Vector2:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.wind_direction if profile else Vector2(1.0, 0.0)
|
|
||||||
|
|
||||||
|
|
||||||
func get_rain_intensity() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.rain_intensity if profile else 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_snow_intensity() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.snow_intensity if profile else 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func is_lightning_active() -> bool:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.lightning_enabled if profile else false
|
|
||||||
|
|
||||||
|
|
||||||
func get_lightning_frequency() -> float:
|
|
||||||
var profile := get_current_profile()
|
|
||||||
return profile.lightning_frequency if profile else 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func get_transition_progress() -> float:
|
|
||||||
return _transition_weight
|
|
||||||
|
|
||||||
|
|
||||||
func is_transitioning() -> bool:
|
|
||||||
return _is_transitioning
|
|
||||||
|
|
||||||
|
|
||||||
func reset_timeline() -> void:
|
|
||||||
_timeline_index = 0
|
|
||||||
_timeline_timer = 0.0
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://blyx8v2gq8nlw
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
@tool
|
|
||||||
class_name WeatherKillVolume
|
|
||||||
extends Area3D
|
|
||||||
|
|
||||||
enum VolumeShape {
|
|
||||||
BOX,
|
|
||||||
SPHERE,
|
|
||||||
CYLINDER
|
|
||||||
}
|
|
||||||
|
|
||||||
@export_group("Volume Settings")
|
|
||||||
@export var volume_shape: VolumeShape = VolumeShape.BOX:
|
|
||||||
set(value):
|
|
||||||
volume_shape = value
|
|
||||||
_update_collision_shape()
|
|
||||||
|
|
||||||
@export var volume_size: Vector3 = Vector3(10.0, 5.0, 10.0):
|
|
||||||
set(value):
|
|
||||||
volume_size = value
|
|
||||||
_update_collision_shape()
|
|
||||||
|
|
||||||
@export var volume_radius: float = 5.0:
|
|
||||||
set(value):
|
|
||||||
volume_radius = value
|
|
||||||
_update_collision_shape()
|
|
||||||
|
|
||||||
@export_group("Kill Behavior")
|
|
||||||
@export var enabled: bool = true
|
|
||||||
@export var kill_priority: int = 0
|
|
||||||
@export var instant_kill: bool = true
|
|
||||||
@export var fade_out_margin: float = 1.0
|
|
||||||
@export var fade_out_duration: float = 0.3
|
|
||||||
|
|
||||||
@export_group("Particle Types")
|
|
||||||
@export var block_rain: bool = true
|
|
||||||
@export var block_snow: bool = true
|
|
||||||
@export var block_all_precipitation: bool = true
|
|
||||||
|
|
||||||
@export_group("Debug")
|
|
||||||
@export var show_debug_gizmo: bool = true
|
|
||||||
@export var debug_color: Color = Color(0.2, 0.5, 1.0, 0.3)
|
|
||||||
|
|
||||||
var _collision_shape: CollisionShape3D
|
|
||||||
var _particles_inside: Dictionary = {}
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_setup_collision()
|
|
||||||
|
|
||||||
body_entered.connect(_on_body_entered)
|
|
||||||
body_exited.connect(_on_body_exited)
|
|
||||||
area_entered.connect(_on_area_entered)
|
|
||||||
area_exited.connect(_on_area_exited)
|
|
||||||
|
|
||||||
|
|
||||||
func _setup_collision() -> void:
|
|
||||||
_collision_shape = CollisionShape3D.new()
|
|
||||||
_collision_shape.name = "KillVolumeShape"
|
|
||||||
add_child(_collision_shape)
|
|
||||||
_update_collision_shape()
|
|
||||||
|
|
||||||
collision_layer = 0
|
|
||||||
collision_mask = 1 << 20
|
|
||||||
monitorable = true
|
|
||||||
monitoring = true
|
|
||||||
|
|
||||||
|
|
||||||
func _update_collision_shape() -> void:
|
|
||||||
if _collision_shape == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var shape: Shape3D
|
|
||||||
|
|
||||||
match volume_shape:
|
|
||||||
VolumeShape.BOX:
|
|
||||||
var box := BoxShape3D.new()
|
|
||||||
box.size = volume_size
|
|
||||||
shape = box
|
|
||||||
|
|
||||||
VolumeShape.SPHERE:
|
|
||||||
var sphere := SphereShape3D.new()
|
|
||||||
sphere.radius = volume_radius
|
|
||||||
shape = sphere
|
|
||||||
|
|
||||||
VolumeShape.CYLINDER:
|
|
||||||
var cylinder := CylinderShape3D.new()
|
|
||||||
cylinder.radius = volume_radius
|
|
||||||
cylinder.height = volume_size.y
|
|
||||||
shape = cylinder
|
|
||||||
|
|
||||||
_collision_shape.shape = shape
|
|
||||||
|
|
||||||
|
|
||||||
func _on_body_entered(body: Node3D) -> void:
|
|
||||||
if not enabled:
|
|
||||||
return
|
|
||||||
|
|
||||||
if _is_precipitation_particle(body):
|
|
||||||
_handle_particle_enter(body)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_body_exited(body: Node3D) -> void:
|
|
||||||
_handle_particle_exit(body)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_area_entered(area: Area3D) -> void:
|
|
||||||
if not enabled:
|
|
||||||
return
|
|
||||||
|
|
||||||
if area.has_meta("precipitation_particle"):
|
|
||||||
_handle_particle_enter(area)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_area_exited(area: Area3D) -> void:
|
|
||||||
_handle_particle_exit(area)
|
|
||||||
|
|
||||||
|
|
||||||
func _is_precipitation_particle(node: Node3D) -> bool:
|
|
||||||
if node.has_meta("particle_type"):
|
|
||||||
var particle_type: String = node.get_meta("particle_type")
|
|
||||||
|
|
||||||
if block_all_precipitation:
|
|
||||||
return particle_type in ["rain", "snow", "hail", "sleet"]
|
|
||||||
|
|
||||||
if block_rain and particle_type == "rain":
|
|
||||||
return true
|
|
||||||
|
|
||||||
if block_snow and particle_type == "snow":
|
|
||||||
return true
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func _handle_particle_enter(node: Node3D) -> void:
|
|
||||||
if instant_kill:
|
|
||||||
_kill_particle(node)
|
|
||||||
else:
|
|
||||||
_particles_inside[node.get_instance_id()] = {
|
|
||||||
"node": node,
|
|
||||||
"fade_time": 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func _handle_particle_exit(node: Node3D) -> void:
|
|
||||||
var id := node.get_instance_id()
|
|
||||||
if _particles_inside.has(id):
|
|
||||||
_particles_inside.erase(id)
|
|
||||||
|
|
||||||
|
|
||||||
func _kill_particle(node: Node3D) -> void:
|
|
||||||
if node.has_method("kill"):
|
|
||||||
node.call("kill")
|
|
||||||
elif node is GPUParticles3D:
|
|
||||||
node.emitting = false
|
|
||||||
elif node is CPUParticles3D:
|
|
||||||
node.emitting = false
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if instant_kill or _particles_inside.is_empty():
|
|
||||||
return
|
|
||||||
|
|
||||||
var to_remove: Array[int] = []
|
|
||||||
|
|
||||||
for id in _particles_inside:
|
|
||||||
var data: Dictionary = _particles_inside[id]
|
|
||||||
var node: Node3D = data["node"]
|
|
||||||
|
|
||||||
if not is_instance_valid(node):
|
|
||||||
to_remove.append(id)
|
|
||||||
continue
|
|
||||||
|
|
||||||
data["fade_time"] += delta
|
|
||||||
var fade_progress: float = data["fade_time"] / fade_out_duration
|
|
||||||
|
|
||||||
if fade_progress >= 1.0:
|
|
||||||
_kill_particle(node)
|
|
||||||
to_remove.append(id)
|
|
||||||
else:
|
|
||||||
_apply_fade(node, 1.0 - fade_progress)
|
|
||||||
|
|
||||||
for id in to_remove:
|
|
||||||
_particles_inside.erase(id)
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_fade(node: Node3D, alpha: float) -> void:
|
|
||||||
if node.has_method("set_alpha"):
|
|
||||||
node.call("set_alpha", alpha)
|
|
||||||
elif node is GPUParticles3D or node is CPUParticles3D:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func is_point_inside(point: Vector3) -> bool:
|
|
||||||
var local_point := to_local(point)
|
|
||||||
|
|
||||||
match volume_shape:
|
|
||||||
VolumeShape.BOX:
|
|
||||||
var half_size := volume_size * 0.5
|
|
||||||
return abs(local_point.x) <= half_size.x and \
|
|
||||||
abs(local_point.y) <= half_size.y and \
|
|
||||||
abs(local_point.z) <= half_size.z
|
|
||||||
|
|
||||||
VolumeShape.SPHERE:
|
|
||||||
return local_point.length() <= volume_radius
|
|
||||||
|
|
||||||
VolumeShape.CYLINDER:
|
|
||||||
var horizontal_dist := Vector2(local_point.x, local_point.z).length()
|
|
||||||
var half_height := volume_size.y * 0.5
|
|
||||||
return horizontal_dist <= volume_radius and abs(local_point.y) <= half_height
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func is_point_in_fade_margin(point: Vector3) -> bool:
|
|
||||||
if fade_out_margin <= 0:
|
|
||||||
return false
|
|
||||||
|
|
||||||
var local_point := to_local(point)
|
|
||||||
|
|
||||||
match volume_shape:
|
|
||||||
VolumeShape.BOX:
|
|
||||||
var half_size := volume_size * 0.5
|
|
||||||
var inner_half := half_size - Vector3(fade_out_margin, fade_out_margin, fade_out_margin)
|
|
||||||
|
|
||||||
var in_outer: bool = abs(local_point.x) <= half_size.x and \
|
|
||||||
abs(local_point.y) <= half_size.y and \
|
|
||||||
abs(local_point.z) <= half_size.z
|
|
||||||
|
|
||||||
var in_inner: bool = abs(local_point.x) <= inner_half.x and \
|
|
||||||
abs(local_point.y) <= inner_half.y and \
|
|
||||||
abs(local_point.z) <= inner_half.z
|
|
||||||
|
|
||||||
return in_outer and not in_inner
|
|
||||||
|
|
||||||
VolumeShape.SPHERE:
|
|
||||||
var dist := local_point.length()
|
|
||||||
return dist <= volume_radius and dist >= volume_radius - fade_out_margin
|
|
||||||
|
|
||||||
VolumeShape.CYLINDER:
|
|
||||||
var horizontal_dist := Vector2(local_point.x, local_point.z).length()
|
|
||||||
var half_height := volume_size.y * 0.5
|
|
||||||
|
|
||||||
var in_outer: bool = horizontal_dist <= volume_radius and abs(local_point.y) <= half_height
|
|
||||||
var in_inner: bool = horizontal_dist <= volume_radius - fade_out_margin and \
|
|
||||||
abs(local_point.y) <= half_height - fade_out_margin
|
|
||||||
|
|
||||||
return in_outer and not in_inner
|
|
||||||
|
|
||||||
return false
|
|
||||||
|
|
||||||
|
|
||||||
func get_fade_factor(point: Vector3) -> float:
|
|
||||||
if not is_point_inside(point):
|
|
||||||
return 1.0
|
|
||||||
|
|
||||||
if not is_point_in_fade_margin(point):
|
|
||||||
return 0.0
|
|
||||||
|
|
||||||
var local_point := to_local(point)
|
|
||||||
var min_distance_to_edge := fade_out_margin
|
|
||||||
|
|
||||||
match volume_shape:
|
|
||||||
VolumeShape.BOX:
|
|
||||||
var half_size := volume_size * 0.5
|
|
||||||
min_distance_to_edge = minf(min_distance_to_edge, half_size.x - abs(local_point.x))
|
|
||||||
min_distance_to_edge = minf(min_distance_to_edge, half_size.y - abs(local_point.y))
|
|
||||||
min_distance_to_edge = minf(min_distance_to_edge, half_size.z - abs(local_point.z))
|
|
||||||
|
|
||||||
VolumeShape.SPHERE:
|
|
||||||
min_distance_to_edge = volume_radius - local_point.length()
|
|
||||||
|
|
||||||
VolumeShape.CYLINDER:
|
|
||||||
var horizontal_dist := Vector2(local_point.x, local_point.z).length()
|
|
||||||
var half_height := volume_size.y * 0.5
|
|
||||||
min_distance_to_edge = minf(volume_radius - horizontal_dist, half_height - abs(local_point.y))
|
|
||||||
|
|
||||||
return clampf(min_distance_to_edge / fade_out_margin, 0.0, 1.0)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://burw0wjl85d8a
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
## Manages rain and snow particle effects driven by the weather controller.
|
|
||||||
@tool
|
|
||||||
class_name WeatherVFX
|
|
||||||
extends Node3D
|
|
||||||
|
|
||||||
@export_group("Rain")
|
|
||||||
@export var rain_amount: int = 4000
|
|
||||||
@export var rain_area: Vector3 = Vector3(80.0, 40.0, 80.0)
|
|
||||||
@export var rain_speed: float = 20.0
|
|
||||||
@export var rain_color: Color = Color(0.7, 0.75, 0.85, 0.4)
|
|
||||||
|
|
||||||
@export_group("Snow")
|
|
||||||
@export var snow_amount: int = 2000
|
|
||||||
@export var snow_area: Vector3 = Vector3(80.0, 12.0, 80.0)
|
|
||||||
@export var snow_speed: float = 4.0
|
|
||||||
@export var snow_color: Color = Color(0.95, 0.95, 1.0, 0.8)
|
|
||||||
|
|
||||||
@export_group("Lightning")
|
|
||||||
@export var lightning_color: Color = Color(0.9, 0.9, 1.0)
|
|
||||||
@export var lightning_flash_duration: float = 0.15
|
|
||||||
|
|
||||||
@export_group("Rain Audio")
|
|
||||||
@export var rain_audio_enabled: bool = true
|
|
||||||
@export var rain_volume_db_max: float = 0.0
|
|
||||||
@export var rain_crossfade_threshold: float = 0.5
|
|
||||||
|
|
||||||
@export_group("Thunder")
|
|
||||||
@export var thunder_enabled: bool = true
|
|
||||||
@export var thunder_min_delay: float = 1.0
|
|
||||||
@export var thunder_max_delay: float = 5.0
|
|
||||||
@export var thunder_volume_db: float = -2.0
|
|
||||||
|
|
||||||
var _rain_particles: GPUParticles3D
|
|
||||||
var _snow_particles: GPUParticles3D
|
|
||||||
var _rain_material: ShaderMaterial
|
|
||||||
var _snow_material: ShaderMaterial
|
|
||||||
var _target_rain: float = 0.0
|
|
||||||
var _target_snow: float = 0.0
|
|
||||||
var _current_rain: float = 0.0
|
|
||||||
var _current_snow: float = 0.0
|
|
||||||
var _lightning_active: bool = false
|
|
||||||
var _lightning_frequency: float = 0.0
|
|
||||||
var _lightning_timer: float = 0.0
|
|
||||||
var _lightning_next: float = 0.0
|
|
||||||
var _lightning_flash_timer: float = 0.0
|
|
||||||
var _lightning_light: DirectionalLight3D
|
|
||||||
var _thunder_player: AudioStreamPlayer
|
|
||||||
var _thunder_pending: bool = false
|
|
||||||
var _thunder_delay_timer: float = 0.0
|
|
||||||
var _rain_light_player: AudioStreamPlayer
|
|
||||||
var _rain_hard_player: AudioStreamPlayer
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_create_rain_system()
|
|
||||||
_create_snow_system()
|
|
||||||
_create_lightning_light()
|
|
||||||
_create_thunder_player()
|
|
||||||
_create_rain_audio_players()
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
_current_rain = move_toward(_current_rain, _target_rain, delta * 0.5)
|
|
||||||
_current_snow = move_toward(_current_snow, _target_snow, delta * 0.3)
|
|
||||||
|
|
||||||
_rain_particles.emitting = _current_rain > 0.01
|
|
||||||
_rain_particles.amount = maxi(1, int(rain_amount * _current_rain))
|
|
||||||
if _rain_material:
|
|
||||||
_rain_material.set_shader_parameter("alpha_mult", _current_rain)
|
|
||||||
|
|
||||||
_snow_particles.emitting = _current_snow > 0.01
|
|
||||||
_snow_particles.amount = maxi(1, int(snow_amount * _current_snow))
|
|
||||||
if _snow_material:
|
|
||||||
_snow_material.set_shader_parameter("alpha_mult", _current_snow)
|
|
||||||
|
|
||||||
_process_lightning(delta)
|
|
||||||
_process_thunder(delta)
|
|
||||||
_process_rain_audio()
|
|
||||||
_follow_camera()
|
|
||||||
|
|
||||||
|
|
||||||
func _process_lightning(delta: float) -> void:
|
|
||||||
if _lightning_flash_timer > 0.0:
|
|
||||||
_lightning_flash_timer -= delta
|
|
||||||
if _lightning_light:
|
|
||||||
var flash := _lightning_flash_timer / lightning_flash_duration
|
|
||||||
_lightning_light.light_energy = flash * 3.0
|
|
||||||
_lightning_light.visible = true
|
|
||||||
if _lightning_flash_timer <= 0.0 and _lightning_light:
|
|
||||||
_lightning_light.visible = false
|
|
||||||
|
|
||||||
if not _lightning_active or _lightning_frequency <= 0.0:
|
|
||||||
return
|
|
||||||
|
|
||||||
_lightning_timer += delta
|
|
||||||
if _lightning_timer >= _lightning_next:
|
|
||||||
_lightning_timer = 0.0
|
|
||||||
_lightning_next = randf_range(1.0 / maxf(_lightning_frequency, 0.01) * 0.5, 1.0 / maxf(_lightning_frequency, 0.01) * 2.0)
|
|
||||||
_trigger_lightning()
|
|
||||||
|
|
||||||
|
|
||||||
func _trigger_lightning() -> void:
|
|
||||||
_lightning_flash_timer = lightning_flash_duration
|
|
||||||
if _lightning_light:
|
|
||||||
_lightning_light.light_color = lightning_color
|
|
||||||
_lightning_light.light_energy = 3.0
|
|
||||||
_lightning_light.visible = true
|
|
||||||
_lightning_light.rotation_degrees.x = randf_range(-80.0, -50.0)
|
|
||||||
_lightning_light.rotation_degrees.y = randf_range(-180.0, 180.0)
|
|
||||||
|
|
||||||
if thunder_enabled:
|
|
||||||
_thunder_pending = true
|
|
||||||
_thunder_delay_timer = randf_range(thunder_min_delay, thunder_max_delay)
|
|
||||||
|
|
||||||
|
|
||||||
func _process_thunder(delta: float) -> void:
|
|
||||||
if not _thunder_pending:
|
|
||||||
return
|
|
||||||
|
|
||||||
_thunder_delay_timer -= delta
|
|
||||||
if _thunder_delay_timer <= 0.0:
|
|
||||||
_thunder_pending = false
|
|
||||||
_play_thunder()
|
|
||||||
|
|
||||||
|
|
||||||
func _play_thunder() -> void:
|
|
||||||
if _thunder_player == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
_thunder_player.play()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_thunder_player() -> void:
|
|
||||||
_thunder_player = AudioStreamPlayer.new()
|
|
||||||
_thunder_player.name = "ThunderPlayer"
|
|
||||||
_thunder_player.volume_db = thunder_volume_db
|
|
||||||
_thunder_player.bus = "Master"
|
|
||||||
_thunder_player.stream = load("res://resources/thunder.mp3")
|
|
||||||
add_child(_thunder_player)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_rain_audio_players() -> void:
|
|
||||||
_rain_light_player = AudioStreamPlayer.new()
|
|
||||||
_rain_light_player.name = "RainLightPlayer"
|
|
||||||
_rain_light_player.volume_db = -80.0
|
|
||||||
_rain_light_player.bus = "Master"
|
|
||||||
_rain_light_player.stream = load("res://resources/rain_light.mp3")
|
|
||||||
add_child(_rain_light_player)
|
|
||||||
|
|
||||||
_rain_hard_player = AudioStreamPlayer.new()
|
|
||||||
_rain_hard_player.name = "RainHardPlayer"
|
|
||||||
_rain_hard_player.volume_db = -80.0
|
|
||||||
_rain_hard_player.bus = "Master"
|
|
||||||
_rain_hard_player.stream = load("res://resources/rain_gentle.mp3")
|
|
||||||
add_child(_rain_hard_player)
|
|
||||||
|
|
||||||
|
|
||||||
func _process_rain_audio() -> void:
|
|
||||||
if not rain_audio_enabled:
|
|
||||||
if _rain_light_player.playing:
|
|
||||||
_rain_light_player.stop()
|
|
||||||
if _rain_hard_player.playing:
|
|
||||||
_rain_hard_player.stop()
|
|
||||||
return
|
|
||||||
|
|
||||||
if _current_rain < 0.01:
|
|
||||||
if _rain_light_player.playing:
|
|
||||||
_rain_light_player.stop()
|
|
||||||
if _rain_hard_player.playing:
|
|
||||||
_rain_hard_player.stop()
|
|
||||||
return
|
|
||||||
|
|
||||||
# Below threshold: only light rain plays, volume scales linearly 0 → max
|
|
||||||
# Above threshold: light rain fades out, hard rain fades in
|
|
||||||
if _current_rain <= rain_crossfade_threshold:
|
|
||||||
# Light rain: volume from 0 to max based on percentage within the range
|
|
||||||
var light_vol := _current_rain / rain_crossfade_threshold
|
|
||||||
_set_rain_player(_rain_light_player, light_vol)
|
|
||||||
_stop_rain_player(_rain_hard_player)
|
|
||||||
else:
|
|
||||||
# Crossfade zone: light fades out, hard fades in
|
|
||||||
var t := (_current_rain - rain_crossfade_threshold) / (1.0 - rain_crossfade_threshold)
|
|
||||||
_set_rain_player(_rain_light_player, 1.0 - t)
|
|
||||||
_set_rain_player(_rain_hard_player, t)
|
|
||||||
|
|
||||||
|
|
||||||
func _set_rain_player(player: AudioStreamPlayer, weight: float) -> void:
|
|
||||||
if weight < 0.001:
|
|
||||||
_stop_rain_player(player)
|
|
||||||
return
|
|
||||||
if not player.playing:
|
|
||||||
player.volume_db = -80.0
|
|
||||||
player.play()
|
|
||||||
player.volume_db = lerpf(-80.0, rain_volume_db_max, weight)
|
|
||||||
|
|
||||||
|
|
||||||
func _stop_rain_player(player: AudioStreamPlayer) -> void:
|
|
||||||
if player.playing:
|
|
||||||
player.stop()
|
|
||||||
|
|
||||||
|
|
||||||
func _create_lightning_light() -> void:
|
|
||||||
_lightning_light = DirectionalLight3D.new()
|
|
||||||
_lightning_light.name = "LightningFlash"
|
|
||||||
_lightning_light.light_color = lightning_color
|
|
||||||
_lightning_light.light_energy = 0.0
|
|
||||||
_lightning_light.shadow_enabled = false
|
|
||||||
_lightning_light.visible = false
|
|
||||||
add_child(_lightning_light)
|
|
||||||
|
|
||||||
|
|
||||||
func _follow_camera() -> void:
|
|
||||||
var vp := get_viewport()
|
|
||||||
if vp == null:
|
|
||||||
return
|
|
||||||
var cam := vp.get_camera_3d()
|
|
||||||
if cam:
|
|
||||||
global_position = cam.global_position
|
|
||||||
|
|
||||||
|
|
||||||
func set_rain_intensity(intensity: float) -> void:
|
|
||||||
_target_rain = clampf(intensity, 0.0, 1.0)
|
|
||||||
|
|
||||||
|
|
||||||
func set_snow_intensity(intensity: float) -> void:
|
|
||||||
_target_snow = clampf(intensity, 0.0, 1.0)
|
|
||||||
|
|
||||||
|
|
||||||
func set_lightning(active: bool, frequency: float = 0.1) -> void:
|
|
||||||
_lightning_active = active
|
|
||||||
_lightning_frequency = frequency
|
|
||||||
if not active and _lightning_light:
|
|
||||||
_lightning_light.visible = false
|
|
||||||
|
|
||||||
|
|
||||||
func _create_rain_system() -> void:
|
|
||||||
_rain_particles = GPUParticles3D.new()
|
|
||||||
_rain_particles.name = "RainParticles"
|
|
||||||
_rain_particles.amount = rain_amount
|
|
||||||
_rain_particles.lifetime = rain_area.y / rain_speed
|
|
||||||
_rain_particles.emitting = false
|
|
||||||
_rain_particles.visibility_aabb = AABB(-rain_area / 2.0, rain_area)
|
|
||||||
|
|
||||||
var mat := ParticleProcessMaterial.new()
|
|
||||||
mat.direction = Vector3(0.0, -1.0, 0.0)
|
|
||||||
mat.spread = 5.0
|
|
||||||
mat.initial_velocity_min = rain_speed * 0.8
|
|
||||||
mat.initial_velocity_max = rain_speed * 1.2
|
|
||||||
mat.gravity = Vector3(0.0, -9.8, 0.0)
|
|
||||||
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
|
|
||||||
mat.emission_box_extents = Vector3(rain_area.x / 2.0, 0.5, rain_area.z / 2.0)
|
|
||||||
_rain_particles.process_material = mat
|
|
||||||
_rain_particles.transform.origin.y = rain_area.y / 2.0
|
|
||||||
|
|
||||||
_rain_material = ShaderMaterial.new()
|
|
||||||
_rain_material.shader = _get_rain_shader()
|
|
||||||
_rain_material.set_shader_parameter("rain_color", rain_color)
|
|
||||||
_rain_material.set_shader_parameter("alpha_mult", 0.0)
|
|
||||||
|
|
||||||
var mesh := QuadMesh.new()
|
|
||||||
mesh.size = Vector2(0.02, 0.6)
|
|
||||||
mesh.material = _rain_material
|
|
||||||
_rain_particles.draw_pass_1 = mesh
|
|
||||||
|
|
||||||
add_child(_rain_particles)
|
|
||||||
|
|
||||||
|
|
||||||
func _create_snow_system() -> void:
|
|
||||||
_snow_particles = GPUParticles3D.new()
|
|
||||||
_snow_particles.name = "SnowParticles"
|
|
||||||
_snow_particles.amount = snow_amount
|
|
||||||
_snow_particles.lifetime = snow_area.y / snow_speed * 2.0
|
|
||||||
_snow_particles.emitting = false
|
|
||||||
_snow_particles.visibility_aabb = AABB(-snow_area / 2.0, snow_area)
|
|
||||||
|
|
||||||
var mat := ParticleProcessMaterial.new()
|
|
||||||
mat.direction = Vector3(0.0, -1.0, 0.0)
|
|
||||||
mat.spread = 15.0
|
|
||||||
mat.initial_velocity_min = snow_speed * 0.5
|
|
||||||
mat.initial_velocity_max = snow_speed * 1.0
|
|
||||||
mat.gravity = Vector3(0.0, -3, 0.0)
|
|
||||||
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
|
|
||||||
mat.emission_box_extents = Vector3(snow_area.x / 2.0, 1.0, snow_area.z / 2.0)
|
|
||||||
mat.turbulence_enabled = true
|
|
||||||
mat.turbulence_noise_strength = 1.5
|
|
||||||
mat.turbulence_noise_speed_random = 0.5
|
|
||||||
mat.turbulence_noise_scale = 4.0
|
|
||||||
_snow_particles.process_material = mat
|
|
||||||
_snow_particles.transform.origin.y = snow_area.y / 2.0
|
|
||||||
|
|
||||||
_snow_material = ShaderMaterial.new()
|
|
||||||
_snow_material.shader = _get_snow_shader()
|
|
||||||
_snow_material.set_shader_parameter("snow_color", snow_color)
|
|
||||||
_snow_material.set_shader_parameter("alpha_mult", 0.0)
|
|
||||||
|
|
||||||
var mesh := QuadMesh.new()
|
|
||||||
mesh.size = Vector2(0.12, 0.12)
|
|
||||||
mesh.material = _snow_material
|
|
||||||
_snow_particles.draw_pass_1 = mesh
|
|
||||||
|
|
||||||
add_child(_snow_particles)
|
|
||||||
|
|
||||||
|
|
||||||
func _get_rain_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type spatial;
|
|
||||||
render_mode unshaded, cull_disabled, depth_draw_opaque, blend_mix;
|
|
||||||
|
|
||||||
uniform vec4 rain_color : source_color = vec4(0.7, 0.75, 0.85, 0.4);
|
|
||||||
uniform float alpha_mult = 1.0;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
MODELVIEW_MATRIX = VIEW_MATRIX * mat4(
|
|
||||||
vec4(1.0, 0.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 1.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
MODEL_MATRIX[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
float fade = smoothstep(0.0, 0.3, UV.y) * smoothstep(1.0, 0.7, UV.y);
|
|
||||||
ALBEDO = rain_color.rgb;
|
|
||||||
ALPHA = rain_color.a * fade * alpha_mult;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
|
|
||||||
|
|
||||||
func _get_snow_shader() -> Shader:
|
|
||||||
var shader := Shader.new()
|
|
||||||
shader.code = """
|
|
||||||
shader_type spatial;
|
|
||||||
render_mode unshaded, cull_disabled, depth_draw_opaque, blend_mix;
|
|
||||||
|
|
||||||
uniform vec4 snow_color : source_color = vec4(0.95, 0.95, 1.0, 0.8);
|
|
||||||
uniform float alpha_mult = 1.0;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
MODELVIEW_MATRIX = VIEW_MATRIX * mat4(
|
|
||||||
vec4(1.0, 0.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 1.0, 0.0, 0.0),
|
|
||||||
vec4(0.0, 0.0, 1.0, 0.0),
|
|
||||||
MODEL_MATRIX[3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
float dist = length(UV - vec2(0.5));
|
|
||||||
float circle = smoothstep(0.5, 0.3, dist);
|
|
||||||
ALBEDO = snow_color.rgb;
|
|
||||||
ALPHA = snow_color.a * circle * alpha_mult;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
return shader
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://dgyy8274ji8vd
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 966 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 862 KiB |
@@ -3,6 +3,7 @@
|
|||||||
name="Trinittu"
|
name="Trinittu"
|
||||||
platform="Windows Desktop"
|
platform="Windows Desktop"
|
||||||
runnable=true
|
runnable=true
|
||||||
|
advanced_options=false
|
||||||
dedicated_server=false
|
dedicated_server=false
|
||||||
custom_features=""
|
custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
@@ -10,11 +11,6 @@ include_filter=""
|
|||||||
exclude_filter=""
|
exclude_filter=""
|
||||||
export_path="build/Procedural Train Tracks.exe"
|
export_path="build/Procedural Train Tracks.exe"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
|
||||||
patch_delta_compression_level_zstd=19
|
|
||||||
patch_delta_min_reduction=0.1
|
|
||||||
patch_delta_include_filters="*"
|
|
||||||
patch_delta_exclude_filters=""
|
|
||||||
encryption_include_filters=""
|
encryption_include_filters=""
|
||||||
encryption_exclude_filters=""
|
encryption_exclude_filters=""
|
||||||
seed=0
|
seed=0
|
||||||
@@ -69,53 +65,3 @@ Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorActi
|
|||||||
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
|
||||||
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
|
||||||
Remove-Item -Recurse -Force '{temp_dir}'"
|
Remove-Item -Recurse -Force '{temp_dir}'"
|
||||||
|
|
||||||
[preset.1]
|
|
||||||
|
|
||||||
name="Web"
|
|
||||||
platform="Web"
|
|
||||||
runnable=true
|
|
||||||
dedicated_server=false
|
|
||||||
custom_features=""
|
|
||||||
export_filter="all_resources"
|
|
||||||
include_filter=""
|
|
||||||
exclude_filter=""
|
|
||||||
export_path="web/index.html"
|
|
||||||
patches=PackedStringArray()
|
|
||||||
patch_delta_encoding=false
|
|
||||||
patch_delta_compression_level_zstd=19
|
|
||||||
patch_delta_min_reduction=0.1
|
|
||||||
patch_delta_include_filters="*"
|
|
||||||
patch_delta_exclude_filters=""
|
|
||||||
encryption_include_filters=""
|
|
||||||
encryption_exclude_filters=""
|
|
||||||
seed=0
|
|
||||||
encrypt_pck=false
|
|
||||||
encrypt_directory=false
|
|
||||||
script_export_mode=2
|
|
||||||
|
|
||||||
[preset.1.options]
|
|
||||||
|
|
||||||
custom_template/debug=""
|
|
||||||
custom_template/release=""
|
|
||||||
variant/extensions_support=true
|
|
||||||
variant/thread_support=false
|
|
||||||
vram_texture_compression/for_desktop=true
|
|
||||||
vram_texture_compression/for_mobile=false
|
|
||||||
html/export_icon=true
|
|
||||||
html/custom_html_shell=""
|
|
||||||
html/head_include=""
|
|
||||||
html/canvas_resize_policy=2
|
|
||||||
html/focus_canvas_on_start=true
|
|
||||||
html/experimental_virtual_keyboard=false
|
|
||||||
progressive_web_app/enabled=false
|
|
||||||
progressive_web_app/ensure_cross_origin_isolation_headers=true
|
|
||||||
progressive_web_app/offline_page=""
|
|
||||||
progressive_web_app/display=1
|
|
||||||
progressive_web_app/orientation=0
|
|
||||||
progressive_web_app/icon_144x144=""
|
|
||||||
progressive_web_app/icon_180x180=""
|
|
||||||
progressive_web_app/icon_512x512=""
|
|
||||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
|
||||||
threads/emscripten_pool_size=8
|
|
||||||
threads/godot_pool_size=4
|
|
||||||
|
|||||||
@@ -62,17 +62,7 @@ change_train={
|
|||||||
}
|
}
|
||||||
horn={
|
horn={
|
||||||
"deadzone": 0.5,
|
"deadzone": 0.5,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||||
]
|
|
||||||
}
|
|
||||||
toggle_debug={
|
|
||||||
"deadzone": 0.5,
|
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194334,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
change_camera={
|
|
||||||
"deadzone": 0.5,
|
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
resources/thomastanks_new.mp3
Normal file
BIN
resources/thomastanks_new.mp3
Normal file
Binary file not shown.
19
resources/thomastanks_new.mp3.import
Normal file
19
resources/thomastanks_new.mp3.import
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="mp3"
|
||||||
|
type="AudioStreamMP3"
|
||||||
|
uid="uid://bdluyy5uodjb5"
|
||||||
|
path="res://.godot/imported/thomastanks_new.mp3-faeee3575032f4283c1731a17141e11b.mp3str"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resources/thomastanks_new.mp3"
|
||||||
|
dest_files=["res://.godot/imported/thomastanks_new.mp3-faeee3575032f4283c1731a17141e11b.mp3str"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
||||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://cq4f7h6r8dp4n"
|
uid="uid://b0ktb1ocwlp1f"
|
||||||
path.s3tc="res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.s3tc.ctex"
|
path.s3tc="res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.s3tc.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"imported_formats": ["s3tc_bptc"],
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cdwwcby54pecs"
|
|
||||||
path.s3tc="res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.s3tc.ctex"
|
|
||||||
metadata={
|
|
||||||
"imported_formats": ["s3tc_bptc"],
|
|
||||||
"vram_texture": true
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://resources/train kit/Textures/colormap.png"
|
|
||||||
dest_files=["res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.s3tc.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=2
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/uastc_level=0
|
|
||||||
compress/rdo_quality_loss=0.0
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=true
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/channel_remap/red=0
|
|
||||||
process/channel_remap/green=1
|
|
||||||
process/channel_remap/blue=2
|
|
||||||
process/channel_remap/alpha=3
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=0
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://dq0563ak1peue"
|
|
||||||
path="res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://resources/train kit/Textures/colormap.png"
|
|
||||||
dest_files=["res://.godot/imported/colormap.png-d3d02b00fd834f010bf45b2b9259ea63.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
|
||||||
compress/uastc_level=0
|
|
||||||
compress/rdo_quality_loss=0.0
|
|
||||||
compress/hdr_compression=1
|
|
||||||
compress/normal_map=0
|
|
||||||
compress/channel_pack=0
|
|
||||||
mipmaps/generate=false
|
|
||||||
mipmaps/limit=-1
|
|
||||||
roughness/mode=0
|
|
||||||
roughness/src_normal=""
|
|
||||||
process/channel_remap/red=0
|
|
||||||
process/channel_remap/green=1
|
|
||||||
process/channel_remap/blue=2
|
|
||||||
process/channel_remap/alpha=3
|
|
||||||
process/fix_alpha_border=true
|
|
||||||
process/premult_alpha=false
|
|
||||||
process/normal_map_invert_y=false
|
|
||||||
process/hdr_as_srgb=false
|
|
||||||
process/hdr_clamp_exposure=false
|
|
||||||
process/size_limit=0
|
|
||||||
detect_3d/compress_to=1
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,454 +1,454 @@
|
|||||||
# Created by Kenney (www.kenney.nl)
|
# Created by Kenney (www.kenney.nl)
|
||||||
|
|
||||||
mtllib railroad-rail-corner-small-ramp.mtl
|
mtllib railroad-rail-corner-small-ramp.mtl
|
||||||
|
|
||||||
g railroad-rail-corner-small-ramp
|
g railroad-rail-corner-small-ramp
|
||||||
|
|
||||||
v 0.03222799 0.2288047 1.096161 1 1 1
|
v 0.03222799 0.2288047 1.096161 1 1 1
|
||||||
v -0.0534184 0.2308805 1.044582 1 1 1
|
v -0.0534184 0.2308805 1.044582 1 1 1
|
||||||
v 0.05357766 0.321202 1.064429 1 1 1
|
v 0.05357766 0.321202 1.064429 1 1 1
|
||||||
v -0.03206897 0.3232778 1.01285 1 1 1
|
v -0.03206897 0.3232778 1.01285 1 1 1
|
||||||
v 0.3500001 0.09999979 3.814697E-06 1 1 1
|
v 0.3500001 0.09999979 3.814697E-06 1 1 1
|
||||||
v 0.2684567 0.1569598 0.5677303 1 1 1
|
v 0.2684567 0.1569598 0.5677303 1 1 1
|
||||||
v 0.25 0.0999999 3.576279E-06 1 1 1
|
v 0.25 0.0999999 3.576279E-06 1 1 1
|
||||||
v 0.1731896 0.1600757 0.5374898 1 1 1
|
v 0.1731896 0.1600757 0.5374898 1 1 1
|
||||||
v 0.3499999 -2.384186E-07 4.053116E-06 1 1 1
|
v 0.3499999 -2.384186E-07 4.053116E-06 1 1 1
|
||||||
v 0.2577424 0.06042755 0.5915368 1 1 1
|
v 0.2577424 0.06042755 0.5915368 1 1 1
|
||||||
v 0.25 -2.384186E-07 3.814697E-06 1 1 1
|
v 0.25 -2.384186E-07 3.814697E-06 1 1 1
|
||||||
v 0.1624753 0.06354344 0.5612962 1 1 1
|
v 0.1624753 0.06354344 0.5612962 1 1 1
|
||||||
v -0.4816511 0.2412597 0.7866886 1 1 1
|
v -0.4816511 0.2412597 0.7866886 1 1 1
|
||||||
v -0.5672977 0.2433355 0.7351098 1 1 1
|
v -0.5672977 0.2433355 0.7351098 1 1 1
|
||||||
v -0.4603016 0.333657 0.7549562 1 1 1
|
v -0.4603016 0.333657 0.7549562 1 1 1
|
||||||
v -0.545948 0.3357328 0.7033776 1 1 1
|
v -0.545948 0.3357328 0.7033776 1 1 1
|
||||||
v -0.25 0.1000001 2.503395E-06 1 1 1
|
v -0.25 0.1000001 2.503395E-06 1 1 1
|
||||||
v -0.3031454 0.1756552 0.3862872 1 1 1
|
v -0.3031454 0.1756552 0.3862872 1 1 1
|
||||||
v -0.3499999 0.1000003 2.264977E-06 1 1 1
|
v -0.3499999 0.1000003 2.264977E-06 1 1 1
|
||||||
v -0.3984125 0.1787713 0.3560467 1 1 1
|
v -0.3984125 0.1787713 0.3560467 1 1 1
|
||||||
v -0.25 1.192093E-07 2.741814E-06 1 1 1
|
v -0.25 1.192093E-07 2.741814E-06 1 1 1
|
||||||
v -0.3138597 0.07912314 0.4100935 1 1 1
|
v -0.3138597 0.07912314 0.4100935 1 1 1
|
||||||
v -0.3499999 2.384186E-07 2.503395E-06 1 1 1
|
v -0.3499999 2.384186E-07 2.503395E-06 1 1 1
|
||||||
v -0.4091265 0.08223903 0.379853 1 1 1
|
v -0.4091265 0.08223903 0.379853 1 1 1
|
||||||
v -0.6580944 0.6559293 1.867082 1 1 1
|
v -0.6580944 0.6559293 1.867082 1 1 1
|
||||||
v -0.7188323 0.6547513 1.787649 1 1 1
|
v -0.7188323 0.6547513 1.787649 1 1 1
|
||||||
v -0.6259274 0.74699 1.841135 1 1 1
|
v -0.6259274 0.74699 1.841135 1 1 1
|
||||||
v -0.6866653 0.7458121 1.761703 1 1 1
|
v -0.6866653 0.7458121 1.761703 1 1 1
|
||||||
v -0.2489958 0.5291302 1.486047 1 1 1
|
v -0.2489958 0.5291302 1.486047 1 1 1
|
||||||
v -0.3232303 0.5295908 1.419047 1 1 1
|
v -0.3232303 0.5295908 1.419047 1 1 1
|
||||||
v -0.2777421 0.4385846 1.517275 1 1 1
|
v -0.2777421 0.4385846 1.517275 1 1 1
|
||||||
v -0.3519766 0.4390453 1.450274 1 1 1
|
v -0.3519766 0.4390453 1.450274 1 1 1
|
||||||
v -1.022522 0.6488616 1.390487 1 1 1
|
v -1.022522 0.6488616 1.390487 1 1 1
|
||||||
v -1.08326 0.6476837 1.311055 1 1 1
|
v -1.08326 0.6476837 1.311055 1 1 1
|
||||||
v -0.9903553 0.7399224 1.36454 1 1 1
|
v -0.9903553 0.7399224 1.36454 1 1 1
|
||||||
v -1.051093 0.7387445 1.285108 1 1 1
|
v -1.051093 0.7387445 1.285108 1 1 1
|
||||||
v -0.6944022 0.5318943 1.084045 1 1 1
|
v -0.6944022 0.5318943 1.084045 1 1 1
|
||||||
v -0.7686365 0.5323551 1.017045 1 1 1
|
v -0.7686365 0.5323551 1.017045 1 1 1
|
||||||
v -0.7231483 0.4413488 1.115273 1 1 1
|
v -0.7231483 0.4413488 1.115273 1 1 1
|
||||||
v -0.7973828 0.4418094 1.048272 1 1 1
|
v -0.7973828 0.4418094 1.048272 1 1 1
|
||||||
v -1.658962 0.9852197 2.319037 1 1 1
|
v -1.658962 0.9852197 2.319037 1 1 1
|
||||||
v -1.676997 0.9825025 2.220714 1 1 1
|
v -1.676997 0.9825025 2.220714 1 1 1
|
||||||
v -1.643204 1.08381 2.313422 1 1 1
|
v -1.643204 1.08381 2.313422 1 1 1
|
||||||
v -1.661238 1.081093 2.215099 1 1 1
|
v -1.661238 1.081093 2.215099 1 1 1
|
||||||
v -1.084131 0.9468933 2.126323 1 1 1
|
v -1.084131 0.9468933 2.126323 1 1 1
|
||||||
v -1.127321 0.9441962 2.036171 1 1 1
|
v -1.127321 0.9441962 2.036171 1 1 1
|
||||||
v -1.113795 0.8529241 2.143346 1 1 1
|
v -1.113795 0.8529241 2.143346 1 1 1
|
||||||
v -1.156985 0.8502269 2.053194 1 1 1
|
v -1.156985 0.8502269 2.053194 1 1 1
|
||||||
v -1.76717 0.9689159 1.7291 1 1 1
|
v -1.76717 0.9689159 1.7291 1 1 1
|
||||||
v -1.785205 0.9661987 1.630777 1 1 1
|
v -1.785205 0.9661987 1.630777 1 1 1
|
||||||
v -1.751411 1.067507 1.723485 1 1 1
|
v -1.751411 1.067507 1.723485 1 1 1
|
||||||
v -1.769446 1.06479 1.625162 1 1 1
|
v -1.769446 1.06479 1.625162 1 1 1
|
||||||
v -1.343271 0.9307103 1.585412 1 1 1
|
v -1.343271 0.9307103 1.585412 1 1 1
|
||||||
v -1.38646 0.9280132 1.49526 1 1 1
|
v -1.38646 0.9280132 1.49526 1 1 1
|
||||||
v -1.372935 0.8367411 1.602435 1 1 1
|
v -1.372935 0.8367411 1.602435 1 1 1
|
||||||
v -1.416125 0.834044 1.512283 1 1 1
|
v -1.416125 0.834044 1.512283 1 1 1
|
||||||
v -1.999996 1 2.35 1 1 1
|
v -1.999996 1 2.35 1 1 1
|
||||||
v -1.999996 1 2.25 1 1 1
|
v -1.999996 1 2.25 1 1 1
|
||||||
v -1.999995 1.1 2.35 1 1 1
|
v -1.999995 1.1 2.35 1 1 1
|
||||||
v -1.999996 1.1 2.25 1 1 1
|
v -1.999996 1.1 2.25 1 1 1
|
||||||
v -1.999997 0.9999998 1.75 1 1 1
|
v -1.999997 0.9999998 1.75 1 1 1
|
||||||
v -1.999998 0.9999998 1.65 1 1 1
|
v -1.999998 0.9999998 1.65 1 1 1
|
||||||
v -1.999997 1.1 1.75 1 1 1
|
v -1.999997 1.1 1.75 1 1 1
|
||||||
v -1.999997 1.1 1.65 1 1 1
|
v -1.999997 1.1 1.65 1 1 1
|
||||||
|
|
||||||
vn -0.4699863 0.3818935 0.7957828
|
vn -0.4699863 0.3818935 0.7957828
|
||||||
vn 0.7071072 0.7071064 2.646573E-12
|
vn 0.7071072 0.7071064 2.646573E-12
|
||||||
vn 0.7494 0.6605526 0.04549586
|
vn 0.7494 0.6605526 0.04549586
|
||||||
vn -0.7071064 0.7071072 -3.09088E-06
|
vn -0.7071064 0.7071072 -3.09088E-06
|
||||||
vn -0.5978788 0.7046185 -0.3821698
|
vn -0.5978788 0.7046185 -0.3821698
|
||||||
vn 0.7565761 0.6386693 0.1403356
|
vn 0.7565761 0.6386693 0.1403356
|
||||||
vn -0.4546488 0.668026 -0.5890973
|
vn -0.4546488 0.668026 -0.5890973
|
||||||
vn 1 -6.090609E-07 2.185584E-06
|
vn 1 -6.090609E-07 2.185584E-06
|
||||||
vn 0.95267 -0.03115931 0.3024052
|
vn 0.95267 -0.03115931 0.3024052
|
||||||
vn 0.8564653 -0.02075831 0.515787
|
vn 0.8564653 -0.02075831 0.515787
|
||||||
vn -1 6.090609E-07 -2.185584E-06
|
vn -1 6.090609E-07 -2.185584E-06
|
||||||
vn -0.95267 0.03115931 -0.3024052
|
vn -0.95267 0.03115931 -0.3024052
|
||||||
vn -0.8564653 0.02075831 -0.515787
|
vn -0.8564653 0.02075831 -0.515787
|
||||||
vn 2.185583E-06 -2.185582E-06 -1
|
vn 2.185583E-06 -2.185582E-06 -1
|
||||||
vn -0.2134948 -0.9239732 0.3173224
|
vn -0.2134948 -0.9239732 0.3173224
|
||||||
vn -0.1071417 -0.9653217 0.2380644
|
vn -0.1071417 -0.9653217 0.2380644
|
||||||
vn -6.090656E-07 -1 2.185581E-06
|
vn -6.090656E-07 -1 2.185581E-06
|
||||||
vn -0.7263736 0.4131054 0.5492954
|
vn -0.7263736 0.4131054 0.5492954
|
||||||
vn 0.7281833 0.6369962 0.2529526
|
vn 0.7281833 0.6369962 0.2529526
|
||||||
vn -0.3216493 0.6435114 -0.6945753
|
vn -0.3216493 0.6435114 -0.6945753
|
||||||
vn 0.6569369 0.6522257 0.3782004
|
vn 0.6569369 0.6522257 0.3782004
|
||||||
vn -0.2020279 0.6355672 -0.7451437
|
vn -0.2020279 0.6355672 -0.7451437
|
||||||
vn 0.7423437 -0.004606932 0.6700034
|
vn 0.7423437 -0.004606932 0.6700034
|
||||||
vn 0.6073799 0.01177932 0.7943242
|
vn 0.6073799 0.01177932 0.7943242
|
||||||
vn -0.7423437 0.004606932 -0.6700034
|
vn -0.7423437 0.004606932 -0.6700034
|
||||||
vn -0.6073799 -0.01177932 -0.7943242
|
vn -0.6073799 -0.01177932 -0.7943242
|
||||||
vn 0.4699863 -0.3818935 -0.7957828
|
vn 0.4699863 -0.3818935 -0.7957828
|
||||||
vn -0.3216693 -0.910607 0.2594681
|
vn -0.3216693 -0.910607 0.2594681
|
||||||
vn -0.2874629 -0.9054555 0.3122744
|
vn -0.2874629 -0.9054555 0.3122744
|
||||||
vn -0.9708977 0.1650688 0.1735223
|
vn -0.9708977 0.1650688 0.1735223
|
||||||
vn 0.5151594 0.683535 0.5170982
|
vn 0.5151594 0.683535 0.5170982
|
||||||
vn -0.09563893 0.6453913 -0.7578411
|
vn -0.09563893 0.6453913 -0.7578411
|
||||||
vn 0.2389533 0.716356 0.655542
|
vn 0.2389533 0.716356 0.655542
|
||||||
vn -0.01609421 0.677928 -0.7349522
|
vn -0.01609421 0.677928 -0.7349522
|
||||||
vn 0.4318997 0.02697165 0.9015182
|
vn 0.4318997 0.02697165 0.9015182
|
||||||
vn 0.1803458 0.02717271 0.9832278
|
vn 0.1803458 0.02717271 0.9832278
|
||||||
vn -0.4318997 -0.02697165 -0.9015182
|
vn -0.4318997 -0.02697165 -0.9015182
|
||||||
vn -0.1803458 -0.02717271 -0.9832278
|
vn -0.1803458 -0.02717271 -0.9832278
|
||||||
vn 0.7263736 -0.4131054 -0.5492954
|
vn 0.7263736 -0.4131054 -0.5492954
|
||||||
vn -0.1575852 -0.9859077 0.05615139
|
vn -0.1575852 -0.9859077 0.05615139
|
||||||
vn -0.2966458 -0.9396929 0.1702309
|
vn -0.2966458 -0.9396929 0.1702309
|
||||||
vn -1 2.304713E-06 2.741814E-06
|
vn -1 2.304713E-06 2.741814E-06
|
||||||
vn 3.516674E-06 0.7071073 0.7071063
|
vn 3.516674E-06 0.7071073 0.7071063
|
||||||
vn -3.576279E-07 0.7071062 -0.7071073
|
vn -3.576279E-07 0.7071062 -0.7071073
|
||||||
vn 2.741814E-06 7.205546E-07 1
|
vn 2.741814E-06 7.205546E-07 1
|
||||||
vn -2.741814E-06 -7.205546E-07 -1
|
vn -2.741814E-06 -7.205546E-07 -1
|
||||||
vn 0.9708977 -0.1650688 -0.1735223
|
vn 0.9708977 -0.1650688 -0.1735223
|
||||||
vn -2.304711E-06 -1 7.20561E-07
|
vn -2.304711E-06 -1 7.20561E-07
|
||||||
|
|
||||||
vt 0.96875 0.025
|
vt 0.96875 0.025
|
||||||
vt 0.96875 0.225
|
vt 0.96875 0.225
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/16 1/1/15
|
f 2/1/15 10/1/16 1/1/15
|
||||||
f 10/1/16 2/1/15 12/1/16
|
f 10/1/16 2/1/15 12/1/16
|
||||||
f 12/1/16 9/1/17 10/1/16
|
f 12/1/16 9/1/17 10/1/16
|
||||||
f 9/1/17 12/1/16 11/1/17
|
f 9/1/17 12/1/16 11/1/17
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/16 13/1/15
|
f 14/1/15 22/1/16 13/1/15
|
||||||
f 22/1/16 14/1/15 24/1/16
|
f 22/1/16 14/1/15 24/1/16
|
||||||
f 24/1/16 21/1/17 22/1/16
|
f 24/1/16 21/1/17 22/1/16
|
||||||
f 21/1/17 24/1/16 23/1/17
|
f 21/1/17 24/1/16 23/1/17
|
||||||
f 27/2/18 26/1/18 25/1/18
|
f 27/2/18 26/1/18 25/1/18
|
||||||
f 26/1/18 27/2/18 28/2/18
|
f 26/1/18 27/2/18 28/2/18
|
||||||
f 4/2/7 29/2/19 3/2/6
|
f 4/2/7 29/2/19 3/2/6
|
||||||
f 29/2/19 4/2/7 30/2/20
|
f 29/2/19 4/2/7 30/2/20
|
||||||
f 30/2/20 27/2/21 29/2/19
|
f 30/2/20 27/2/21 29/2/19
|
||||||
f 27/2/21 30/2/20 28/2/22
|
f 27/2/21 30/2/20 28/2/22
|
||||||
f 29/2/19 1/1/10 3/2/6
|
f 29/2/19 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/19 31/1/23
|
f 1/1/10 29/2/19 31/1/23
|
||||||
f 27/2/21 31/1/23 29/2/19
|
f 27/2/21 31/1/23 29/2/19
|
||||||
f 31/1/23 27/2/21 25/1/24
|
f 31/1/23 27/2/21 25/1/24
|
||||||
f 32/1/25 4/2/7 2/1/13
|
f 32/1/25 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/25 30/2/20
|
f 4/2/7 32/1/25 30/2/20
|
||||||
f 26/1/26 30/2/20 32/1/25
|
f 26/1/26 30/2/20 32/1/25
|
||||||
f 30/2/20 26/1/26 28/2/22
|
f 30/2/20 26/1/26 28/2/22
|
||||||
f 4/2/27 1/1/27 2/1/27
|
f 4/2/27 1/1/27 2/1/27
|
||||||
f 1/1/27 4/2/27 3/2/27
|
f 1/1/27 4/2/27 3/2/27
|
||||||
f 26/1/28 31/1/29 25/1/28
|
f 26/1/28 31/1/29 25/1/28
|
||||||
f 31/1/29 26/1/28 32/1/29
|
f 31/1/29 26/1/28 32/1/29
|
||||||
f 32/1/29 1/1/15 31/1/29
|
f 32/1/29 1/1/15 31/1/29
|
||||||
f 1/1/15 32/1/29 2/1/15
|
f 1/1/15 32/1/29 2/1/15
|
||||||
f 35/2/18 34/1/18 33/1/18
|
f 35/2/18 34/1/18 33/1/18
|
||||||
f 34/1/18 35/2/18 36/2/18
|
f 34/1/18 35/2/18 36/2/18
|
||||||
f 16/2/7 37/2/19 15/2/6
|
f 16/2/7 37/2/19 15/2/6
|
||||||
f 37/2/19 16/2/7 38/2/20
|
f 37/2/19 16/2/7 38/2/20
|
||||||
f 38/2/20 35/2/21 37/2/19
|
f 38/2/20 35/2/21 37/2/19
|
||||||
f 35/2/21 38/2/20 36/2/22
|
f 35/2/21 38/2/20 36/2/22
|
||||||
f 37/2/19 13/1/10 15/2/6
|
f 37/2/19 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/19 39/1/23
|
f 13/1/10 37/2/19 39/1/23
|
||||||
f 35/2/21 39/1/23 37/2/19
|
f 35/2/21 39/1/23 37/2/19
|
||||||
f 39/1/23 35/2/21 33/1/24
|
f 39/1/23 35/2/21 33/1/24
|
||||||
f 40/1/25 16/2/7 14/1/13
|
f 40/1/25 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/25 38/2/20
|
f 16/2/7 40/1/25 38/2/20
|
||||||
f 34/1/26 38/2/20 40/1/25
|
f 34/1/26 38/2/20 40/1/25
|
||||||
f 38/2/20 34/1/26 36/2/22
|
f 38/2/20 34/1/26 36/2/22
|
||||||
f 16/2/27 13/1/27 14/1/27
|
f 16/2/27 13/1/27 14/1/27
|
||||||
f 13/1/27 16/2/27 15/2/27
|
f 13/1/27 16/2/27 15/2/27
|
||||||
f 34/1/28 39/1/29 33/1/28
|
f 34/1/28 39/1/29 33/1/28
|
||||||
f 39/1/29 34/1/28 40/1/29
|
f 39/1/29 34/1/28 40/1/29
|
||||||
f 40/1/29 13/1/15 39/1/29
|
f 40/1/29 13/1/15 39/1/29
|
||||||
f 13/1/15 40/1/29 14/1/15
|
f 13/1/15 40/1/29 14/1/15
|
||||||
f 43/2/30 42/1/30 41/1/30
|
f 43/2/30 42/1/30 41/1/30
|
||||||
f 42/1/30 43/2/30 44/2/30
|
f 42/1/30 43/2/30 44/2/30
|
||||||
f 28/2/22 45/2/31 27/2/21
|
f 28/2/22 45/2/31 27/2/21
|
||||||
f 45/2/31 28/2/22 46/2/32
|
f 45/2/31 28/2/22 46/2/32
|
||||||
f 46/2/32 43/2/33 45/2/31
|
f 46/2/32 43/2/33 45/2/31
|
||||||
f 43/2/33 46/2/32 44/2/34
|
f 43/2/33 46/2/32 44/2/34
|
||||||
f 45/2/31 25/1/24 27/2/21
|
f 45/2/31 25/1/24 27/2/21
|
||||||
f 25/1/24 45/2/31 47/1/35
|
f 25/1/24 45/2/31 47/1/35
|
||||||
f 43/2/33 47/1/35 45/2/31
|
f 43/2/33 47/1/35 45/2/31
|
||||||
f 47/1/35 43/2/33 41/1/36
|
f 47/1/35 43/2/33 41/1/36
|
||||||
f 48/1/37 28/2/22 26/1/26
|
f 48/1/37 28/2/22 26/1/26
|
||||||
f 28/2/22 48/1/37 46/2/32
|
f 28/2/22 48/1/37 46/2/32
|
||||||
f 42/1/38 46/2/32 48/1/37
|
f 42/1/38 46/2/32 48/1/37
|
||||||
f 46/2/32 42/1/38 44/2/34
|
f 46/2/32 42/1/38 44/2/34
|
||||||
f 28/2/39 25/1/39 26/1/39
|
f 28/2/39 25/1/39 26/1/39
|
||||||
f 25/1/39 28/2/39 27/2/39
|
f 25/1/39 28/2/39 27/2/39
|
||||||
f 42/1/40 47/1/41 41/1/40
|
f 42/1/40 47/1/41 41/1/40
|
||||||
f 47/1/41 42/1/40 48/1/41
|
f 47/1/41 42/1/40 48/1/41
|
||||||
f 48/1/41 25/1/28 47/1/41
|
f 48/1/41 25/1/28 47/1/41
|
||||||
f 25/1/28 48/1/41 26/1/28
|
f 25/1/28 48/1/41 26/1/28
|
||||||
f 51/2/30 50/1/30 49/1/30
|
f 51/2/30 50/1/30 49/1/30
|
||||||
f 50/1/30 51/2/30 52/2/30
|
f 50/1/30 51/2/30 52/2/30
|
||||||
f 36/2/22 53/2/31 35/2/21
|
f 36/2/22 53/2/31 35/2/21
|
||||||
f 53/2/31 36/2/22 54/2/32
|
f 53/2/31 36/2/22 54/2/32
|
||||||
f 54/2/32 51/2/33 53/2/31
|
f 54/2/32 51/2/33 53/2/31
|
||||||
f 51/2/33 54/2/32 52/2/34
|
f 51/2/33 54/2/32 52/2/34
|
||||||
f 53/2/31 33/1/24 35/2/21
|
f 53/2/31 33/1/24 35/2/21
|
||||||
f 33/1/24 53/2/31 55/1/35
|
f 33/1/24 53/2/31 55/1/35
|
||||||
f 51/2/33 55/1/35 53/2/31
|
f 51/2/33 55/1/35 53/2/31
|
||||||
f 55/1/35 51/2/33 49/1/36
|
f 55/1/35 51/2/33 49/1/36
|
||||||
f 56/1/37 36/2/22 34/1/26
|
f 56/1/37 36/2/22 34/1/26
|
||||||
f 36/2/22 56/1/37 54/2/32
|
f 36/2/22 56/1/37 54/2/32
|
||||||
f 50/1/38 54/2/32 56/1/37
|
f 50/1/38 54/2/32 56/1/37
|
||||||
f 54/2/32 50/1/38 52/2/34
|
f 54/2/32 50/1/38 52/2/34
|
||||||
f 36/2/39 33/1/39 34/1/39
|
f 36/2/39 33/1/39 34/1/39
|
||||||
f 33/1/39 36/2/39 35/2/39
|
f 33/1/39 36/2/39 35/2/39
|
||||||
f 50/1/40 55/1/41 49/1/40
|
f 50/1/40 55/1/41 49/1/40
|
||||||
f 55/1/41 50/1/40 56/1/41
|
f 55/1/41 50/1/40 56/1/41
|
||||||
f 56/1/41 33/1/28 55/1/41
|
f 56/1/41 33/1/28 55/1/41
|
||||||
f 33/1/28 56/1/41 34/1/28
|
f 33/1/28 56/1/41 34/1/28
|
||||||
f 59/2/42 58/1/42 57/1/42
|
f 59/2/42 58/1/42 57/1/42
|
||||||
f 58/1/42 59/2/42 60/2/42
|
f 58/1/42 59/2/42 60/2/42
|
||||||
f 44/2/34 59/2/43 43/2/33
|
f 44/2/34 59/2/43 43/2/33
|
||||||
f 59/2/43 44/2/34 60/2/44
|
f 59/2/43 44/2/34 60/2/44
|
||||||
f 60/2/44 59/2/43 59/2/43
|
f 60/2/44 59/2/43 59/2/43
|
||||||
f 59/2/43 60/2/44 60/2/44
|
f 59/2/43 60/2/44 60/2/44
|
||||||
f 59/2/43 41/1/36 43/2/33
|
f 59/2/43 41/1/36 43/2/33
|
||||||
f 41/1/36 59/2/43 57/1/45
|
f 41/1/36 59/2/43 57/1/45
|
||||||
f 59/2/43 57/1/45 59/2/43
|
f 59/2/43 57/1/45 59/2/43
|
||||||
f 57/1/45 59/2/43 57/1/45
|
f 57/1/45 59/2/43 57/1/45
|
||||||
f 58/1/46 44/2/34 42/1/38
|
f 58/1/46 44/2/34 42/1/38
|
||||||
f 44/2/34 58/1/46 60/2/44
|
f 44/2/34 58/1/46 60/2/44
|
||||||
f 58/1/46 60/2/44 58/1/46
|
f 58/1/46 60/2/44 58/1/46
|
||||||
f 60/2/44 58/1/46 60/2/44
|
f 60/2/44 58/1/46 60/2/44
|
||||||
f 44/2/47 41/1/47 42/1/47
|
f 44/2/47 41/1/47 42/1/47
|
||||||
f 41/1/47 44/2/47 43/2/47
|
f 41/1/47 44/2/47 43/2/47
|
||||||
f 58/1/48 57/1/48 57/1/48
|
f 58/1/48 57/1/48 57/1/48
|
||||||
f 57/1/48 58/1/48 58/1/48
|
f 57/1/48 58/1/48 58/1/48
|
||||||
f 58/1/48 41/1/40 57/1/48
|
f 58/1/48 41/1/40 57/1/48
|
||||||
f 41/1/40 58/1/48 42/1/40
|
f 41/1/40 58/1/48 42/1/40
|
||||||
f 63/2/42 62/1/42 61/1/42
|
f 63/2/42 62/1/42 61/1/42
|
||||||
f 62/1/42 63/2/42 64/2/42
|
f 62/1/42 63/2/42 64/2/42
|
||||||
f 52/2/34 63/2/43 51/2/33
|
f 52/2/34 63/2/43 51/2/33
|
||||||
f 63/2/43 52/2/34 64/2/44
|
f 63/2/43 52/2/34 64/2/44
|
||||||
f 64/2/44 63/2/43 63/2/43
|
f 64/2/44 63/2/43 63/2/43
|
||||||
f 63/2/43 64/2/44 64/2/44
|
f 63/2/43 64/2/44 64/2/44
|
||||||
f 63/2/43 49/1/36 51/2/33
|
f 63/2/43 49/1/36 51/2/33
|
||||||
f 49/1/36 63/2/43 61/1/45
|
f 49/1/36 63/2/43 61/1/45
|
||||||
f 63/2/43 61/1/45 63/2/43
|
f 63/2/43 61/1/45 63/2/43
|
||||||
f 61/1/45 63/2/43 61/1/45
|
f 61/1/45 63/2/43 61/1/45
|
||||||
f 62/1/46 52/2/34 50/1/38
|
f 62/1/46 52/2/34 50/1/38
|
||||||
f 52/2/34 62/1/46 64/2/44
|
f 52/2/34 62/1/46 64/2/44
|
||||||
f 62/1/46 64/2/44 62/1/46
|
f 62/1/46 64/2/44 62/1/46
|
||||||
f 64/2/44 62/1/46 64/2/44
|
f 64/2/44 62/1/46 64/2/44
|
||||||
f 52/2/47 49/1/47 50/1/47
|
f 52/2/47 49/1/47 50/1/47
|
||||||
f 49/1/47 52/2/47 51/2/47
|
f 49/1/47 52/2/47 51/2/47
|
||||||
f 62/1/48 61/1/48 61/1/48
|
f 62/1/48 61/1/48 61/1/48
|
||||||
f 61/1/48 62/1/48 62/1/48
|
f 61/1/48 62/1/48 62/1/48
|
||||||
f 62/1/48 49/1/40 61/1/48
|
f 62/1/48 49/1/40 61/1/48
|
||||||
f 49/1/40 62/1/48 50/1/40
|
f 49/1/40 62/1/48 50/1/40
|
||||||
|
|
||||||
g railroad-rail-corner-small-ramp
|
g railroad-rail-corner-small-ramp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/16 1/1/15
|
f 2/1/15 10/1/16 1/1/15
|
||||||
f 10/1/16 2/1/15 12/1/16
|
f 10/1/16 2/1/15 12/1/16
|
||||||
f 12/1/16 9/1/17 10/1/16
|
f 12/1/16 9/1/17 10/1/16
|
||||||
f 9/1/17 12/1/16 11/1/17
|
f 9/1/17 12/1/16 11/1/17
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/16 13/1/15
|
f 14/1/15 22/1/16 13/1/15
|
||||||
f 22/1/16 14/1/15 24/1/16
|
f 22/1/16 14/1/15 24/1/16
|
||||||
f 24/1/16 21/1/17 22/1/16
|
f 24/1/16 21/1/17 22/1/16
|
||||||
f 21/1/17 24/1/16 23/1/17
|
f 21/1/17 24/1/16 23/1/17
|
||||||
f 27/2/18 26/1/18 25/1/18
|
f 27/2/18 26/1/18 25/1/18
|
||||||
f 26/1/18 27/2/18 28/2/18
|
f 26/1/18 27/2/18 28/2/18
|
||||||
f 4/2/7 29/2/19 3/2/6
|
f 4/2/7 29/2/19 3/2/6
|
||||||
f 29/2/19 4/2/7 30/2/20
|
f 29/2/19 4/2/7 30/2/20
|
||||||
f 30/2/20 27/2/21 29/2/19
|
f 30/2/20 27/2/21 29/2/19
|
||||||
f 27/2/21 30/2/20 28/2/22
|
f 27/2/21 30/2/20 28/2/22
|
||||||
f 29/2/19 1/1/10 3/2/6
|
f 29/2/19 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/19 31/1/23
|
f 1/1/10 29/2/19 31/1/23
|
||||||
f 27/2/21 31/1/23 29/2/19
|
f 27/2/21 31/1/23 29/2/19
|
||||||
f 31/1/23 27/2/21 25/1/24
|
f 31/1/23 27/2/21 25/1/24
|
||||||
f 32/1/25 4/2/7 2/1/13
|
f 32/1/25 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/25 30/2/20
|
f 4/2/7 32/1/25 30/2/20
|
||||||
f 26/1/26 30/2/20 32/1/25
|
f 26/1/26 30/2/20 32/1/25
|
||||||
f 30/2/20 26/1/26 28/2/22
|
f 30/2/20 26/1/26 28/2/22
|
||||||
f 4/2/27 1/1/27 2/1/27
|
f 4/2/27 1/1/27 2/1/27
|
||||||
f 1/1/27 4/2/27 3/2/27
|
f 1/1/27 4/2/27 3/2/27
|
||||||
f 26/1/28 31/1/29 25/1/28
|
f 26/1/28 31/1/29 25/1/28
|
||||||
f 31/1/29 26/1/28 32/1/29
|
f 31/1/29 26/1/28 32/1/29
|
||||||
f 32/1/29 1/1/15 31/1/29
|
f 32/1/29 1/1/15 31/1/29
|
||||||
f 1/1/15 32/1/29 2/1/15
|
f 1/1/15 32/1/29 2/1/15
|
||||||
f 35/2/18 34/1/18 33/1/18
|
f 35/2/18 34/1/18 33/1/18
|
||||||
f 34/1/18 35/2/18 36/2/18
|
f 34/1/18 35/2/18 36/2/18
|
||||||
f 16/2/7 37/2/19 15/2/6
|
f 16/2/7 37/2/19 15/2/6
|
||||||
f 37/2/19 16/2/7 38/2/20
|
f 37/2/19 16/2/7 38/2/20
|
||||||
f 38/2/20 35/2/21 37/2/19
|
f 38/2/20 35/2/21 37/2/19
|
||||||
f 35/2/21 38/2/20 36/2/22
|
f 35/2/21 38/2/20 36/2/22
|
||||||
f 37/2/19 13/1/10 15/2/6
|
f 37/2/19 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/19 39/1/23
|
f 13/1/10 37/2/19 39/1/23
|
||||||
f 35/2/21 39/1/23 37/2/19
|
f 35/2/21 39/1/23 37/2/19
|
||||||
f 39/1/23 35/2/21 33/1/24
|
f 39/1/23 35/2/21 33/1/24
|
||||||
f 40/1/25 16/2/7 14/1/13
|
f 40/1/25 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/25 38/2/20
|
f 16/2/7 40/1/25 38/2/20
|
||||||
f 34/1/26 38/2/20 40/1/25
|
f 34/1/26 38/2/20 40/1/25
|
||||||
f 38/2/20 34/1/26 36/2/22
|
f 38/2/20 34/1/26 36/2/22
|
||||||
f 16/2/27 13/1/27 14/1/27
|
f 16/2/27 13/1/27 14/1/27
|
||||||
f 13/1/27 16/2/27 15/2/27
|
f 13/1/27 16/2/27 15/2/27
|
||||||
f 34/1/28 39/1/29 33/1/28
|
f 34/1/28 39/1/29 33/1/28
|
||||||
f 39/1/29 34/1/28 40/1/29
|
f 39/1/29 34/1/28 40/1/29
|
||||||
f 40/1/29 13/1/15 39/1/29
|
f 40/1/29 13/1/15 39/1/29
|
||||||
f 13/1/15 40/1/29 14/1/15
|
f 13/1/15 40/1/29 14/1/15
|
||||||
f 43/2/30 42/1/30 41/1/30
|
f 43/2/30 42/1/30 41/1/30
|
||||||
f 42/1/30 43/2/30 44/2/30
|
f 42/1/30 43/2/30 44/2/30
|
||||||
f 28/2/22 45/2/31 27/2/21
|
f 28/2/22 45/2/31 27/2/21
|
||||||
f 45/2/31 28/2/22 46/2/32
|
f 45/2/31 28/2/22 46/2/32
|
||||||
f 46/2/32 43/2/33 45/2/31
|
f 46/2/32 43/2/33 45/2/31
|
||||||
f 43/2/33 46/2/32 44/2/34
|
f 43/2/33 46/2/32 44/2/34
|
||||||
f 45/2/31 25/1/24 27/2/21
|
f 45/2/31 25/1/24 27/2/21
|
||||||
f 25/1/24 45/2/31 47/1/35
|
f 25/1/24 45/2/31 47/1/35
|
||||||
f 43/2/33 47/1/35 45/2/31
|
f 43/2/33 47/1/35 45/2/31
|
||||||
f 47/1/35 43/2/33 41/1/36
|
f 47/1/35 43/2/33 41/1/36
|
||||||
f 48/1/37 28/2/22 26/1/26
|
f 48/1/37 28/2/22 26/1/26
|
||||||
f 28/2/22 48/1/37 46/2/32
|
f 28/2/22 48/1/37 46/2/32
|
||||||
f 42/1/38 46/2/32 48/1/37
|
f 42/1/38 46/2/32 48/1/37
|
||||||
f 46/2/32 42/1/38 44/2/34
|
f 46/2/32 42/1/38 44/2/34
|
||||||
f 28/2/39 25/1/39 26/1/39
|
f 28/2/39 25/1/39 26/1/39
|
||||||
f 25/1/39 28/2/39 27/2/39
|
f 25/1/39 28/2/39 27/2/39
|
||||||
f 42/1/40 47/1/41 41/1/40
|
f 42/1/40 47/1/41 41/1/40
|
||||||
f 47/1/41 42/1/40 48/1/41
|
f 47/1/41 42/1/40 48/1/41
|
||||||
f 48/1/41 25/1/28 47/1/41
|
f 48/1/41 25/1/28 47/1/41
|
||||||
f 25/1/28 48/1/41 26/1/28
|
f 25/1/28 48/1/41 26/1/28
|
||||||
f 51/2/30 50/1/30 49/1/30
|
f 51/2/30 50/1/30 49/1/30
|
||||||
f 50/1/30 51/2/30 52/2/30
|
f 50/1/30 51/2/30 52/2/30
|
||||||
f 36/2/22 53/2/31 35/2/21
|
f 36/2/22 53/2/31 35/2/21
|
||||||
f 53/2/31 36/2/22 54/2/32
|
f 53/2/31 36/2/22 54/2/32
|
||||||
f 54/2/32 51/2/33 53/2/31
|
f 54/2/32 51/2/33 53/2/31
|
||||||
f 51/2/33 54/2/32 52/2/34
|
f 51/2/33 54/2/32 52/2/34
|
||||||
f 53/2/31 33/1/24 35/2/21
|
f 53/2/31 33/1/24 35/2/21
|
||||||
f 33/1/24 53/2/31 55/1/35
|
f 33/1/24 53/2/31 55/1/35
|
||||||
f 51/2/33 55/1/35 53/2/31
|
f 51/2/33 55/1/35 53/2/31
|
||||||
f 55/1/35 51/2/33 49/1/36
|
f 55/1/35 51/2/33 49/1/36
|
||||||
f 56/1/37 36/2/22 34/1/26
|
f 56/1/37 36/2/22 34/1/26
|
||||||
f 36/2/22 56/1/37 54/2/32
|
f 36/2/22 56/1/37 54/2/32
|
||||||
f 50/1/38 54/2/32 56/1/37
|
f 50/1/38 54/2/32 56/1/37
|
||||||
f 54/2/32 50/1/38 52/2/34
|
f 54/2/32 50/1/38 52/2/34
|
||||||
f 36/2/39 33/1/39 34/1/39
|
f 36/2/39 33/1/39 34/1/39
|
||||||
f 33/1/39 36/2/39 35/2/39
|
f 33/1/39 36/2/39 35/2/39
|
||||||
f 50/1/40 55/1/41 49/1/40
|
f 50/1/40 55/1/41 49/1/40
|
||||||
f 55/1/41 50/1/40 56/1/41
|
f 55/1/41 50/1/40 56/1/41
|
||||||
f 56/1/41 33/1/28 55/1/41
|
f 56/1/41 33/1/28 55/1/41
|
||||||
f 33/1/28 56/1/41 34/1/28
|
f 33/1/28 56/1/41 34/1/28
|
||||||
f 59/2/42 58/1/42 57/1/42
|
f 59/2/42 58/1/42 57/1/42
|
||||||
f 58/1/42 59/2/42 60/2/42
|
f 58/1/42 59/2/42 60/2/42
|
||||||
f 44/2/34 59/2/43 43/2/33
|
f 44/2/34 59/2/43 43/2/33
|
||||||
f 59/2/43 44/2/34 60/2/44
|
f 59/2/43 44/2/34 60/2/44
|
||||||
f 60/2/44 59/2/43 59/2/43
|
f 60/2/44 59/2/43 59/2/43
|
||||||
f 59/2/43 60/2/44 60/2/44
|
f 59/2/43 60/2/44 60/2/44
|
||||||
f 59/2/43 41/1/36 43/2/33
|
f 59/2/43 41/1/36 43/2/33
|
||||||
f 41/1/36 59/2/43 57/1/45
|
f 41/1/36 59/2/43 57/1/45
|
||||||
f 59/2/43 57/1/45 59/2/43
|
f 59/2/43 57/1/45 59/2/43
|
||||||
f 57/1/45 59/2/43 57/1/45
|
f 57/1/45 59/2/43 57/1/45
|
||||||
f 58/1/46 44/2/34 42/1/38
|
f 58/1/46 44/2/34 42/1/38
|
||||||
f 44/2/34 58/1/46 60/2/44
|
f 44/2/34 58/1/46 60/2/44
|
||||||
f 58/1/46 60/2/44 58/1/46
|
f 58/1/46 60/2/44 58/1/46
|
||||||
f 60/2/44 58/1/46 60/2/44
|
f 60/2/44 58/1/46 60/2/44
|
||||||
f 44/2/47 41/1/47 42/1/47
|
f 44/2/47 41/1/47 42/1/47
|
||||||
f 41/1/47 44/2/47 43/2/47
|
f 41/1/47 44/2/47 43/2/47
|
||||||
f 58/1/48 57/1/48 57/1/48
|
f 58/1/48 57/1/48 57/1/48
|
||||||
f 57/1/48 58/1/48 58/1/48
|
f 57/1/48 58/1/48 58/1/48
|
||||||
f 58/1/48 41/1/40 57/1/48
|
f 58/1/48 41/1/40 57/1/48
|
||||||
f 41/1/40 58/1/48 42/1/40
|
f 41/1/40 58/1/48 42/1/40
|
||||||
f 63/2/42 62/1/42 61/1/42
|
f 63/2/42 62/1/42 61/1/42
|
||||||
f 62/1/42 63/2/42 64/2/42
|
f 62/1/42 63/2/42 64/2/42
|
||||||
f 52/2/34 63/2/43 51/2/33
|
f 52/2/34 63/2/43 51/2/33
|
||||||
f 63/2/43 52/2/34 64/2/44
|
f 63/2/43 52/2/34 64/2/44
|
||||||
f 64/2/44 63/2/43 63/2/43
|
f 64/2/44 63/2/43 63/2/43
|
||||||
f 63/2/43 64/2/44 64/2/44
|
f 63/2/43 64/2/44 64/2/44
|
||||||
f 63/2/43 49/1/36 51/2/33
|
f 63/2/43 49/1/36 51/2/33
|
||||||
f 49/1/36 63/2/43 61/1/45
|
f 49/1/36 63/2/43 61/1/45
|
||||||
f 63/2/43 61/1/45 63/2/43
|
f 63/2/43 61/1/45 63/2/43
|
||||||
f 61/1/45 63/2/43 61/1/45
|
f 61/1/45 63/2/43 61/1/45
|
||||||
f 62/1/46 52/2/34 50/1/38
|
f 62/1/46 52/2/34 50/1/38
|
||||||
f 52/2/34 62/1/46 64/2/44
|
f 52/2/34 62/1/46 64/2/44
|
||||||
f 62/1/46 64/2/44 62/1/46
|
f 62/1/46 64/2/44 62/1/46
|
||||||
f 64/2/44 62/1/46 64/2/44
|
f 64/2/44 62/1/46 64/2/44
|
||||||
f 52/2/47 49/1/47 50/1/47
|
f 52/2/47 49/1/47 50/1/47
|
||||||
f 49/1/47 52/2/47 51/2/47
|
f 49/1/47 52/2/47 51/2/47
|
||||||
f 62/1/48 61/1/48 61/1/48
|
f 62/1/48 61/1/48 61/1/48
|
||||||
f 61/1/48 62/1/48 62/1/48
|
f 61/1/48 62/1/48 62/1/48
|
||||||
f 62/1/48 49/1/40 61/1/48
|
f 62/1/48 49/1/40 61/1/48
|
||||||
f 49/1/40 62/1/48 50/1/40
|
f 49/1/40 62/1/48 50/1/40
|
||||||
|
|
||||||
|
|||||||
@@ -1,447 +1,447 @@
|
|||||||
# Created by Kenney (www.kenney.nl)
|
# Created by Kenney (www.kenney.nl)
|
||||||
|
|
||||||
mtllib railroad-rail-corner-small.mtl
|
mtllib railroad-rail-corner-small.mtl
|
||||||
|
|
||||||
g railroad-rail-corner-small
|
g railroad-rail-corner-small
|
||||||
|
|
||||||
v 0.01303887 0 1.128196 1 1 1
|
v 0.01303887 0 1.128196 1 1 1
|
||||||
v -0.07224965 0 1.075987 1 1 1
|
v -0.07224965 0 1.075987 1 1 1
|
||||||
v 0.01303887 0.1 1.128196 1 1 1
|
v 0.01303887 0.1 1.128196 1 1 1
|
||||||
v -0.07224965 0.1 1.075987 1 1 1
|
v -0.07224965 0.1 1.075987 1 1 1
|
||||||
v 0.3499999 0.1 3.814697E-06 1 1 1
|
v 0.3499999 0.1 3.814697E-06 1 1 1
|
||||||
v 0.2564378 0.1 0.5963393 1 1 1
|
v 0.2564378 0.1 0.5963393 1 1 1
|
||||||
v 0.25 0.1 3.576279E-06 1 1 1
|
v 0.25 0.1 3.576279E-06 1 1 1
|
||||||
v 0.1609817 0.1 0.5665379 1 1 1
|
v 0.1609817 0.1 0.5665379 1 1 1
|
||||||
v 0.3499999 0 3.814697E-06 1 1 1
|
v 0.3499999 0 3.814697E-06 1 1 1
|
||||||
v 0.2564378 0 0.5963393 1 1 1
|
v 0.2564378 0 0.5963393 1 1 1
|
||||||
v 0.25 0 3.576279E-06 1 1 1
|
v 0.25 0 3.576279E-06 1 1 1
|
||||||
v 0.1609817 0 0.5665379 1 1 1
|
v 0.1609817 0 0.5665379 1 1 1
|
||||||
v -0.4986923 0 0.8149374 1 1 1
|
v -0.4986923 0 0.8149374 1 1 1
|
||||||
v -0.5839808 0 0.7627276 1 1 1
|
v -0.5839808 0 0.7627276 1 1 1
|
||||||
v -0.4986923 0.1 0.8149374 1 1 1
|
v -0.4986923 0.1 0.8149374 1 1 1
|
||||||
v -0.5839808 0.1 0.7627276 1 1 1
|
v -0.5839808 0.1 0.7627276 1 1 1
|
||||||
v -0.25 0.1 2.622604E-06 1 1 1
|
v -0.25 0.1 2.622604E-06 1 1 1
|
||||||
v -0.316299 0.1 0.4175299 1 1 1
|
v -0.316299 0.1 0.4175299 1 1 1
|
||||||
v -0.3499999 0.1 2.384186E-06 1 1 1
|
v -0.3499999 0.1 2.384186E-06 1 1 1
|
||||||
v -0.4117551 0.1 0.3877285 1 1 1
|
v -0.4117551 0.1 0.3877285 1 1 1
|
||||||
v -0.25 0 2.622604E-06 1 1 1
|
v -0.25 0 2.622604E-06 1 1 1
|
||||||
v -0.316299 0 0.4175299 1 1 1
|
v -0.316299 0 0.4175299 1 1 1
|
||||||
v -0.3499999 0 2.384186E-06 1 1 1
|
v -0.3499999 0 2.384186E-06 1 1 1
|
||||||
v -0.4117551 0 0.3877285 1 1 1
|
v -0.4117551 0 0.3877285 1 1 1
|
||||||
v -0.7770739 0 1.952166 1 1 1
|
v -0.7770739 0 1.952166 1 1 1
|
||||||
v -0.8329458 0 1.86923 1 1 1
|
v -0.8329458 0 1.86923 1 1 1
|
||||||
v -0.7770739 0.1 1.952166 1 1 1
|
v -0.7770739 0.1 1.952166 1 1 1
|
||||||
v -0.8329458 0.1 1.86923 1 1 1
|
v -0.8329458 0.1 1.86923 1 1 1
|
||||||
v -0.3384459 0.1 1.582615 1 1 1
|
v -0.3384459 0.1 1.582615 1 1 1
|
||||||
v -0.4105844 0.1 1.513362 1 1 1
|
v -0.4105844 0.1 1.513362 1 1 1
|
||||||
v -0.3384459 0 1.582615 1 1 1
|
v -0.3384459 0 1.582615 1 1 1
|
||||||
v -0.4105844 0 1.513362 1 1 1
|
v -0.4105844 0 1.513362 1 1 1
|
||||||
v -1.112305 0 1.454551 1 1 1
|
v -1.112305 0 1.454551 1 1 1
|
||||||
v -1.168176 0 1.371616 1 1 1
|
v -1.168176 0 1.371616 1 1 1
|
||||||
v -1.112305 0.1 1.454551 1 1 1
|
v -1.112305 0.1 1.454551 1 1 1
|
||||||
v -1.168176 0.1 1.371616 1 1 1
|
v -1.168176 0.1 1.371616 1 1 1
|
||||||
v -0.7712772 0.1 1.167095 1 1 1
|
v -0.7712772 0.1 1.167095 1 1 1
|
||||||
v -0.8434157 0.1 1.097842 1 1 1
|
v -0.8434157 0.1 1.097842 1 1 1
|
||||||
v -0.7712772 0 1.167095 1 1 1
|
v -0.7712772 0 1.167095 1 1 1
|
||||||
v -0.8434157 0 1.097842 1 1 1
|
v -0.8434157 0 1.097842 1 1 1
|
||||||
v -1.880378 0 2.346164 1 1 1
|
v -1.880378 0 2.346164 1 1 1
|
||||||
v -1.886755 0 2.246367 1 1 1
|
v -1.886755 0 2.246367 1 1 1
|
||||||
v -1.880378 0.1 2.346164 1 1 1
|
v -1.880378 0.1 2.346164 1 1 1
|
||||||
v -1.886755 0.1 2.246367 1 1 1
|
v -1.886755 0.1 2.246367 1 1 1
|
||||||
v -1.294373 0.1 2.219167 1 1 1
|
v -1.294373 0.1 2.219167 1 1 1
|
||||||
v -1.329077 0.1 2.125382 1 1 1
|
v -1.329077 0.1 2.125382 1 1 1
|
||||||
v -1.294373 0 2.219167 1 1 1
|
v -1.294373 0 2.219167 1 1 1
|
||||||
v -1.329077 0 2.125382 1 1 1
|
v -1.329077 0 2.125382 1 1 1
|
||||||
v -1.918643 0 1.747385 1 1 1
|
v -1.918643 0 1.747385 1 1 1
|
||||||
v -1.92502 0 1.647589 1 1 1
|
v -1.92502 0 1.647589 1 1 1
|
||||||
v -1.918643 0.1 1.747385 1 1 1
|
v -1.918643 0.1 1.747385 1 1 1
|
||||||
v -1.92502 0.1 1.647589 1 1 1
|
v -1.92502 0.1 1.647589 1 1 1
|
||||||
v -1.502599 0.1 1.656457 1 1 1
|
v -1.502599 0.1 1.656457 1 1 1
|
||||||
v -1.537304 0.1 1.562672 1 1 1
|
v -1.537304 0.1 1.562672 1 1 1
|
||||||
v -1.502599 0 1.656457 1 1 1
|
v -1.502599 0 1.656457 1 1 1
|
||||||
v -1.537304 0 1.562672 1 1 1
|
v -1.537304 0 1.562672 1 1 1
|
||||||
v -1.999996 0 2.35 1 1 1
|
v -1.999996 0 2.35 1 1 1
|
||||||
v -1.999996 0 2.25 1 1 1
|
v -1.999996 0 2.25 1 1 1
|
||||||
v -1.999996 0.1 2.35 1 1 1
|
v -1.999996 0.1 2.35 1 1 1
|
||||||
v -1.999996 0.1 2.25 1 1 1
|
v -1.999996 0.1 2.25 1 1 1
|
||||||
v -1.999998 0 1.75 1 1 1
|
v -1.999998 0 1.75 1 1 1
|
||||||
v -1.999998 0 1.65 1 1 1
|
v -1.999998 0 1.65 1 1 1
|
||||||
v -1.999998 0.1 1.75 1 1 1
|
v -1.999998 0.1 1.75 1 1 1
|
||||||
v -1.999998 0.1 1.65 1 1 1
|
v -1.999998 0.1 1.65 1 1 1
|
||||||
|
|
||||||
vn -0.5220984 0 0.8528852
|
vn -0.5220984 0 0.8528852
|
||||||
vn 0.7071068 0.7071068 1.459836E-06
|
vn 0.7071068 0.7071068 1.459836E-06
|
||||||
vn 0.6749765 0.7071068 0.2107289
|
vn 0.6749765 0.7071068 0.2107289
|
||||||
vn -0.7071068 0.7071068 -1.459836E-06
|
vn -0.7071068 0.7071068 -1.459836E-06
|
||||||
vn -0.6749765 0.7071068 -0.2107289
|
vn -0.6749765 0.7071068 -0.2107289
|
||||||
vn 0.603081 0.7071068 0.3691793
|
vn 0.603081 0.7071068 0.3691793
|
||||||
vn -0.603081 0.7071068 -0.3691793
|
vn -0.603081 0.7071068 -0.3691793
|
||||||
vn 1 0 2.06452E-06
|
vn 1 0 2.06452E-06
|
||||||
vn 0.954561 0 0.2980156
|
vn 0.954561 0 0.2980156
|
||||||
vn 0.8528852 0 0.5220984
|
vn 0.8528852 0 0.5220984
|
||||||
vn -1 0 -2.06452E-06
|
vn -1 0 -2.06452E-06
|
||||||
vn -0.954561 0 -0.2980156
|
vn -0.954561 0 -0.2980156
|
||||||
vn -0.8528852 0 -0.5220984
|
vn -0.8528852 0 -0.5220984
|
||||||
vn 2.06452E-06 0 -1
|
vn 2.06452E-06 0 -1
|
||||||
vn 0 -1 0
|
vn 0 -1 0
|
||||||
vn -0.8293579 0 0.5587178
|
vn -0.8293579 0 0.5587178
|
||||||
vn 0.5100965 0.7071068 0.4896953
|
vn 0.5100965 0.7071068 0.4896953
|
||||||
vn -0.5100965 0.7071068 -0.4896953
|
vn -0.5100965 0.7071068 -0.4896953
|
||||||
vn 0.3950732 0.7071068 0.5864446
|
vn 0.3950732 0.7071068 0.5864446
|
||||||
vn -0.3950732 0.7071068 -0.5864446
|
vn -0.3950732 0.7071068 -0.5864446
|
||||||
vn 0.7213855 0 0.6925338
|
vn 0.7213855 0 0.6925338
|
||||||
vn 0.5587178 0 0.8293579
|
vn 0.5587178 0 0.8293579
|
||||||
vn -0.7213855 0 -0.6925338
|
vn -0.7213855 0 -0.6925338
|
||||||
vn -0.5587178 0 -0.8293579
|
vn -0.5587178 0 -0.8293579
|
||||||
vn 0.5220984 0 -0.8528852
|
vn 0.5220984 0 -0.8528852
|
||||||
vn -0.9979642 0 0.06377482
|
vn -0.9979642 0 0.06377482
|
||||||
vn 0.245397 0.7071068 0.6631594
|
vn 0.245397 0.7071068 0.6631594
|
||||||
vn -0.245397 0.7071068 -0.6631594
|
vn -0.245397 0.7071068 -0.6631594
|
||||||
vn 0.04509562 0.7071068 0.7056673
|
vn 0.04509562 0.7071068 0.7056673
|
||||||
vn -0.04509562 0.7071068 -0.7056673
|
vn -0.04509562 0.7071068 -0.7056673
|
||||||
vn 0.3470438 0 0.937849
|
vn 0.3470438 0 0.937849
|
||||||
vn 0.06377482 0 0.9979642
|
vn 0.06377482 0 0.9979642
|
||||||
vn -0.3470438 0 -0.937849
|
vn -0.3470438 0 -0.937849
|
||||||
vn -0.06377482 0 -0.9979642
|
vn -0.06377482 0 -0.9979642
|
||||||
vn 0.8293579 0 -0.5587178
|
vn 0.8293579 0 -0.5587178
|
||||||
vn -0.9999999 0 2.205372E-06
|
vn -0.9999999 0 2.205372E-06
|
||||||
vn 1.549721E-06 0.7071068 0.7071067
|
vn 1.549721E-06 0.7071068 0.7071067
|
||||||
vn -1.549721E-06 0.7071068 -0.7071067
|
vn -1.549721E-06 0.7071068 -0.7071067
|
||||||
vn 2.205372E-06 0 0.9999999
|
vn 2.205372E-06 0 0.9999999
|
||||||
vn -2.205372E-06 0 -0.9999999
|
vn -2.205372E-06 0 -0.9999999
|
||||||
vn 0.9979642 0 -0.06377482
|
vn 0.9979642 0 -0.06377482
|
||||||
|
|
||||||
vt 0.96875 0.025
|
vt 0.96875 0.025
|
||||||
vt 0.96875 0.225
|
vt 0.96875 0.225
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/15 1/1/15
|
f 2/1/15 10/1/15 1/1/15
|
||||||
f 10/1/15 2/1/15 12/1/15
|
f 10/1/15 2/1/15 12/1/15
|
||||||
f 12/1/15 9/1/15 10/1/15
|
f 12/1/15 9/1/15 10/1/15
|
||||||
f 9/1/15 12/1/15 11/1/15
|
f 9/1/15 12/1/15 11/1/15
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/15 13/1/15
|
f 14/1/15 22/1/15 13/1/15
|
||||||
f 22/1/15 14/1/15 24/1/15
|
f 22/1/15 14/1/15 24/1/15
|
||||||
f 24/1/15 21/1/15 22/1/15
|
f 24/1/15 21/1/15 22/1/15
|
||||||
f 21/1/15 24/1/15 23/1/15
|
f 21/1/15 24/1/15 23/1/15
|
||||||
f 27/2/16 26/1/16 25/1/16
|
f 27/2/16 26/1/16 25/1/16
|
||||||
f 26/1/16 27/2/16 28/2/16
|
f 26/1/16 27/2/16 28/2/16
|
||||||
f 4/2/7 29/2/17 3/2/6
|
f 4/2/7 29/2/17 3/2/6
|
||||||
f 29/2/17 4/2/7 30/2/18
|
f 29/2/17 4/2/7 30/2/18
|
||||||
f 30/2/18 27/2/19 29/2/17
|
f 30/2/18 27/2/19 29/2/17
|
||||||
f 27/2/19 30/2/18 28/2/20
|
f 27/2/19 30/2/18 28/2/20
|
||||||
f 29/2/17 1/1/10 3/2/6
|
f 29/2/17 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/17 31/1/21
|
f 1/1/10 29/2/17 31/1/21
|
||||||
f 27/2/19 31/1/21 29/2/17
|
f 27/2/19 31/1/21 29/2/17
|
||||||
f 31/1/21 27/2/19 25/1/22
|
f 31/1/21 27/2/19 25/1/22
|
||||||
f 32/1/23 4/2/7 2/1/13
|
f 32/1/23 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/23 30/2/18
|
f 4/2/7 32/1/23 30/2/18
|
||||||
f 26/1/24 30/2/18 32/1/23
|
f 26/1/24 30/2/18 32/1/23
|
||||||
f 30/2/18 26/1/24 28/2/20
|
f 30/2/18 26/1/24 28/2/20
|
||||||
f 4/2/25 1/1/25 2/1/25
|
f 4/2/25 1/1/25 2/1/25
|
||||||
f 1/1/25 4/2/25 3/2/25
|
f 1/1/25 4/2/25 3/2/25
|
||||||
f 26/1/15 31/1/15 25/1/15
|
f 26/1/15 31/1/15 25/1/15
|
||||||
f 31/1/15 26/1/15 32/1/15
|
f 31/1/15 26/1/15 32/1/15
|
||||||
f 32/1/15 1/1/15 31/1/15
|
f 32/1/15 1/1/15 31/1/15
|
||||||
f 1/1/15 32/1/15 2/1/15
|
f 1/1/15 32/1/15 2/1/15
|
||||||
f 35/2/16 34/1/16 33/1/16
|
f 35/2/16 34/1/16 33/1/16
|
||||||
f 34/1/16 35/2/16 36/2/16
|
f 34/1/16 35/2/16 36/2/16
|
||||||
f 16/2/7 37/2/17 15/2/6
|
f 16/2/7 37/2/17 15/2/6
|
||||||
f 37/2/17 16/2/7 38/2/18
|
f 37/2/17 16/2/7 38/2/18
|
||||||
f 38/2/18 35/2/19 37/2/17
|
f 38/2/18 35/2/19 37/2/17
|
||||||
f 35/2/19 38/2/18 36/2/20
|
f 35/2/19 38/2/18 36/2/20
|
||||||
f 37/2/17 13/1/10 15/2/6
|
f 37/2/17 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/17 39/1/21
|
f 13/1/10 37/2/17 39/1/21
|
||||||
f 35/2/19 39/1/21 37/2/17
|
f 35/2/19 39/1/21 37/2/17
|
||||||
f 39/1/21 35/2/19 33/1/22
|
f 39/1/21 35/2/19 33/1/22
|
||||||
f 40/1/23 16/2/7 14/1/13
|
f 40/1/23 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/23 38/2/18
|
f 16/2/7 40/1/23 38/2/18
|
||||||
f 34/1/24 38/2/18 40/1/23
|
f 34/1/24 38/2/18 40/1/23
|
||||||
f 38/2/18 34/1/24 36/2/20
|
f 38/2/18 34/1/24 36/2/20
|
||||||
f 16/2/25 13/1/25 14/1/25
|
f 16/2/25 13/1/25 14/1/25
|
||||||
f 13/1/25 16/2/25 15/2/25
|
f 13/1/25 16/2/25 15/2/25
|
||||||
f 34/1/15 39/1/15 33/1/15
|
f 34/1/15 39/1/15 33/1/15
|
||||||
f 39/1/15 34/1/15 40/1/15
|
f 39/1/15 34/1/15 40/1/15
|
||||||
f 40/1/15 13/1/15 39/1/15
|
f 40/1/15 13/1/15 39/1/15
|
||||||
f 13/1/15 40/1/15 14/1/15
|
f 13/1/15 40/1/15 14/1/15
|
||||||
f 43/2/26 42/1/26 41/1/26
|
f 43/2/26 42/1/26 41/1/26
|
||||||
f 42/1/26 43/2/26 44/2/26
|
f 42/1/26 43/2/26 44/2/26
|
||||||
f 28/2/20 45/2/27 27/2/19
|
f 28/2/20 45/2/27 27/2/19
|
||||||
f 45/2/27 28/2/20 46/2/28
|
f 45/2/27 28/2/20 46/2/28
|
||||||
f 46/2/28 43/2/29 45/2/27
|
f 46/2/28 43/2/29 45/2/27
|
||||||
f 43/2/29 46/2/28 44/2/30
|
f 43/2/29 46/2/28 44/2/30
|
||||||
f 45/2/27 25/1/22 27/2/19
|
f 45/2/27 25/1/22 27/2/19
|
||||||
f 25/1/22 45/2/27 47/1/31
|
f 25/1/22 45/2/27 47/1/31
|
||||||
f 43/2/29 47/1/31 45/2/27
|
f 43/2/29 47/1/31 45/2/27
|
||||||
f 47/1/31 43/2/29 41/1/32
|
f 47/1/31 43/2/29 41/1/32
|
||||||
f 48/1/33 28/2/20 26/1/24
|
f 48/1/33 28/2/20 26/1/24
|
||||||
f 28/2/20 48/1/33 46/2/28
|
f 28/2/20 48/1/33 46/2/28
|
||||||
f 42/1/34 46/2/28 48/1/33
|
f 42/1/34 46/2/28 48/1/33
|
||||||
f 46/2/28 42/1/34 44/2/30
|
f 46/2/28 42/1/34 44/2/30
|
||||||
f 28/2/35 25/1/35 26/1/35
|
f 28/2/35 25/1/35 26/1/35
|
||||||
f 25/1/35 28/2/35 27/2/35
|
f 25/1/35 28/2/35 27/2/35
|
||||||
f 42/1/15 47/1/15 41/1/15
|
f 42/1/15 47/1/15 41/1/15
|
||||||
f 47/1/15 42/1/15 48/1/15
|
f 47/1/15 42/1/15 48/1/15
|
||||||
f 48/1/15 25/1/15 47/1/15
|
f 48/1/15 25/1/15 47/1/15
|
||||||
f 25/1/15 48/1/15 26/1/15
|
f 25/1/15 48/1/15 26/1/15
|
||||||
f 51/2/26 50/1/26 49/1/26
|
f 51/2/26 50/1/26 49/1/26
|
||||||
f 50/1/26 51/2/26 52/2/26
|
f 50/1/26 51/2/26 52/2/26
|
||||||
f 36/2/20 53/2/27 35/2/19
|
f 36/2/20 53/2/27 35/2/19
|
||||||
f 53/2/27 36/2/20 54/2/28
|
f 53/2/27 36/2/20 54/2/28
|
||||||
f 54/2/28 51/2/29 53/2/27
|
f 54/2/28 51/2/29 53/2/27
|
||||||
f 51/2/29 54/2/28 52/2/30
|
f 51/2/29 54/2/28 52/2/30
|
||||||
f 53/2/27 33/1/22 35/2/19
|
f 53/2/27 33/1/22 35/2/19
|
||||||
f 33/1/22 53/2/27 55/1/31
|
f 33/1/22 53/2/27 55/1/31
|
||||||
f 51/2/29 55/1/31 53/2/27
|
f 51/2/29 55/1/31 53/2/27
|
||||||
f 55/1/31 51/2/29 49/1/32
|
f 55/1/31 51/2/29 49/1/32
|
||||||
f 56/1/33 36/2/20 34/1/24
|
f 56/1/33 36/2/20 34/1/24
|
||||||
f 36/2/20 56/1/33 54/2/28
|
f 36/2/20 56/1/33 54/2/28
|
||||||
f 50/1/34 54/2/28 56/1/33
|
f 50/1/34 54/2/28 56/1/33
|
||||||
f 54/2/28 50/1/34 52/2/30
|
f 54/2/28 50/1/34 52/2/30
|
||||||
f 36/2/35 33/1/35 34/1/35
|
f 36/2/35 33/1/35 34/1/35
|
||||||
f 33/1/35 36/2/35 35/2/35
|
f 33/1/35 36/2/35 35/2/35
|
||||||
f 50/1/15 55/1/15 49/1/15
|
f 50/1/15 55/1/15 49/1/15
|
||||||
f 55/1/15 50/1/15 56/1/15
|
f 55/1/15 50/1/15 56/1/15
|
||||||
f 56/1/15 33/1/15 55/1/15
|
f 56/1/15 33/1/15 55/1/15
|
||||||
f 33/1/15 56/1/15 34/1/15
|
f 33/1/15 56/1/15 34/1/15
|
||||||
f 59/2/36 58/1/36 57/1/36
|
f 59/2/36 58/1/36 57/1/36
|
||||||
f 58/1/36 59/2/36 60/2/36
|
f 58/1/36 59/2/36 60/2/36
|
||||||
f 44/2/30 59/2/37 43/2/29
|
f 44/2/30 59/2/37 43/2/29
|
||||||
f 59/2/37 44/2/30 60/2/38
|
f 59/2/37 44/2/30 60/2/38
|
||||||
f 60/2/38 59/2/37 59/2/37
|
f 60/2/38 59/2/37 59/2/37
|
||||||
f 59/2/37 60/2/38 60/2/38
|
f 59/2/37 60/2/38 60/2/38
|
||||||
f 59/2/37 41/1/32 43/2/29
|
f 59/2/37 41/1/32 43/2/29
|
||||||
f 41/1/32 59/2/37 57/1/39
|
f 41/1/32 59/2/37 57/1/39
|
||||||
f 59/2/37 57/1/39 59/2/37
|
f 59/2/37 57/1/39 59/2/37
|
||||||
f 57/1/39 59/2/37 57/1/39
|
f 57/1/39 59/2/37 57/1/39
|
||||||
f 58/1/40 44/2/30 42/1/34
|
f 58/1/40 44/2/30 42/1/34
|
||||||
f 44/2/30 58/1/40 60/2/38
|
f 44/2/30 58/1/40 60/2/38
|
||||||
f 58/1/40 60/2/38 58/1/40
|
f 58/1/40 60/2/38 58/1/40
|
||||||
f 60/2/38 58/1/40 60/2/38
|
f 60/2/38 58/1/40 60/2/38
|
||||||
f 44/2/41 41/1/41 42/1/41
|
f 44/2/41 41/1/41 42/1/41
|
||||||
f 41/1/41 44/2/41 43/2/41
|
f 41/1/41 44/2/41 43/2/41
|
||||||
f 58/1/15 57/1/15 57/1/15
|
f 58/1/15 57/1/15 57/1/15
|
||||||
f 57/1/15 58/1/15 58/1/15
|
f 57/1/15 58/1/15 58/1/15
|
||||||
f 58/1/15 41/1/15 57/1/15
|
f 58/1/15 41/1/15 57/1/15
|
||||||
f 41/1/15 58/1/15 42/1/15
|
f 41/1/15 58/1/15 42/1/15
|
||||||
f 63/2/36 62/1/36 61/1/36
|
f 63/2/36 62/1/36 61/1/36
|
||||||
f 62/1/36 63/2/36 64/2/36
|
f 62/1/36 63/2/36 64/2/36
|
||||||
f 52/2/30 63/2/37 51/2/29
|
f 52/2/30 63/2/37 51/2/29
|
||||||
f 63/2/37 52/2/30 64/2/38
|
f 63/2/37 52/2/30 64/2/38
|
||||||
f 64/2/38 63/2/37 63/2/37
|
f 64/2/38 63/2/37 63/2/37
|
||||||
f 63/2/37 64/2/38 64/2/38
|
f 63/2/37 64/2/38 64/2/38
|
||||||
f 63/2/37 49/1/32 51/2/29
|
f 63/2/37 49/1/32 51/2/29
|
||||||
f 49/1/32 63/2/37 61/1/39
|
f 49/1/32 63/2/37 61/1/39
|
||||||
f 63/2/37 61/1/39 63/2/37
|
f 63/2/37 61/1/39 63/2/37
|
||||||
f 61/1/39 63/2/37 61/1/39
|
f 61/1/39 63/2/37 61/1/39
|
||||||
f 62/1/40 52/2/30 50/1/34
|
f 62/1/40 52/2/30 50/1/34
|
||||||
f 52/2/30 62/1/40 64/2/38
|
f 52/2/30 62/1/40 64/2/38
|
||||||
f 62/1/40 64/2/38 62/1/40
|
f 62/1/40 64/2/38 62/1/40
|
||||||
f 64/2/38 62/1/40 64/2/38
|
f 64/2/38 62/1/40 64/2/38
|
||||||
f 52/2/41 49/1/41 50/1/41
|
f 52/2/41 49/1/41 50/1/41
|
||||||
f 49/1/41 52/2/41 51/2/41
|
f 49/1/41 52/2/41 51/2/41
|
||||||
f 62/1/15 61/1/15 61/1/15
|
f 62/1/15 61/1/15 61/1/15
|
||||||
f 61/1/15 62/1/15 62/1/15
|
f 61/1/15 62/1/15 62/1/15
|
||||||
f 62/1/15 49/1/15 61/1/15
|
f 62/1/15 49/1/15 61/1/15
|
||||||
f 49/1/15 62/1/15 50/1/15
|
f 49/1/15 62/1/15 50/1/15
|
||||||
|
|
||||||
g railroad-rail-corner-small
|
g railroad-rail-corner-small
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/15 1/1/15
|
f 2/1/15 10/1/15 1/1/15
|
||||||
f 10/1/15 2/1/15 12/1/15
|
f 10/1/15 2/1/15 12/1/15
|
||||||
f 12/1/15 9/1/15 10/1/15
|
f 12/1/15 9/1/15 10/1/15
|
||||||
f 9/1/15 12/1/15 11/1/15
|
f 9/1/15 12/1/15 11/1/15
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/15 13/1/15
|
f 14/1/15 22/1/15 13/1/15
|
||||||
f 22/1/15 14/1/15 24/1/15
|
f 22/1/15 14/1/15 24/1/15
|
||||||
f 24/1/15 21/1/15 22/1/15
|
f 24/1/15 21/1/15 22/1/15
|
||||||
f 21/1/15 24/1/15 23/1/15
|
f 21/1/15 24/1/15 23/1/15
|
||||||
f 27/2/16 26/1/16 25/1/16
|
f 27/2/16 26/1/16 25/1/16
|
||||||
f 26/1/16 27/2/16 28/2/16
|
f 26/1/16 27/2/16 28/2/16
|
||||||
f 4/2/7 29/2/17 3/2/6
|
f 4/2/7 29/2/17 3/2/6
|
||||||
f 29/2/17 4/2/7 30/2/18
|
f 29/2/17 4/2/7 30/2/18
|
||||||
f 30/2/18 27/2/19 29/2/17
|
f 30/2/18 27/2/19 29/2/17
|
||||||
f 27/2/19 30/2/18 28/2/20
|
f 27/2/19 30/2/18 28/2/20
|
||||||
f 29/2/17 1/1/10 3/2/6
|
f 29/2/17 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/17 31/1/21
|
f 1/1/10 29/2/17 31/1/21
|
||||||
f 27/2/19 31/1/21 29/2/17
|
f 27/2/19 31/1/21 29/2/17
|
||||||
f 31/1/21 27/2/19 25/1/22
|
f 31/1/21 27/2/19 25/1/22
|
||||||
f 32/1/23 4/2/7 2/1/13
|
f 32/1/23 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/23 30/2/18
|
f 4/2/7 32/1/23 30/2/18
|
||||||
f 26/1/24 30/2/18 32/1/23
|
f 26/1/24 30/2/18 32/1/23
|
||||||
f 30/2/18 26/1/24 28/2/20
|
f 30/2/18 26/1/24 28/2/20
|
||||||
f 4/2/25 1/1/25 2/1/25
|
f 4/2/25 1/1/25 2/1/25
|
||||||
f 1/1/25 4/2/25 3/2/25
|
f 1/1/25 4/2/25 3/2/25
|
||||||
f 26/1/15 31/1/15 25/1/15
|
f 26/1/15 31/1/15 25/1/15
|
||||||
f 31/1/15 26/1/15 32/1/15
|
f 31/1/15 26/1/15 32/1/15
|
||||||
f 32/1/15 1/1/15 31/1/15
|
f 32/1/15 1/1/15 31/1/15
|
||||||
f 1/1/15 32/1/15 2/1/15
|
f 1/1/15 32/1/15 2/1/15
|
||||||
f 35/2/16 34/1/16 33/1/16
|
f 35/2/16 34/1/16 33/1/16
|
||||||
f 34/1/16 35/2/16 36/2/16
|
f 34/1/16 35/2/16 36/2/16
|
||||||
f 16/2/7 37/2/17 15/2/6
|
f 16/2/7 37/2/17 15/2/6
|
||||||
f 37/2/17 16/2/7 38/2/18
|
f 37/2/17 16/2/7 38/2/18
|
||||||
f 38/2/18 35/2/19 37/2/17
|
f 38/2/18 35/2/19 37/2/17
|
||||||
f 35/2/19 38/2/18 36/2/20
|
f 35/2/19 38/2/18 36/2/20
|
||||||
f 37/2/17 13/1/10 15/2/6
|
f 37/2/17 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/17 39/1/21
|
f 13/1/10 37/2/17 39/1/21
|
||||||
f 35/2/19 39/1/21 37/2/17
|
f 35/2/19 39/1/21 37/2/17
|
||||||
f 39/1/21 35/2/19 33/1/22
|
f 39/1/21 35/2/19 33/1/22
|
||||||
f 40/1/23 16/2/7 14/1/13
|
f 40/1/23 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/23 38/2/18
|
f 16/2/7 40/1/23 38/2/18
|
||||||
f 34/1/24 38/2/18 40/1/23
|
f 34/1/24 38/2/18 40/1/23
|
||||||
f 38/2/18 34/1/24 36/2/20
|
f 38/2/18 34/1/24 36/2/20
|
||||||
f 16/2/25 13/1/25 14/1/25
|
f 16/2/25 13/1/25 14/1/25
|
||||||
f 13/1/25 16/2/25 15/2/25
|
f 13/1/25 16/2/25 15/2/25
|
||||||
f 34/1/15 39/1/15 33/1/15
|
f 34/1/15 39/1/15 33/1/15
|
||||||
f 39/1/15 34/1/15 40/1/15
|
f 39/1/15 34/1/15 40/1/15
|
||||||
f 40/1/15 13/1/15 39/1/15
|
f 40/1/15 13/1/15 39/1/15
|
||||||
f 13/1/15 40/1/15 14/1/15
|
f 13/1/15 40/1/15 14/1/15
|
||||||
f 43/2/26 42/1/26 41/1/26
|
f 43/2/26 42/1/26 41/1/26
|
||||||
f 42/1/26 43/2/26 44/2/26
|
f 42/1/26 43/2/26 44/2/26
|
||||||
f 28/2/20 45/2/27 27/2/19
|
f 28/2/20 45/2/27 27/2/19
|
||||||
f 45/2/27 28/2/20 46/2/28
|
f 45/2/27 28/2/20 46/2/28
|
||||||
f 46/2/28 43/2/29 45/2/27
|
f 46/2/28 43/2/29 45/2/27
|
||||||
f 43/2/29 46/2/28 44/2/30
|
f 43/2/29 46/2/28 44/2/30
|
||||||
f 45/2/27 25/1/22 27/2/19
|
f 45/2/27 25/1/22 27/2/19
|
||||||
f 25/1/22 45/2/27 47/1/31
|
f 25/1/22 45/2/27 47/1/31
|
||||||
f 43/2/29 47/1/31 45/2/27
|
f 43/2/29 47/1/31 45/2/27
|
||||||
f 47/1/31 43/2/29 41/1/32
|
f 47/1/31 43/2/29 41/1/32
|
||||||
f 48/1/33 28/2/20 26/1/24
|
f 48/1/33 28/2/20 26/1/24
|
||||||
f 28/2/20 48/1/33 46/2/28
|
f 28/2/20 48/1/33 46/2/28
|
||||||
f 42/1/34 46/2/28 48/1/33
|
f 42/1/34 46/2/28 48/1/33
|
||||||
f 46/2/28 42/1/34 44/2/30
|
f 46/2/28 42/1/34 44/2/30
|
||||||
f 28/2/35 25/1/35 26/1/35
|
f 28/2/35 25/1/35 26/1/35
|
||||||
f 25/1/35 28/2/35 27/2/35
|
f 25/1/35 28/2/35 27/2/35
|
||||||
f 42/1/15 47/1/15 41/1/15
|
f 42/1/15 47/1/15 41/1/15
|
||||||
f 47/1/15 42/1/15 48/1/15
|
f 47/1/15 42/1/15 48/1/15
|
||||||
f 48/1/15 25/1/15 47/1/15
|
f 48/1/15 25/1/15 47/1/15
|
||||||
f 25/1/15 48/1/15 26/1/15
|
f 25/1/15 48/1/15 26/1/15
|
||||||
f 51/2/26 50/1/26 49/1/26
|
f 51/2/26 50/1/26 49/1/26
|
||||||
f 50/1/26 51/2/26 52/2/26
|
f 50/1/26 51/2/26 52/2/26
|
||||||
f 36/2/20 53/2/27 35/2/19
|
f 36/2/20 53/2/27 35/2/19
|
||||||
f 53/2/27 36/2/20 54/2/28
|
f 53/2/27 36/2/20 54/2/28
|
||||||
f 54/2/28 51/2/29 53/2/27
|
f 54/2/28 51/2/29 53/2/27
|
||||||
f 51/2/29 54/2/28 52/2/30
|
f 51/2/29 54/2/28 52/2/30
|
||||||
f 53/2/27 33/1/22 35/2/19
|
f 53/2/27 33/1/22 35/2/19
|
||||||
f 33/1/22 53/2/27 55/1/31
|
f 33/1/22 53/2/27 55/1/31
|
||||||
f 51/2/29 55/1/31 53/2/27
|
f 51/2/29 55/1/31 53/2/27
|
||||||
f 55/1/31 51/2/29 49/1/32
|
f 55/1/31 51/2/29 49/1/32
|
||||||
f 56/1/33 36/2/20 34/1/24
|
f 56/1/33 36/2/20 34/1/24
|
||||||
f 36/2/20 56/1/33 54/2/28
|
f 36/2/20 56/1/33 54/2/28
|
||||||
f 50/1/34 54/2/28 56/1/33
|
f 50/1/34 54/2/28 56/1/33
|
||||||
f 54/2/28 50/1/34 52/2/30
|
f 54/2/28 50/1/34 52/2/30
|
||||||
f 36/2/35 33/1/35 34/1/35
|
f 36/2/35 33/1/35 34/1/35
|
||||||
f 33/1/35 36/2/35 35/2/35
|
f 33/1/35 36/2/35 35/2/35
|
||||||
f 50/1/15 55/1/15 49/1/15
|
f 50/1/15 55/1/15 49/1/15
|
||||||
f 55/1/15 50/1/15 56/1/15
|
f 55/1/15 50/1/15 56/1/15
|
||||||
f 56/1/15 33/1/15 55/1/15
|
f 56/1/15 33/1/15 55/1/15
|
||||||
f 33/1/15 56/1/15 34/1/15
|
f 33/1/15 56/1/15 34/1/15
|
||||||
f 59/2/36 58/1/36 57/1/36
|
f 59/2/36 58/1/36 57/1/36
|
||||||
f 58/1/36 59/2/36 60/2/36
|
f 58/1/36 59/2/36 60/2/36
|
||||||
f 44/2/30 59/2/37 43/2/29
|
f 44/2/30 59/2/37 43/2/29
|
||||||
f 59/2/37 44/2/30 60/2/38
|
f 59/2/37 44/2/30 60/2/38
|
||||||
f 60/2/38 59/2/37 59/2/37
|
f 60/2/38 59/2/37 59/2/37
|
||||||
f 59/2/37 60/2/38 60/2/38
|
f 59/2/37 60/2/38 60/2/38
|
||||||
f 59/2/37 41/1/32 43/2/29
|
f 59/2/37 41/1/32 43/2/29
|
||||||
f 41/1/32 59/2/37 57/1/39
|
f 41/1/32 59/2/37 57/1/39
|
||||||
f 59/2/37 57/1/39 59/2/37
|
f 59/2/37 57/1/39 59/2/37
|
||||||
f 57/1/39 59/2/37 57/1/39
|
f 57/1/39 59/2/37 57/1/39
|
||||||
f 58/1/40 44/2/30 42/1/34
|
f 58/1/40 44/2/30 42/1/34
|
||||||
f 44/2/30 58/1/40 60/2/38
|
f 44/2/30 58/1/40 60/2/38
|
||||||
f 58/1/40 60/2/38 58/1/40
|
f 58/1/40 60/2/38 58/1/40
|
||||||
f 60/2/38 58/1/40 60/2/38
|
f 60/2/38 58/1/40 60/2/38
|
||||||
f 44/2/41 41/1/41 42/1/41
|
f 44/2/41 41/1/41 42/1/41
|
||||||
f 41/1/41 44/2/41 43/2/41
|
f 41/1/41 44/2/41 43/2/41
|
||||||
f 58/1/15 57/1/15 57/1/15
|
f 58/1/15 57/1/15 57/1/15
|
||||||
f 57/1/15 58/1/15 58/1/15
|
f 57/1/15 58/1/15 58/1/15
|
||||||
f 58/1/15 41/1/15 57/1/15
|
f 58/1/15 41/1/15 57/1/15
|
||||||
f 41/1/15 58/1/15 42/1/15
|
f 41/1/15 58/1/15 42/1/15
|
||||||
f 63/2/36 62/1/36 61/1/36
|
f 63/2/36 62/1/36 61/1/36
|
||||||
f 62/1/36 63/2/36 64/2/36
|
f 62/1/36 63/2/36 64/2/36
|
||||||
f 52/2/30 63/2/37 51/2/29
|
f 52/2/30 63/2/37 51/2/29
|
||||||
f 63/2/37 52/2/30 64/2/38
|
f 63/2/37 52/2/30 64/2/38
|
||||||
f 64/2/38 63/2/37 63/2/37
|
f 64/2/38 63/2/37 63/2/37
|
||||||
f 63/2/37 64/2/38 64/2/38
|
f 63/2/37 64/2/38 64/2/38
|
||||||
f 63/2/37 49/1/32 51/2/29
|
f 63/2/37 49/1/32 51/2/29
|
||||||
f 49/1/32 63/2/37 61/1/39
|
f 49/1/32 63/2/37 61/1/39
|
||||||
f 63/2/37 61/1/39 63/2/37
|
f 63/2/37 61/1/39 63/2/37
|
||||||
f 61/1/39 63/2/37 61/1/39
|
f 61/1/39 63/2/37 61/1/39
|
||||||
f 62/1/40 52/2/30 50/1/34
|
f 62/1/40 52/2/30 50/1/34
|
||||||
f 52/2/30 62/1/40 64/2/38
|
f 52/2/30 62/1/40 64/2/38
|
||||||
f 62/1/40 64/2/38 62/1/40
|
f 62/1/40 64/2/38 62/1/40
|
||||||
f 64/2/38 62/1/40 64/2/38
|
f 64/2/38 62/1/40 64/2/38
|
||||||
f 52/2/41 49/1/41 50/1/41
|
f 52/2/41 49/1/41 50/1/41
|
||||||
f 49/1/41 52/2/41 51/2/41
|
f 49/1/41 52/2/41 51/2/41
|
||||||
f 62/1/15 61/1/15 61/1/15
|
f 62/1/15 61/1/15 61/1/15
|
||||||
f 61/1/15 62/1/15 62/1/15
|
f 61/1/15 62/1/15 62/1/15
|
||||||
f 62/1/15 49/1/15 61/1/15
|
f 62/1/15 49/1/15 61/1/15
|
||||||
f 49/1/15 62/1/15 50/1/15
|
f 49/1/15 62/1/15 50/1/15
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,454 +1,454 @@
|
|||||||
# Created by Kenney (www.kenney.nl)
|
# Created by Kenney (www.kenney.nl)
|
||||||
|
|
||||||
mtllib railroad-rail-straight-bend.mtl
|
mtllib railroad-rail-straight-bend.mtl
|
||||||
|
|
||||||
g railroad-rail-straight-bend
|
g railroad-rail-straight-bend
|
||||||
|
|
||||||
v 0.3499999 0.2855045 0.9454412 1 1 1
|
v 0.3499999 0.2855045 0.9454412 1 1 1
|
||||||
v 0.25 0.2854948 0.9454471 1 1 1
|
v 0.25 0.2854948 0.9454471 1 1 1
|
||||||
v 0.3499889 0.370793 0.8932313 1 1 1
|
v 0.3499889 0.370793 0.8932313 1 1 1
|
||||||
v 0.2499886 0.3707833 0.8932372 1 1 1
|
v 0.2499886 0.3707833 0.8932372 1 1 1
|
||||||
v 0.3499999 0.1 2.861023E-06 1 1 1
|
v 0.3499999 0.1 2.861023E-06 1 1 1
|
||||||
v 0.3499942 0.1731339 0.4622263 1 1 1
|
v 0.3499942 0.1731339 0.4622263 1 1 1
|
||||||
v 0.25 0.1 2.861023E-06 1 1 1
|
v 0.25 0.1 2.861023E-06 1 1 1
|
||||||
v 0.2499943 0.1731284 0.4622279 1 1 1
|
v 0.2499943 0.1731284 0.4622279 1 1 1
|
||||||
v 0.3499999 0 3.099442E-06 1 1 1
|
v 0.3499999 0 3.099442E-06 1 1 1
|
||||||
v 0.3499999 0.07767773 0.4920279 1 1 1
|
v 0.3499999 0.07767773 0.4920279 1 1 1
|
||||||
v 0.25 0 3.099442E-06 1 1 1
|
v 0.25 0 3.099442E-06 1 1 1
|
||||||
v 0.25 0.07767224 0.4920295 1 1 1
|
v 0.25 0.07767224 0.4920295 1 1 1
|
||||||
v -0.25 0.2854466 0.9454765 1 1 1
|
v -0.25 0.2854466 0.9454765 1 1 1
|
||||||
v -0.3500004 0.2854371 0.9454824 1 1 1
|
v -0.3500004 0.2854371 0.9454824 1 1 1
|
||||||
v -0.2500114 0.3707352 0.8932667 1 1 1
|
v -0.2500114 0.3707352 0.8932667 1 1 1
|
||||||
v -0.3500109 0.3707256 0.8932726 1 1 1
|
v -0.3500109 0.3707256 0.8932726 1 1 1
|
||||||
v -0.25 0.1 2.861023E-06 1 1 1
|
v -0.25 0.1 2.861023E-06 1 1 1
|
||||||
v -0.2500057 0.1731009 0.4622365 1 1 1
|
v -0.2500057 0.1731009 0.4622365 1 1 1
|
||||||
v -0.3500004 0.1 2.861023E-06 1 1 1
|
v -0.3500004 0.1 2.861023E-06 1 1 1
|
||||||
v -0.3500061 0.1730955 0.4622382 1 1 1
|
v -0.3500061 0.1730955 0.4622382 1 1 1
|
||||||
v -0.25 0 3.099442E-06 1 1 1
|
v -0.25 0 3.099442E-06 1 1 1
|
||||||
v -0.25 0.07764494 0.4920381 1 1 1
|
v -0.25 0.07764494 0.4920381 1 1 1
|
||||||
v -0.3500004 0 3.099442E-06 1 1 1
|
v -0.3500004 0 3.099442E-06 1 1 1
|
||||||
v -0.3500004 0.07763946 0.4920398 1 1 1
|
v -0.3500004 0.07763946 0.4920398 1 1 1
|
||||||
v 0.3499999 0.9726683 1.661826 1 1 1
|
v 0.3499999 0.9726683 1.661826 1 1 1
|
||||||
v 0.25 0.9726559 1.661845 1 1 1
|
v 0.25 0.9726559 1.661845 1 1 1
|
||||||
v 0.349978 1.02854 1.578891 1 1 1
|
v 0.349978 1.02854 1.578891 1 1 1
|
||||||
v 0.2499776 1.028528 1.578909 1 1 1
|
v 0.2499776 1.028528 1.578909 1 1 1
|
||||||
v 0.3499832 0.6631117 1.270934 1 1 1
|
v 0.3499832 0.6631117 1.270934 1 1 1
|
||||||
v 0.2499833 0.6630995 1.270946 1 1 1
|
v 0.2499833 0.6630995 1.270946 1 1 1
|
||||||
v 0.3499999 0.5909731 1.340188 1 1 1
|
v 0.3499999 0.5909731 1.340188 1 1 1
|
||||||
v 0.25 0.590961 1.340199 1 1 1
|
v 0.25 0.590961 1.340199 1 1 1
|
||||||
v -0.25 0.9725939 1.661937 1 1 1
|
v -0.25 0.9725939 1.661937 1 1 1
|
||||||
v -0.3500004 0.9725815 1.661955 1 1 1
|
v -0.3500004 0.9725815 1.661955 1 1 1
|
||||||
v -0.2500219 1.028466 1.579001 1 1 1
|
v -0.2500219 1.028466 1.579001 1 1 1
|
||||||
v -0.3500223 1.028453 1.579019 1 1 1
|
v -0.3500223 1.028453 1.579019 1 1 1
|
||||||
v -0.2500172 0.6630392 1.271004 1 1 1
|
v -0.2500172 0.6630392 1.271004 1 1 1
|
||||||
v -0.3500166 0.663027 1.271016 1 1 1
|
v -0.3500166 0.663027 1.271016 1 1 1
|
||||||
v -0.25 0.5909007 1.340257 1 1 1
|
v -0.25 0.5909007 1.340257 1 1 1
|
||||||
v -0.3500004 0.5908885 1.340269 1 1 1
|
v -0.3500004 0.5908885 1.340269 1 1 1
|
||||||
v 0.3499999 1.902707 1.996766 1 1 1
|
v 0.3499999 1.902707 1.996766 1 1 1
|
||||||
v 0.25 1.902705 1.996798 1 1 1
|
v 0.25 1.902705 1.996798 1 1 1
|
||||||
v 0.3499684 1.909084 1.89697 1 1 1
|
v 0.3499684 1.909084 1.89697 1 1 1
|
||||||
v 0.2499685 1.909082 1.897001 1 1 1
|
v 0.2499685 1.909082 1.897001 1 1 1
|
||||||
v 0.3499722 1.450577 1.797044 1 1 1
|
v 0.3499722 1.450577 1.797044 1 1 1
|
||||||
v 0.2499723 1.450567 1.79707 1 1 1
|
v 0.2499723 1.450567 1.79707 1 1 1
|
||||||
v 0.3499999 1.415872 1.890829 1 1 1
|
v 0.3499999 1.415872 1.890829 1 1 1
|
||||||
v 0.25 1.415863 1.890855 1 1 1
|
v 0.25 1.415863 1.890855 1 1 1
|
||||||
v -0.25 1.902695 1.996955 1 1 1
|
v -0.25 1.902695 1.996955 1 1 1
|
||||||
v -0.3500004 1.902693 1.996986 1 1 1
|
v -0.3500004 1.902693 1.996986 1 1 1
|
||||||
v -0.2500315 1.909072 1.897158 1 1 1
|
v -0.2500315 1.909072 1.897158 1 1 1
|
||||||
v -0.3500319 1.90907 1.897189 1 1 1
|
v -0.3500319 1.90907 1.897189 1 1 1
|
||||||
v -0.2500277 1.450519 1.7972 1 1 1
|
v -0.2500277 1.450519 1.7972 1 1 1
|
||||||
v -0.350028 1.450509 1.797226 1 1 1
|
v -0.350028 1.450509 1.797226 1 1 1
|
||||||
v -0.25 1.415814 1.890985 1 1 1
|
v -0.25 1.415814 1.890985 1 1 1
|
||||||
v -0.3500004 1.415805 1.891011 1 1 1
|
v -0.3500004 1.415805 1.891011 1 1 1
|
||||||
v 0.3499999 1.999997 2 1 1 1
|
v 0.3499999 1.999997 2 1 1 1
|
||||||
v 0.25 1.999997 2 1 1 1
|
v 0.25 1.999997 2 1 1 1
|
||||||
v 0.3499999 1.999997 1.9 1 1 1
|
v 0.3499999 1.999997 1.9 1 1 1
|
||||||
v 0.25 1.999997 1.9 1 1 1
|
v 0.25 1.999997 1.9 1 1 1
|
||||||
v -0.25 1.999997 2 1 1 1
|
v -0.25 1.999997 2 1 1 1
|
||||||
v -0.3500004 1.999997 2 1 1 1
|
v -0.3500004 1.999997 2 1 1 1
|
||||||
v -0.25 1.999997 1.9 1 1 1
|
v -0.25 1.999997 1.9 1 1 1
|
||||||
v -0.3500004 1.999997 1.9 1 1 1
|
v -0.3500004 1.999997 1.9 1 1 1
|
||||||
|
|
||||||
vn 1.818989E-12 0.5220981 0.8528854
|
vn 1.818989E-12 0.5220981 0.8528854
|
||||||
vn 0.7071068 0.7071068 -1.459836E-06
|
vn 0.7071068 0.7071068 -1.459836E-06
|
||||||
vn 0.7070663 0.6750152 -0.2107409
|
vn 0.7070663 0.6750152 -0.2107409
|
||||||
vn -0.7071068 0.7071068 -1.459836E-06
|
vn -0.7071068 0.7071068 -1.459836E-06
|
||||||
vn -0.7071472 0.6749379 -0.2107168
|
vn -0.7071472 0.6749379 -0.2107168
|
||||||
vn 0.7070269 0.6031491 -0.3692208
|
vn 0.7070269 0.6031491 -0.3692208
|
||||||
vn -0.7071866 0.6030129 -0.3691374
|
vn -0.7071866 0.6030129 -0.3691374
|
||||||
vn 1 3.571274E-10 -7.372964E-16
|
vn 1 3.571274E-10 -7.372964E-16
|
||||||
vn 1 5.463722E-05 -1.705784E-05
|
vn 1 5.463722E-05 -1.705784E-05
|
||||||
vn 1 9.633944E-05 -5.897469E-05
|
vn 1 9.633944E-05 -5.897469E-05
|
||||||
vn -1 -3.571274E-10 7.372964E-16
|
vn -1 -3.571274E-10 7.372964E-16
|
||||||
vn -1 -5.463722E-05 1.705784E-05
|
vn -1 -5.463722E-05 1.705784E-05
|
||||||
vn -1 -9.633944E-05 5.897469E-05
|
vn -1 -9.633944E-05 5.897469E-05
|
||||||
vn 0 -2.064519E-06 -1
|
vn 0 -2.064519E-06 -1
|
||||||
vn 0.0001129571 -0.8528854 0.5220981
|
vn 0.0001129571 -0.8528854 0.5220981
|
||||||
vn 5.723807E-05 -0.954561 0.2980156
|
vn 5.723807E-05 -0.954561 0.2980156
|
||||||
vn 3.571274E-10 -1 2.064519E-06
|
vn 3.571274E-10 -1 2.064519E-06
|
||||||
vn 1.455192E-11 0.8293576 0.5587182
|
vn 1.455192E-11 0.8293576 0.5587182
|
||||||
vn 0.7069883 0.5101821 -0.4897772
|
vn 0.7069883 0.5101821 -0.4897772
|
||||||
vn -0.7072252 0.5100113 -0.4896131
|
vn -0.7072252 0.5100113 -0.4896131
|
||||||
vn 0.7069498 0.3951611 -0.5865746
|
vn 0.7069498 0.3951611 -0.5865746
|
||||||
vn -0.7072637 0.3949857 -0.5863142
|
vn -0.7072637 0.3949857 -0.5863142
|
||||||
vn 1 0.0001208208 -0.0001159886
|
vn 1 0.0001208208 -0.0001159886
|
||||||
vn 1 0.0001240229 -0.0001840989
|
vn 1 0.0001240229 -0.0001840989
|
||||||
vn -1 -0.0001208208 0.0001159886
|
vn -1 -0.0001208208 0.0001159886
|
||||||
vn -1 -0.0001240229 0.0001840989
|
vn -1 -0.0001240229 0.0001840989
|
||||||
vn -1.818989E-12 -0.5220981 -0.8528854
|
vn -1.818989E-12 -0.5220981 -0.8528854
|
||||||
vn 0.0002219777 -0.5587181 0.8293576
|
vn 0.0002219777 -0.5587181 0.8293576
|
||||||
vn 0.0001674844 -0.7213856 0.6925336
|
vn 0.0001674844 -0.7213856 0.6925336
|
||||||
vn 1.455192E-11 0.9979643 0.0637747
|
vn 1.455192E-11 0.9979643 0.0637747
|
||||||
vn 0.7069106 0.245465 -0.6633433
|
vn 0.7069106 0.245465 -0.6633433
|
||||||
vn -0.7073029 0.2453289 -0.6629753
|
vn -0.7073029 0.2453289 -0.6629753
|
||||||
vn 0.7068844 0.04510975 -0.7058891
|
vn 0.7068844 0.04510975 -0.7058891
|
||||||
vn -0.707329 0.04508126 -0.7054455
|
vn -0.707329 0.04508126 -0.7054455
|
||||||
vn 0.9999999 9.628916E-05 -0.0002602113
|
vn 0.9999999 9.628916E-05 -0.0002602113
|
||||||
vn 0.9999999 2.004761E-05 -0.000313711
|
vn 0.9999999 2.004761E-05 -0.000313711
|
||||||
vn -0.9999999 -9.628916E-05 0.0002602113
|
vn -0.9999999 -9.628916E-05 0.0002602113
|
||||||
vn -0.9999999 -2.004761E-05 0.000313711
|
vn -0.9999999 -2.004761E-05 0.000313711
|
||||||
vn -1.455192E-11 -0.8293576 -0.5587182
|
vn -1.455192E-11 -0.8293576 -0.5587182
|
||||||
vn 0.0003143509 -0.0637747 0.9979643
|
vn 0.0003143509 -0.0637747 0.9979643
|
||||||
vn 0.0002774554 -0.3470438 0.9378489
|
vn 0.0002774554 -0.3470438 0.9378489
|
||||||
vn 0 0.9999999 2.384186E-06
|
vn 0 0.9999999 2.384186E-06
|
||||||
vn 0.7071068 1.66893E-06 -0.7071067
|
vn 0.7071068 1.66893E-06 -0.7071067
|
||||||
vn -0.7071068 1.66893E-06 -0.7071067
|
vn -0.7071068 1.66893E-06 -0.7071067
|
||||||
vn 1 2.575717E-14 -1.136924E-08
|
vn 1 2.575717E-14 -1.136924E-08
|
||||||
vn -1 -2.575717E-14 1.136924E-08
|
vn -1 -2.575717E-14 1.136924E-08
|
||||||
vn -1.455192E-11 -0.9979643 -0.0637747
|
vn -1.455192E-11 -0.9979643 -0.0637747
|
||||||
vn 1.136924E-08 -2.384186E-06 0.9999999
|
vn 1.136924E-08 -2.384186E-06 0.9999999
|
||||||
|
|
||||||
vt 0.96875 0.025
|
vt 0.96875 0.025
|
||||||
vt 0.96875 0.225
|
vt 0.96875 0.225
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/16 1/1/15
|
f 2/1/15 10/1/16 1/1/15
|
||||||
f 10/1/16 2/1/15 12/1/16
|
f 10/1/16 2/1/15 12/1/16
|
||||||
f 12/1/16 9/1/17 10/1/16
|
f 12/1/16 9/1/17 10/1/16
|
||||||
f 9/1/17 12/1/16 11/1/17
|
f 9/1/17 12/1/16 11/1/17
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/16 13/1/15
|
f 14/1/15 22/1/16 13/1/15
|
||||||
f 22/1/16 14/1/15 24/1/16
|
f 22/1/16 14/1/15 24/1/16
|
||||||
f 24/1/16 21/1/17 22/1/16
|
f 24/1/16 21/1/17 22/1/16
|
||||||
f 21/1/17 24/1/16 23/1/17
|
f 21/1/17 24/1/16 23/1/17
|
||||||
f 27/2/18 26/1/18 25/1/18
|
f 27/2/18 26/1/18 25/1/18
|
||||||
f 26/1/18 27/2/18 28/2/18
|
f 26/1/18 27/2/18 28/2/18
|
||||||
f 4/2/7 29/2/19 3/2/6
|
f 4/2/7 29/2/19 3/2/6
|
||||||
f 29/2/19 4/2/7 30/2/20
|
f 29/2/19 4/2/7 30/2/20
|
||||||
f 30/2/20 27/2/21 29/2/19
|
f 30/2/20 27/2/21 29/2/19
|
||||||
f 27/2/21 30/2/20 28/2/22
|
f 27/2/21 30/2/20 28/2/22
|
||||||
f 29/2/19 1/1/10 3/2/6
|
f 29/2/19 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/19 31/1/23
|
f 1/1/10 29/2/19 31/1/23
|
||||||
f 27/2/21 31/1/23 29/2/19
|
f 27/2/21 31/1/23 29/2/19
|
||||||
f 31/1/23 27/2/21 25/1/24
|
f 31/1/23 27/2/21 25/1/24
|
||||||
f 32/1/25 4/2/7 2/1/13
|
f 32/1/25 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/25 30/2/20
|
f 4/2/7 32/1/25 30/2/20
|
||||||
f 26/1/26 30/2/20 32/1/25
|
f 26/1/26 30/2/20 32/1/25
|
||||||
f 30/2/20 26/1/26 28/2/22
|
f 30/2/20 26/1/26 28/2/22
|
||||||
f 4/2/27 1/1/27 2/1/27
|
f 4/2/27 1/1/27 2/1/27
|
||||||
f 1/1/27 4/2/27 3/2/27
|
f 1/1/27 4/2/27 3/2/27
|
||||||
f 26/1/28 31/1/29 25/1/28
|
f 26/1/28 31/1/29 25/1/28
|
||||||
f 31/1/29 26/1/28 32/1/29
|
f 31/1/29 26/1/28 32/1/29
|
||||||
f 32/1/29 1/1/15 31/1/29
|
f 32/1/29 1/1/15 31/1/29
|
||||||
f 1/1/15 32/1/29 2/1/15
|
f 1/1/15 32/1/29 2/1/15
|
||||||
f 35/2/18 34/1/18 33/1/18
|
f 35/2/18 34/1/18 33/1/18
|
||||||
f 34/1/18 35/2/18 36/2/18
|
f 34/1/18 35/2/18 36/2/18
|
||||||
f 16/2/7 37/2/19 15/2/6
|
f 16/2/7 37/2/19 15/2/6
|
||||||
f 37/2/19 16/2/7 38/2/20
|
f 37/2/19 16/2/7 38/2/20
|
||||||
f 38/2/20 35/2/21 37/2/19
|
f 38/2/20 35/2/21 37/2/19
|
||||||
f 35/2/21 38/2/20 36/2/22
|
f 35/2/21 38/2/20 36/2/22
|
||||||
f 37/2/19 13/1/10 15/2/6
|
f 37/2/19 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/19 39/1/23
|
f 13/1/10 37/2/19 39/1/23
|
||||||
f 35/2/21 39/1/23 37/2/19
|
f 35/2/21 39/1/23 37/2/19
|
||||||
f 39/1/23 35/2/21 33/1/24
|
f 39/1/23 35/2/21 33/1/24
|
||||||
f 40/1/25 16/2/7 14/1/13
|
f 40/1/25 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/25 38/2/20
|
f 16/2/7 40/1/25 38/2/20
|
||||||
f 34/1/26 38/2/20 40/1/25
|
f 34/1/26 38/2/20 40/1/25
|
||||||
f 38/2/20 34/1/26 36/2/22
|
f 38/2/20 34/1/26 36/2/22
|
||||||
f 16/2/27 13/1/27 14/1/27
|
f 16/2/27 13/1/27 14/1/27
|
||||||
f 13/1/27 16/2/27 15/2/27
|
f 13/1/27 16/2/27 15/2/27
|
||||||
f 34/1/28 39/1/29 33/1/28
|
f 34/1/28 39/1/29 33/1/28
|
||||||
f 39/1/29 34/1/28 40/1/29
|
f 39/1/29 34/1/28 40/1/29
|
||||||
f 40/1/29 13/1/15 39/1/29
|
f 40/1/29 13/1/15 39/1/29
|
||||||
f 13/1/15 40/1/29 14/1/15
|
f 13/1/15 40/1/29 14/1/15
|
||||||
f 43/2/30 42/1/30 41/1/30
|
f 43/2/30 42/1/30 41/1/30
|
||||||
f 42/1/30 43/2/30 44/2/30
|
f 42/1/30 43/2/30 44/2/30
|
||||||
f 28/2/22 45/2/31 27/2/21
|
f 28/2/22 45/2/31 27/2/21
|
||||||
f 45/2/31 28/2/22 46/2/32
|
f 45/2/31 28/2/22 46/2/32
|
||||||
f 46/2/32 43/2/33 45/2/31
|
f 46/2/32 43/2/33 45/2/31
|
||||||
f 43/2/33 46/2/32 44/2/34
|
f 43/2/33 46/2/32 44/2/34
|
||||||
f 45/2/31 25/1/24 27/2/21
|
f 45/2/31 25/1/24 27/2/21
|
||||||
f 25/1/24 45/2/31 47/1/35
|
f 25/1/24 45/2/31 47/1/35
|
||||||
f 43/2/33 47/1/35 45/2/31
|
f 43/2/33 47/1/35 45/2/31
|
||||||
f 47/1/35 43/2/33 41/1/36
|
f 47/1/35 43/2/33 41/1/36
|
||||||
f 48/1/37 28/2/22 26/1/26
|
f 48/1/37 28/2/22 26/1/26
|
||||||
f 28/2/22 48/1/37 46/2/32
|
f 28/2/22 48/1/37 46/2/32
|
||||||
f 42/1/38 46/2/32 48/1/37
|
f 42/1/38 46/2/32 48/1/37
|
||||||
f 46/2/32 42/1/38 44/2/34
|
f 46/2/32 42/1/38 44/2/34
|
||||||
f 28/2/39 25/1/39 26/1/39
|
f 28/2/39 25/1/39 26/1/39
|
||||||
f 25/1/39 28/2/39 27/2/39
|
f 25/1/39 28/2/39 27/2/39
|
||||||
f 42/1/40 47/1/41 41/1/40
|
f 42/1/40 47/1/41 41/1/40
|
||||||
f 47/1/41 42/1/40 48/1/41
|
f 47/1/41 42/1/40 48/1/41
|
||||||
f 48/1/41 25/1/28 47/1/41
|
f 48/1/41 25/1/28 47/1/41
|
||||||
f 25/1/28 48/1/41 26/1/28
|
f 25/1/28 48/1/41 26/1/28
|
||||||
f 51/2/30 50/1/30 49/1/30
|
f 51/2/30 50/1/30 49/1/30
|
||||||
f 50/1/30 51/2/30 52/2/30
|
f 50/1/30 51/2/30 52/2/30
|
||||||
f 36/2/22 53/2/31 35/2/21
|
f 36/2/22 53/2/31 35/2/21
|
||||||
f 53/2/31 36/2/22 54/2/32
|
f 53/2/31 36/2/22 54/2/32
|
||||||
f 54/2/32 51/2/33 53/2/31
|
f 54/2/32 51/2/33 53/2/31
|
||||||
f 51/2/33 54/2/32 52/2/34
|
f 51/2/33 54/2/32 52/2/34
|
||||||
f 53/2/31 33/1/24 35/2/21
|
f 53/2/31 33/1/24 35/2/21
|
||||||
f 33/1/24 53/2/31 55/1/35
|
f 33/1/24 53/2/31 55/1/35
|
||||||
f 51/2/33 55/1/35 53/2/31
|
f 51/2/33 55/1/35 53/2/31
|
||||||
f 55/1/35 51/2/33 49/1/36
|
f 55/1/35 51/2/33 49/1/36
|
||||||
f 56/1/37 36/2/22 34/1/26
|
f 56/1/37 36/2/22 34/1/26
|
||||||
f 36/2/22 56/1/37 54/2/32
|
f 36/2/22 56/1/37 54/2/32
|
||||||
f 50/1/38 54/2/32 56/1/37
|
f 50/1/38 54/2/32 56/1/37
|
||||||
f 54/2/32 50/1/38 52/2/34
|
f 54/2/32 50/1/38 52/2/34
|
||||||
f 36/2/39 33/1/39 34/1/39
|
f 36/2/39 33/1/39 34/1/39
|
||||||
f 33/1/39 36/2/39 35/2/39
|
f 33/1/39 36/2/39 35/2/39
|
||||||
f 50/1/40 55/1/41 49/1/40
|
f 50/1/40 55/1/41 49/1/40
|
||||||
f 55/1/41 50/1/40 56/1/41
|
f 55/1/41 50/1/40 56/1/41
|
||||||
f 56/1/41 33/1/28 55/1/41
|
f 56/1/41 33/1/28 55/1/41
|
||||||
f 33/1/28 56/1/41 34/1/28
|
f 33/1/28 56/1/41 34/1/28
|
||||||
f 59/2/42 58/1/42 57/1/42
|
f 59/2/42 58/1/42 57/1/42
|
||||||
f 58/1/42 59/2/42 60/2/42
|
f 58/1/42 59/2/42 60/2/42
|
||||||
f 44/2/34 59/2/43 43/2/33
|
f 44/2/34 59/2/43 43/2/33
|
||||||
f 59/2/43 44/2/34 60/2/44
|
f 59/2/43 44/2/34 60/2/44
|
||||||
f 60/2/44 59/2/43 59/2/43
|
f 60/2/44 59/2/43 59/2/43
|
||||||
f 59/2/43 60/2/44 60/2/44
|
f 59/2/43 60/2/44 60/2/44
|
||||||
f 59/2/43 41/1/36 43/2/33
|
f 59/2/43 41/1/36 43/2/33
|
||||||
f 41/1/36 59/2/43 57/1/45
|
f 41/1/36 59/2/43 57/1/45
|
||||||
f 59/2/43 57/1/45 59/2/43
|
f 59/2/43 57/1/45 59/2/43
|
||||||
f 57/1/45 59/2/43 57/1/45
|
f 57/1/45 59/2/43 57/1/45
|
||||||
f 58/1/46 44/2/34 42/1/38
|
f 58/1/46 44/2/34 42/1/38
|
||||||
f 44/2/34 58/1/46 60/2/44
|
f 44/2/34 58/1/46 60/2/44
|
||||||
f 58/1/46 60/2/44 58/1/46
|
f 58/1/46 60/2/44 58/1/46
|
||||||
f 60/2/44 58/1/46 60/2/44
|
f 60/2/44 58/1/46 60/2/44
|
||||||
f 44/2/47 41/1/47 42/1/47
|
f 44/2/47 41/1/47 42/1/47
|
||||||
f 41/1/47 44/2/47 43/2/47
|
f 41/1/47 44/2/47 43/2/47
|
||||||
f 58/1/48 57/1/48 57/1/48
|
f 58/1/48 57/1/48 57/1/48
|
||||||
f 57/1/48 58/1/48 58/1/48
|
f 57/1/48 58/1/48 58/1/48
|
||||||
f 58/1/48 41/1/40 57/1/48
|
f 58/1/48 41/1/40 57/1/48
|
||||||
f 41/1/40 58/1/48 42/1/40
|
f 41/1/40 58/1/48 42/1/40
|
||||||
f 63/2/42 62/1/42 61/1/42
|
f 63/2/42 62/1/42 61/1/42
|
||||||
f 62/1/42 63/2/42 64/2/42
|
f 62/1/42 63/2/42 64/2/42
|
||||||
f 52/2/34 63/2/43 51/2/33
|
f 52/2/34 63/2/43 51/2/33
|
||||||
f 63/2/43 52/2/34 64/2/44
|
f 63/2/43 52/2/34 64/2/44
|
||||||
f 64/2/44 63/2/43 63/2/43
|
f 64/2/44 63/2/43 63/2/43
|
||||||
f 63/2/43 64/2/44 64/2/44
|
f 63/2/43 64/2/44 64/2/44
|
||||||
f 63/2/43 49/1/36 51/2/33
|
f 63/2/43 49/1/36 51/2/33
|
||||||
f 49/1/36 63/2/43 61/1/45
|
f 49/1/36 63/2/43 61/1/45
|
||||||
f 63/2/43 61/1/45 63/2/43
|
f 63/2/43 61/1/45 63/2/43
|
||||||
f 61/1/45 63/2/43 61/1/45
|
f 61/1/45 63/2/43 61/1/45
|
||||||
f 62/1/46 52/2/34 50/1/38
|
f 62/1/46 52/2/34 50/1/38
|
||||||
f 52/2/34 62/1/46 64/2/44
|
f 52/2/34 62/1/46 64/2/44
|
||||||
f 62/1/46 64/2/44 62/1/46
|
f 62/1/46 64/2/44 62/1/46
|
||||||
f 64/2/44 62/1/46 64/2/44
|
f 64/2/44 62/1/46 64/2/44
|
||||||
f 52/2/47 49/1/47 50/1/47
|
f 52/2/47 49/1/47 50/1/47
|
||||||
f 49/1/47 52/2/47 51/2/47
|
f 49/1/47 52/2/47 51/2/47
|
||||||
f 62/1/48 61/1/48 61/1/48
|
f 62/1/48 61/1/48 61/1/48
|
||||||
f 61/1/48 62/1/48 62/1/48
|
f 61/1/48 62/1/48 62/1/48
|
||||||
f 62/1/48 49/1/40 61/1/48
|
f 62/1/48 49/1/40 61/1/48
|
||||||
f 49/1/40 62/1/48 50/1/40
|
f 49/1/40 62/1/48 50/1/40
|
||||||
|
|
||||||
g railroad-rail-straight-bend
|
g railroad-rail-straight-bend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usemtl colormap
|
usemtl colormap
|
||||||
|
|
||||||
f 3/2/1 2/1/1 1/1/1
|
f 3/2/1 2/1/1 1/1/1
|
||||||
f 2/1/1 3/2/1 4/2/1
|
f 2/1/1 3/2/1 4/2/1
|
||||||
f 7/2/4 6/2/3 5/2/2
|
f 7/2/4 6/2/3 5/2/2
|
||||||
f 6/2/3 7/2/4 8/2/5
|
f 6/2/3 7/2/4 8/2/5
|
||||||
f 8/2/5 3/2/6 6/2/3
|
f 8/2/5 3/2/6 6/2/3
|
||||||
f 3/2/6 8/2/5 4/2/7
|
f 3/2/6 8/2/5 4/2/7
|
||||||
f 6/2/3 9/1/8 5/2/2
|
f 6/2/3 9/1/8 5/2/2
|
||||||
f 9/1/8 6/2/3 10/1/9
|
f 9/1/8 6/2/3 10/1/9
|
||||||
f 3/2/6 10/1/9 6/2/3
|
f 3/2/6 10/1/9 6/2/3
|
||||||
f 10/1/9 3/2/6 1/1/10
|
f 10/1/9 3/2/6 1/1/10
|
||||||
f 12/1/12 7/2/4 11/1/11
|
f 12/1/12 7/2/4 11/1/11
|
||||||
f 7/2/4 12/1/12 8/2/5
|
f 7/2/4 12/1/12 8/2/5
|
||||||
f 2/1/13 8/2/5 12/1/12
|
f 2/1/13 8/2/5 12/1/12
|
||||||
f 8/2/5 2/1/13 4/2/7
|
f 8/2/5 2/1/13 4/2/7
|
||||||
f 7/2/14 9/1/14 11/1/14
|
f 7/2/14 9/1/14 11/1/14
|
||||||
f 9/1/14 7/2/14 5/2/14
|
f 9/1/14 7/2/14 5/2/14
|
||||||
f 2/1/15 10/1/16 1/1/15
|
f 2/1/15 10/1/16 1/1/15
|
||||||
f 10/1/16 2/1/15 12/1/16
|
f 10/1/16 2/1/15 12/1/16
|
||||||
f 12/1/16 9/1/17 10/1/16
|
f 12/1/16 9/1/17 10/1/16
|
||||||
f 9/1/17 12/1/16 11/1/17
|
f 9/1/17 12/1/16 11/1/17
|
||||||
f 15/2/1 14/1/1 13/1/1
|
f 15/2/1 14/1/1 13/1/1
|
||||||
f 14/1/1 15/2/1 16/2/1
|
f 14/1/1 15/2/1 16/2/1
|
||||||
f 19/2/4 18/2/3 17/2/2
|
f 19/2/4 18/2/3 17/2/2
|
||||||
f 18/2/3 19/2/4 20/2/5
|
f 18/2/3 19/2/4 20/2/5
|
||||||
f 20/2/5 15/2/6 18/2/3
|
f 20/2/5 15/2/6 18/2/3
|
||||||
f 15/2/6 20/2/5 16/2/7
|
f 15/2/6 20/2/5 16/2/7
|
||||||
f 18/2/3 21/1/8 17/2/2
|
f 18/2/3 21/1/8 17/2/2
|
||||||
f 21/1/8 18/2/3 22/1/9
|
f 21/1/8 18/2/3 22/1/9
|
||||||
f 15/2/6 22/1/9 18/2/3
|
f 15/2/6 22/1/9 18/2/3
|
||||||
f 22/1/9 15/2/6 13/1/10
|
f 22/1/9 15/2/6 13/1/10
|
||||||
f 24/1/12 19/2/4 23/1/11
|
f 24/1/12 19/2/4 23/1/11
|
||||||
f 19/2/4 24/1/12 20/2/5
|
f 19/2/4 24/1/12 20/2/5
|
||||||
f 14/1/13 20/2/5 24/1/12
|
f 14/1/13 20/2/5 24/1/12
|
||||||
f 20/2/5 14/1/13 16/2/7
|
f 20/2/5 14/1/13 16/2/7
|
||||||
f 19/2/14 21/1/14 23/1/14
|
f 19/2/14 21/1/14 23/1/14
|
||||||
f 21/1/14 19/2/14 17/2/14
|
f 21/1/14 19/2/14 17/2/14
|
||||||
f 14/1/15 22/1/16 13/1/15
|
f 14/1/15 22/1/16 13/1/15
|
||||||
f 22/1/16 14/1/15 24/1/16
|
f 22/1/16 14/1/15 24/1/16
|
||||||
f 24/1/16 21/1/17 22/1/16
|
f 24/1/16 21/1/17 22/1/16
|
||||||
f 21/1/17 24/1/16 23/1/17
|
f 21/1/17 24/1/16 23/1/17
|
||||||
f 27/2/18 26/1/18 25/1/18
|
f 27/2/18 26/1/18 25/1/18
|
||||||
f 26/1/18 27/2/18 28/2/18
|
f 26/1/18 27/2/18 28/2/18
|
||||||
f 4/2/7 29/2/19 3/2/6
|
f 4/2/7 29/2/19 3/2/6
|
||||||
f 29/2/19 4/2/7 30/2/20
|
f 29/2/19 4/2/7 30/2/20
|
||||||
f 30/2/20 27/2/21 29/2/19
|
f 30/2/20 27/2/21 29/2/19
|
||||||
f 27/2/21 30/2/20 28/2/22
|
f 27/2/21 30/2/20 28/2/22
|
||||||
f 29/2/19 1/1/10 3/2/6
|
f 29/2/19 1/1/10 3/2/6
|
||||||
f 1/1/10 29/2/19 31/1/23
|
f 1/1/10 29/2/19 31/1/23
|
||||||
f 27/2/21 31/1/23 29/2/19
|
f 27/2/21 31/1/23 29/2/19
|
||||||
f 31/1/23 27/2/21 25/1/24
|
f 31/1/23 27/2/21 25/1/24
|
||||||
f 32/1/25 4/2/7 2/1/13
|
f 32/1/25 4/2/7 2/1/13
|
||||||
f 4/2/7 32/1/25 30/2/20
|
f 4/2/7 32/1/25 30/2/20
|
||||||
f 26/1/26 30/2/20 32/1/25
|
f 26/1/26 30/2/20 32/1/25
|
||||||
f 30/2/20 26/1/26 28/2/22
|
f 30/2/20 26/1/26 28/2/22
|
||||||
f 4/2/27 1/1/27 2/1/27
|
f 4/2/27 1/1/27 2/1/27
|
||||||
f 1/1/27 4/2/27 3/2/27
|
f 1/1/27 4/2/27 3/2/27
|
||||||
f 26/1/28 31/1/29 25/1/28
|
f 26/1/28 31/1/29 25/1/28
|
||||||
f 31/1/29 26/1/28 32/1/29
|
f 31/1/29 26/1/28 32/1/29
|
||||||
f 32/1/29 1/1/15 31/1/29
|
f 32/1/29 1/1/15 31/1/29
|
||||||
f 1/1/15 32/1/29 2/1/15
|
f 1/1/15 32/1/29 2/1/15
|
||||||
f 35/2/18 34/1/18 33/1/18
|
f 35/2/18 34/1/18 33/1/18
|
||||||
f 34/1/18 35/2/18 36/2/18
|
f 34/1/18 35/2/18 36/2/18
|
||||||
f 16/2/7 37/2/19 15/2/6
|
f 16/2/7 37/2/19 15/2/6
|
||||||
f 37/2/19 16/2/7 38/2/20
|
f 37/2/19 16/2/7 38/2/20
|
||||||
f 38/2/20 35/2/21 37/2/19
|
f 38/2/20 35/2/21 37/2/19
|
||||||
f 35/2/21 38/2/20 36/2/22
|
f 35/2/21 38/2/20 36/2/22
|
||||||
f 37/2/19 13/1/10 15/2/6
|
f 37/2/19 13/1/10 15/2/6
|
||||||
f 13/1/10 37/2/19 39/1/23
|
f 13/1/10 37/2/19 39/1/23
|
||||||
f 35/2/21 39/1/23 37/2/19
|
f 35/2/21 39/1/23 37/2/19
|
||||||
f 39/1/23 35/2/21 33/1/24
|
f 39/1/23 35/2/21 33/1/24
|
||||||
f 40/1/25 16/2/7 14/1/13
|
f 40/1/25 16/2/7 14/1/13
|
||||||
f 16/2/7 40/1/25 38/2/20
|
f 16/2/7 40/1/25 38/2/20
|
||||||
f 34/1/26 38/2/20 40/1/25
|
f 34/1/26 38/2/20 40/1/25
|
||||||
f 38/2/20 34/1/26 36/2/22
|
f 38/2/20 34/1/26 36/2/22
|
||||||
f 16/2/27 13/1/27 14/1/27
|
f 16/2/27 13/1/27 14/1/27
|
||||||
f 13/1/27 16/2/27 15/2/27
|
f 13/1/27 16/2/27 15/2/27
|
||||||
f 34/1/28 39/1/29 33/1/28
|
f 34/1/28 39/1/29 33/1/28
|
||||||
f 39/1/29 34/1/28 40/1/29
|
f 39/1/29 34/1/28 40/1/29
|
||||||
f 40/1/29 13/1/15 39/1/29
|
f 40/1/29 13/1/15 39/1/29
|
||||||
f 13/1/15 40/1/29 14/1/15
|
f 13/1/15 40/1/29 14/1/15
|
||||||
f 43/2/30 42/1/30 41/1/30
|
f 43/2/30 42/1/30 41/1/30
|
||||||
f 42/1/30 43/2/30 44/2/30
|
f 42/1/30 43/2/30 44/2/30
|
||||||
f 28/2/22 45/2/31 27/2/21
|
f 28/2/22 45/2/31 27/2/21
|
||||||
f 45/2/31 28/2/22 46/2/32
|
f 45/2/31 28/2/22 46/2/32
|
||||||
f 46/2/32 43/2/33 45/2/31
|
f 46/2/32 43/2/33 45/2/31
|
||||||
f 43/2/33 46/2/32 44/2/34
|
f 43/2/33 46/2/32 44/2/34
|
||||||
f 45/2/31 25/1/24 27/2/21
|
f 45/2/31 25/1/24 27/2/21
|
||||||
f 25/1/24 45/2/31 47/1/35
|
f 25/1/24 45/2/31 47/1/35
|
||||||
f 43/2/33 47/1/35 45/2/31
|
f 43/2/33 47/1/35 45/2/31
|
||||||
f 47/1/35 43/2/33 41/1/36
|
f 47/1/35 43/2/33 41/1/36
|
||||||
f 48/1/37 28/2/22 26/1/26
|
f 48/1/37 28/2/22 26/1/26
|
||||||
f 28/2/22 48/1/37 46/2/32
|
f 28/2/22 48/1/37 46/2/32
|
||||||
f 42/1/38 46/2/32 48/1/37
|
f 42/1/38 46/2/32 48/1/37
|
||||||
f 46/2/32 42/1/38 44/2/34
|
f 46/2/32 42/1/38 44/2/34
|
||||||
f 28/2/39 25/1/39 26/1/39
|
f 28/2/39 25/1/39 26/1/39
|
||||||
f 25/1/39 28/2/39 27/2/39
|
f 25/1/39 28/2/39 27/2/39
|
||||||
f 42/1/40 47/1/41 41/1/40
|
f 42/1/40 47/1/41 41/1/40
|
||||||
f 47/1/41 42/1/40 48/1/41
|
f 47/1/41 42/1/40 48/1/41
|
||||||
f 48/1/41 25/1/28 47/1/41
|
f 48/1/41 25/1/28 47/1/41
|
||||||
f 25/1/28 48/1/41 26/1/28
|
f 25/1/28 48/1/41 26/1/28
|
||||||
f 51/2/30 50/1/30 49/1/30
|
f 51/2/30 50/1/30 49/1/30
|
||||||
f 50/1/30 51/2/30 52/2/30
|
f 50/1/30 51/2/30 52/2/30
|
||||||
f 36/2/22 53/2/31 35/2/21
|
f 36/2/22 53/2/31 35/2/21
|
||||||
f 53/2/31 36/2/22 54/2/32
|
f 53/2/31 36/2/22 54/2/32
|
||||||
f 54/2/32 51/2/33 53/2/31
|
f 54/2/32 51/2/33 53/2/31
|
||||||
f 51/2/33 54/2/32 52/2/34
|
f 51/2/33 54/2/32 52/2/34
|
||||||
f 53/2/31 33/1/24 35/2/21
|
f 53/2/31 33/1/24 35/2/21
|
||||||
f 33/1/24 53/2/31 55/1/35
|
f 33/1/24 53/2/31 55/1/35
|
||||||
f 51/2/33 55/1/35 53/2/31
|
f 51/2/33 55/1/35 53/2/31
|
||||||
f 55/1/35 51/2/33 49/1/36
|
f 55/1/35 51/2/33 49/1/36
|
||||||
f 56/1/37 36/2/22 34/1/26
|
f 56/1/37 36/2/22 34/1/26
|
||||||
f 36/2/22 56/1/37 54/2/32
|
f 36/2/22 56/1/37 54/2/32
|
||||||
f 50/1/38 54/2/32 56/1/37
|
f 50/1/38 54/2/32 56/1/37
|
||||||
f 54/2/32 50/1/38 52/2/34
|
f 54/2/32 50/1/38 52/2/34
|
||||||
f 36/2/39 33/1/39 34/1/39
|
f 36/2/39 33/1/39 34/1/39
|
||||||
f 33/1/39 36/2/39 35/2/39
|
f 33/1/39 36/2/39 35/2/39
|
||||||
f 50/1/40 55/1/41 49/1/40
|
f 50/1/40 55/1/41 49/1/40
|
||||||
f 55/1/41 50/1/40 56/1/41
|
f 55/1/41 50/1/40 56/1/41
|
||||||
f 56/1/41 33/1/28 55/1/41
|
f 56/1/41 33/1/28 55/1/41
|
||||||
f 33/1/28 56/1/41 34/1/28
|
f 33/1/28 56/1/41 34/1/28
|
||||||
f 59/2/42 58/1/42 57/1/42
|
f 59/2/42 58/1/42 57/1/42
|
||||||
f 58/1/42 59/2/42 60/2/42
|
f 58/1/42 59/2/42 60/2/42
|
||||||
f 44/2/34 59/2/43 43/2/33
|
f 44/2/34 59/2/43 43/2/33
|
||||||
f 59/2/43 44/2/34 60/2/44
|
f 59/2/43 44/2/34 60/2/44
|
||||||
f 60/2/44 59/2/43 59/2/43
|
f 60/2/44 59/2/43 59/2/43
|
||||||
f 59/2/43 60/2/44 60/2/44
|
f 59/2/43 60/2/44 60/2/44
|
||||||
f 59/2/43 41/1/36 43/2/33
|
f 59/2/43 41/1/36 43/2/33
|
||||||
f 41/1/36 59/2/43 57/1/45
|
f 41/1/36 59/2/43 57/1/45
|
||||||
f 59/2/43 57/1/45 59/2/43
|
f 59/2/43 57/1/45 59/2/43
|
||||||
f 57/1/45 59/2/43 57/1/45
|
f 57/1/45 59/2/43 57/1/45
|
||||||
f 58/1/46 44/2/34 42/1/38
|
f 58/1/46 44/2/34 42/1/38
|
||||||
f 44/2/34 58/1/46 60/2/44
|
f 44/2/34 58/1/46 60/2/44
|
||||||
f 58/1/46 60/2/44 58/1/46
|
f 58/1/46 60/2/44 58/1/46
|
||||||
f 60/2/44 58/1/46 60/2/44
|
f 60/2/44 58/1/46 60/2/44
|
||||||
f 44/2/47 41/1/47 42/1/47
|
f 44/2/47 41/1/47 42/1/47
|
||||||
f 41/1/47 44/2/47 43/2/47
|
f 41/1/47 44/2/47 43/2/47
|
||||||
f 58/1/48 57/1/48 57/1/48
|
f 58/1/48 57/1/48 57/1/48
|
||||||
f 57/1/48 58/1/48 58/1/48
|
f 57/1/48 58/1/48 58/1/48
|
||||||
f 58/1/48 41/1/40 57/1/48
|
f 58/1/48 41/1/40 57/1/48
|
||||||
f 41/1/40 58/1/48 42/1/40
|
f 41/1/40 58/1/48 42/1/40
|
||||||
f 63/2/42 62/1/42 61/1/42
|
f 63/2/42 62/1/42 61/1/42
|
||||||
f 62/1/42 63/2/42 64/2/42
|
f 62/1/42 63/2/42 64/2/42
|
||||||
f 52/2/34 63/2/43 51/2/33
|
f 52/2/34 63/2/43 51/2/33
|
||||||
f 63/2/43 52/2/34 64/2/44
|
f 63/2/43 52/2/34 64/2/44
|
||||||
f 64/2/44 63/2/43 63/2/43
|
f 64/2/44 63/2/43 63/2/43
|
||||||
f 63/2/43 64/2/44 64/2/44
|
f 63/2/43 64/2/44 64/2/44
|
||||||
f 63/2/43 49/1/36 51/2/33
|
f 63/2/43 49/1/36 51/2/33
|
||||||
f 49/1/36 63/2/43 61/1/45
|
f 49/1/36 63/2/43 61/1/45
|
||||||
f 63/2/43 61/1/45 63/2/43
|
f 63/2/43 61/1/45 63/2/43
|
||||||
f 61/1/45 63/2/43 61/1/45
|
f 61/1/45 63/2/43 61/1/45
|
||||||
f 62/1/46 52/2/34 50/1/38
|
f 62/1/46 52/2/34 50/1/38
|
||||||
f 52/2/34 62/1/46 64/2/44
|
f 52/2/34 62/1/46 64/2/44
|
||||||
f 62/1/46 64/2/44 62/1/46
|
f 62/1/46 64/2/44 62/1/46
|
||||||
f 64/2/44 62/1/46 64/2/44
|
f 64/2/44 62/1/46 64/2/44
|
||||||
f 52/2/47 49/1/47 50/1/47
|
f 52/2/47 49/1/47 50/1/47
|
||||||
f 49/1/47 52/2/47 51/2/47
|
f 49/1/47 52/2/47 51/2/47
|
||||||
f 62/1/48 61/1/48 61/1/48
|
f 62/1/48 61/1/48 61/1/48
|
||||||
f 61/1/48 62/1/48 62/1/48
|
f 61/1/48 62/1/48 62/1/48
|
||||||
f 62/1/48 49/1/40 61/1/48
|
f 62/1/48 49/1/40 61/1/48
|
||||||
f 49/1/40 62/1/48 50/1/40
|
f 49/1/40 62/1/48 50/1/40
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user