stash this project for future reference

This commit is contained in:
Evert Prants 2019-11-06 19:24:55 +02:00
commit a81ce96b6a
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
24 changed files with 1687 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/**/*.import

View File

@ -0,0 +1,186 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=2]
[sub_resource type="Shader" id=1]
code = "shader_type spatial; // Written by GLtracy, ported to Godot by SolarLiner
render_mode blend_add, depth_test_disable;
// math const
uniform float PI = 3.14159265359;
uniform float MAX = 100000.0;
uniform vec3 position = vec3(0.0);
// scatter const
uniform float length_scale = 1000.0;
uniform float ground_radius = 128.0;
uniform float atmosphere_radius = 128.05;
uniform vec4 scattering_cf: hint_color = vec4(0.105707, 0.375536, 0.92076, 1.0);
uniform float scattering_power = 35.92;
uniform float rayleight_cf: hint_range(0.001, 1.0) = 0.07;
uniform float mie_cf: hint_range(0.001, 1.0) = 0.04;
uniform int scatter_passes: hint_range(0, 10) = 1;
// ray intersects sphere
// e = -b +/- sqrt( b^2 - c )
vec2 ray_vs_sphere( vec3 p, vec3 dir, float r ) {
float b = dot( p, dir );
float c = dot( p, p ) - r * r;
float d = b * b - c;
if ( d < 0.0 ) {
return vec2( MAX, -MAX );
}
d = sqrt( d );
return vec2( -b - d, -b + d );
}
// Mie
// g : ( -0.75, -0.999 )
// 3 * ( 1 - g^2 ) 1 + c^2
// F = ----------------- * -------------------------------
// 8pi * ( 2 + g^2 ) ( 1 + g^2 - 2 * g * c )^(3/2)
float phase_mie( float g, float c, float cc ) {
float gg = g * g;
float a = ( 1.0 - gg ) * ( 1.0 + cc );
float b = 1.0 + gg - 2.0 * (-g) * c;
b *= sqrt( b );
b *= 2.0 + gg;
return ( 3.0 / 8.0 * PI ) * a / b;
}
// Rayleigh
// g : 0
// F = 3/16PI * ( 1 + c^2 )
float phase_ray( float cc ) {
return ( 3.0 / 16.0 * PI ) * ( 1.0 + cc );
}
float density( vec3 p, float ph ) {
float scale_height = (atmosphere_radius - ground_radius);
return exp( -max( (length( p ) - ground_radius)/scale_height, 0.0 ) / ph );
}
float optic( vec3 p, vec3 q, float ph ) {
vec3 s = ( q - p ) / float( scatter_passes );
vec3 v = p + s * 0.5;
float sum = 0.0;
for ( int i = 0; i < scatter_passes; i++ ) {
sum += density( v, ph );
v += s;
}
sum *= length( s );
return sum;
}
vec3 in_scatter(vec3 o, vec3 dir, vec2 e, vec3 l) {
float ph_ray = rayleight_cf;
float ph_mie = mie_cf;
vec3 k_ray = scattering_cf.rgb * scattering_power; //(0.105707, 0.375536, 0.92076)*35.9486
vec3 k_mie = vec3( 1. * scattering_power );
float k_mie_ex = 1.1;
vec3 sum_ray = vec3( 0.0 );
vec3 sum_mie = vec3( 0.0 );
float n_ray0 = 0.0;
float n_mie0 = 0.0;
float len = ( e.y - e.x ) / float( scatter_passes*100 );
vec3 s = dir * len;
vec3 v = o + dir * ( e.x + len * 0.5 );
for ( int i = 0; i < scatter_passes*100; i++) {
float d_ray = density( v, ph_ray ) * len;
float d_mie = density( v, ph_mie ) * len;
n_ray0 += d_ray;
n_mie0 += d_mie;
v += s;
/*vec2 e = ray_vs_sphere( v, l, R_INNER );
e.x = max( e.x, 0.0 );
if ( e.x < e.y ) {
continue;
}*/
vec2 f = ray_vs_sphere( v, l, atmosphere_radius );
vec3 u = v + l * f.y;
float n_ray1 = optic( v, u, ph_ray );
float n_mie1 = optic( v, u, ph_mie );
vec3 att = exp( - ( n_ray0 + n_ray1 ) * k_ray - ( n_mie0 + n_mie1 ) * k_mie * k_mie_ex );
sum_ray += d_ray * att;
sum_mie += d_mie * att;
}
float c = dot( dir, -l );
float cc = c * c;
vec3 scatter =
sum_ray * k_ray * phase_ray( cc ) +
sum_mie * k_mie * phase_mie( -0.78, c, cc );
return scatter;
}
// ray direction
vec3 ray_dir( float fov, vec2 size, vec2 pos ) {
vec2 xy = pos - size * 0.5;
float cot_half_fov = tan( radians( 90.0 - fov * 0.5 ) );
float z = size.y * 0.5 * cot_half_fov;
return normalize( vec3( xy, -z ) );
}
void vertex() {
VERTEX += NORMAL * (atmosphere_radius - ground_radius)/1.;
}
void light()
{
// default ray dir
vec3 dir = VIEW;
// default ray origin
vec3 eye = INV_CAMERA_MATRIX[3].xyz + (CAMERA_MATRIX*vec4(position, 0.0)).xyz;
// sun light dir
vec3 l = -LIGHT;
vec2 e = ray_vs_sphere( eye, dir, atmosphere_radius );
if ( e.x > e.y ) {
DIFFUSE_LIGHT = vec3(0.0);
return;
}
vec2 f = ray_vs_sphere( eye, dir, ground_radius );
e.y = min( e.y, f.x );
vec3 I = in_scatter(eye, dir, e, l);
//DIFFUSE_LIGHT = vec3( pow( I, vec3( 1.0 / 2.2 ) ));
DIFFUSE_LIGHT = I*LIGHT_COLOR;
}"
[resource]
shader = SubResource( 1 )
shader_param/PI = 3.14159
shader_param/MAX = 100000.0
shader_param/position = Vector3( 0, 0, 0 )
shader_param/length_scale = 1000.0
shader_param/ground_radius = 6.371
shader_param/atmosphere_radius = 6.471
shader_param/scattering_cf = Color( 0.14902, 0.4, 0.909804, 1 )
shader_param/scattering_power = 36.0
shader_param/rayleight_cf = 0.07
shader_param/mie_cf = 0.04
shader_param/scatter_passes = 2

View File

@ -0,0 +1,7 @@
## 1.2
- Ingame gui configuration:
- draggability (configurable)
- customizable gui background
- enhanced movement (acceleration, deceleration..)

View File

@ -0,0 +1,54 @@
## Docummentation:
### Settings available via Editor/GDscript:
- bool enable : enable/disable camera controls. Default is true.
- int mouse_mode: Same as Godot's mouse settings by default the mouse is captured:
- Visible = 0 (MOUSE_MODE_VISIBLE),
- Hidden = 1 (MOUSE_MODE_HIDDEN),
- Capture = 2 (MOUSE_MODE_CAPTURED),
- Confined = 3 (MOUSE_MODE_CONFINED).
- bool mouselook - Enable/disable mouselook. Default is true.
- float sensitivity - Sensitivity of the mouselook. A value between 0 and 1. Default value is 0.5.
- float smoothness - Smoothness of the mouselook. A value between 0,001 and 0,999. Default value is 0.5.
- Spatial privot - Optional privot object for thirdperson like mouselook. Default value is None (no privot).
- bool rotate_privot - Enable/disable if the will be rotated with the camera. Default is false.
- float distance - The distance between the camera and the privot object. Minimum value is 0. Default value is 5.0
- bool rotate_privote - Rotate privot object with the mouselook. Default is false.
- bool collision - The camera avoid it to go through/behind objects. Default is true.
- int yaw_limit - Limit the yaw of the mouselook in Degrees, if limit >= 360 there is no limit. Default value is 360.
- int pitch_limit - Limit the Pitch of the mouselook in Degrees, if limit = 360 there is no limit. Default value is 360.
- bool movement - Enable/disable camera movement (flying). Default is true.
- bool local - Switch between movement on local or global axes. Default is true.
- float acceleration - Set the movement speed up factor. A Value between 0 and 1. Default value is 1.0.
- float deceleration - Set the movement slow down factor. A Value between 0 and 1. Default value is 0.1.
- Vector3 max_speed - Set maximum movement speed for each axes separately. Default value is (1.0, 1.0, 1.0).
- String forword_action - Input Action for fordward movement. Default action is "ui_up".
- String backward_action - Input Action for backward movement. Default action is "ui_down".
- String left_action - Input Action for Left movement. Default action is "ui_left".
- String right_action: Input Action for Right movement. Default action is "ui_right".
- String up_action - Input Action for upward movement. Default action is "ui_page_up".
- String down_action: Input Action for downward movement. Default action is "ui_page_down".
- String gui_action - Input Action to show/hide the ingame control gui. Default action is "ui_cancel".
- bool use_gui - Enable/disable ingame gui. Default is true.
### Gui configuration:
The ingame gui can also be configurated via constants in the camera_control_gui.gd script
- const Vector2 GUI_POS - The default position of the gui. Default is (10, 10).
- const Vector2 GUI_SIZE - The size of the gui. Default is (200, 0)
- const bool DRAGGABLE - Enable/disable draggable gui. Default is true.
- const bool CUSTOM_BACKGROUND - Enable/disable custom background color. Default is false.
- const Color CUSTOM_COLOR - Set custom background color.
- const MAX_SPEED - The maximal value of the speedslider

View File

@ -0,0 +1,51 @@
All parts of this project that are not copyrighted or licensed by someone else are released under the MIT License:
Copyright (c) 2018 Jaccomo Lorenz (Maujoe)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------
Other Files:
Some files caintained in this project may be generated by the Godot Engine version 3.0 that is covered by its own license, an up to date version can be found on: https://github.com/godotengine/godot/blob/master/LICENSE.txt.
Quote (18th February 2018):
"Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE."

View File

@ -0,0 +1,98 @@
# Camera Control Script
An easy "plug and play" camera script for the godot engine 3.0 that provides controls like mouselook, movement and an optional ingame control gui.
Useful for development and quick tests.
### Features:
- mouselook
- movement
- ingame gui (optional)
### Preview:
Demo video: https://www.youtube.com/watch?v=OSJRc-IiOio&t=9s
<details>
<summary>Editor Settings</summary>
<img src="screenshots/editor_settings.png" >
</details>
<details>
<summary>Ingame Gui</summary>
<img src="screenshots/ingame_gui.png" >
</details>
## How to use
There is a demo scene in the demo folder where you can test all features and play with the script settings.
If you don't need the demo just ignore the demo folder and connect your camera with the "camera_control.gd" script that can be found in the script folder.
## Docummentation:
### Settings available via Editor/GDscript:
- bool enable : enable/disable camera controls. Default is true.
- int mouse_mode: Same as Godot's mouse settings by default the mouse is captured:
- Visible = 0 (MOUSE_MODE_VISIBLE),
- Hidden = 1 (MOUSE_MODE_HIDDEN),
- Capture = 2 (MOUSE_MODE_CAPTURED),
- Confined = 3 (MOUSE_MODE_CONFINED).
- bool mouselook - Enable/disable mouselook. Default is true.
- float sensitivity - Sensitivity of the mouselook. A value between 0 and 1. Default value is 0.5.
- float smoothness - Smoothness of the mouselook. A value between 0,001 and 0,999. Default value is 0.5.
- Spatial privot - Optional privot object for thirdperson like mouselook. Default value is None (no privot).
- bool rotate_privot - Enable/disable if the will be rotated with the camera. Default is false.
- float distance - The distance between the camera and the privot object. Minimum value is 0. Default value is 5.0
- bool rotate_privote - Rotate privot object with the mouselook. Default is false.
- bool collision - The camera avoid it to go through/behind objects. Default is true.
- int yaw_limit - Limit the yaw of the mouselook in Degrees, if limit >= 360 there is no limit. Default value is 360.
- int pitch_limit - Limit the Pitch of the mouselook in Degrees, if limit = 360 there is no limit. Default value is 360.
- bool movement - Enable/disable camera movement (flying). Default is true.
- bool local - Switch between movement on local or global axes. Default is true.
- float acceleration - Set the movement speed up factor. A Value between 0 and 1. Default value is 1.0.
- float deceleration - Set the movement slow down factor. A Value between 0 and 1. Default value is 0.1.
- Vector3 max_speed - Set maximum movement speed for each axes separately. Default value is (1.0, 1.0, 1.0).
- String forword_action - Input Action for fordward movement. Default action is "ui_up".
- String backward_action - Input Action for backward movement. Default action is "ui_down".
- String left_action - Input Action for Left movement. Default action is "ui_left".
- String right_action: Input Action for Right movement. Default action is "ui_right".
- String up_action - Input Action for upward movement. Default action is "ui_page_up".
- String down_action: Input Action for downward movement. Default action is "ui_page_down".
- String gui_action - Input Action to show/hide the ingame control gui. Default action is "ui_cancel".
- bool use_gui - Enable/disable ingame gui. Default is true.
### Gui configuration:
The ingame gui can also be configurated via constants in the camera_control_gui.gd script
![Image](screenshots/gui_settings.png)
- const Vector2 GUI_POS - The default position of the gui. Default is (10, 10).
- const Vector2 GUI_SIZE - The size of the gui. Default is (200, 0)
- const bool DRAGGABLE - Enable/disable draggable gui. Default is true.
- const bool CUSTOM_BACKGROUND - Enable/disable custom background color. Default is false.
- const Color CUSTOM_COLOR - Set custom background color.
- const MAX_SPEED - The maximal value of the speedslider
### To-do/possible features:
- refactoring
- distance shortcut key.
- improve movement: speed shortcut
- multiple camera support/jump between cameras
- screenshot functionality(?)
- more modularisation(?)
- add signal notification(?)
- ...
## License
All parts of this project that are not copyrighted or licensed by someone else are released free under the MIT License - see the LICENSE.md file for details.
Please keep license file, thanks. :)

View File

@ -0,0 +1,102 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1]
radiance_size = 4
sky_top_color = Color( 0.0470588, 0.454902, 0.976471, 1 )
sky_horizon_color = Color( 0.556863, 0.823529, 0.909804, 1 )
sky_curve = 0.25
sky_energy = 1.0
ground_bottom_color = Color( 0.101961, 0.145098, 0.188235, 1 )
ground_horizon_color = Color( 0.482353, 0.788235, 0.952941, 1 )
ground_curve = 0.01
ground_energy = 1.0
sun_color = Color( 1, 1, 1, 1 )
sun_latitude = 35.0
sun_longitude = 0.0
sun_angle_min = 1.0
sun_angle_max = 100.0
sun_curve = 0.05
sun_energy = 16.0
texture_size = 2
[resource]
background_mode = 2
background_sky = SubResource( 1 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 1.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 3
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.0
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0
_sections_unfolded = [ "Ambient Light", "Background" ]

View File

@ -0,0 +1,270 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://assets/maujoe.camera_control/scripts/camera_control.gd" type="Script" id=1]
[sub_resource type="SpatialMaterial" id=1]
render_priority = 0
flags_transparent = false
flags_unshaded = false
flags_vertex_lighting = false
flags_no_depth_test = false
flags_use_point_size = false
flags_world_triplanar = false
flags_fixed_size = false
flags_albedo_tex_force_srgb = false
vertex_color_use_as_albedo = false
vertex_color_is_srgb = false
params_diffuse_mode = 0
params_specular_mode = 0
params_blend_mode = 0
params_cull_mode = 0
params_depth_draw_mode = 0
params_line_width = 1.0
params_point_size = 1.0
params_billboard_mode = 0
params_grow = false
params_use_alpha_scissor = false
albedo_color = Color( 1, 1, 1, 1 )
metallic = 0.0
metallic_specular = 0.5
metallic_texture_channel = 0
roughness = 0.0
roughness_texture_channel = 0
emission_enabled = false
normal_enabled = false
rim_enabled = false
clearcoat_enabled = false
anisotropy_enabled = false
ao_enabled = false
depth_enabled = false
subsurf_scatter_enabled = false
transmission_enabled = false
refraction_enabled = false
detail_enabled = false
uv1_scale = Vector3( 1, 1, 1 )
uv1_offset = Vector3( 0, 0, 0 )
uv1_triplanar = false
uv1_triplanar_sharpness = 1.0
uv2_scale = Vector3( 1, 1, 1 )
uv2_offset = Vector3( 0, 0, 0 )
uv2_triplanar = false
uv2_triplanar_sharpness = 1.0
proximity_fade_enable = false
distance_fade_enable = false
[sub_resource type="PlaneMesh" id=2]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
size = Vector2( 10, 10 )
subdivide_width = 0
subdivide_depth = 0
[sub_resource type="SpatialMaterial" id=3]
render_priority = 0
flags_transparent = false
flags_unshaded = false
flags_vertex_lighting = false
flags_no_depth_test = false
flags_use_point_size = false
flags_world_triplanar = false
flags_fixed_size = false
flags_albedo_tex_force_srgb = false
vertex_color_use_as_albedo = false
vertex_color_is_srgb = false
params_diffuse_mode = 0
params_specular_mode = 0
params_blend_mode = 0
params_cull_mode = 0
params_depth_draw_mode = 0
params_line_width = 1.0
params_point_size = 1.0
params_billboard_mode = 0
params_grow = false
params_use_alpha_scissor = false
albedo_color = Color( 1, 1, 1, 1 )
metallic = 0.0
metallic_specular = 0.5
metallic_texture_channel = 0
roughness = 0.0
roughness_texture_channel = 0
emission_enabled = false
normal_enabled = false
rim_enabled = false
clearcoat_enabled = false
anisotropy_enabled = false
ao_enabled = false
depth_enabled = false
subsurf_scatter_enabled = false
transmission_enabled = false
refraction_enabled = false
detail_enabled = false
uv1_scale = Vector3( 1, 1, 1 )
uv1_offset = Vector3( 0, 0, 0 )
uv1_triplanar = false
uv1_triplanar_sharpness = 1.0
uv2_scale = Vector3( 1, 1, 1 )
uv2_offset = Vector3( 0, 0, 0 )
uv2_triplanar = false
uv2_triplanar_sharpness = 1.0
proximity_fade_enable = false
distance_fade_enable = false
[sub_resource type="CubeMesh" id=4]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
size = Vector3( 2, 2, 2 )
subdivide_width = 0
subdivide_height = 0
subdivide_depth = 0
[sub_resource type="ConcavePolygonShape" id=5]
data = PoolVector3Array( -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1 )
[sub_resource type="CubeMesh" id=6]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
size = Vector3( 1, 2, 1 )
subdivide_width = 0
subdivide_height = 0
subdivide_depth = 0
[node name="Node" type="Node" index="0"]
[node name="Camera" type="Camera" parent="." index="0"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 5 )
keep_aspect = 1
cull_mask = 1048575
environment = null
h_offset = 0.0
v_offset = 0.0
doppler_tracking = 0
projection = 0
current = false
fov = 70.0
size = 1.0
near = 0.05
far = 100.0
script = ExtResource( 1 )
enabled = true
mouse_mode = 2
mouselook = true
sensitivity = 0.5
smoothness = 0.5
privot = null
distance = 6.0
rotate_privot = false
collisions = false
yaw_limit = 360
pitch_limit = 360
movement = true
acceleration = 1.0
deceleration = 0.1
max_speed = Vector3( 1, 1, 1 )
local = true
forward_action = "ui_up"
backward_action = "ui_down"
left_action = "ui_left"
right_action = "ui_right"
up_action = "ui_page_up"
down_action = "ui_page_down"
use_gui = true
gui_action = "ui_cancel"
[node name="DirectionalLight" type="DirectionalLight" parent="." index="1"]
transform = Transform( 1, 0, 0, 0, 0.866025, 0.5, 0, -0.5, 0.866025, 0, 8, 0 )
layers = 1
light_color = Color( 1, 1, 1, 1 )
light_energy = 1.0
light_indirect_energy = 1.0
light_negative = false
light_specular = 0.5
light_bake_mode = 1
light_cull_mask = -1
shadow_enabled = false
shadow_color = Color( 0, 0, 0, 1 )
shadow_bias = 0.1
shadow_contact = 0.0
shadow_reverse_cull_face = false
editor_only = false
directional_shadow_mode = 2
directional_shadow_split_1 = 0.1
directional_shadow_split_2 = 0.2
directional_shadow_split_3 = 0.5
directional_shadow_blend_splits = false
directional_shadow_normal_bias = 0.8
directional_shadow_bias_split_scale = 0.25
directional_shadow_depth_range = 0
directional_shadow_max_distance = 200.0
[node name="Ground" type="MeshInstance" parent="." index="2"]
layers = 1
material_override = SubResource( 1 )
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 2 )
skeleton = NodePath("..")
material/0 = null
_sections_unfolded = [ "Geometry" ]
[node name="Cube" type="MeshInstance" parent="." index="3"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 1, -4 )
layers = 1
material_override = SubResource( 3 )
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 4 )
skeleton = NodePath("..")
material/0 = null
_sections_unfolded = [ "Geometry" ]
[node name="StaticBody" type="StaticBody" parent="Cube" index="0"]
input_ray_pickable = true
input_capture_on_drag = false
collision_layer = 1
collision_mask = 1
friction = 1.0
bounce = 0.0
constant_linear_velocity = Vector3( 0, 0, 0 )
constant_angular_velocity = Vector3( 0, 0, 0 )
[node name="CollisionShape" type="CollisionShape" parent="Cube/StaticBody" index="0"]
shape = SubResource( 5 )
disabled = false
[node name="Cube2" type="MeshInstance" parent="." index="4"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 )
layers = 1
material_override = SubResource( 3 )
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 6 )
skeleton = NodePath("..")
material/0 = null
_sections_unfolded = [ "Geometry" ]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -0,0 +1,208 @@
# Licensed under the MIT License.
# Copyright (c) 2018 Jaccomo Lorenz (Maujoe)
extends Camera
# User settings:
# General settings
export var enabled = true setget set_enabled
export(int, "Visible", "Hidden", "Caputered, Confined") var mouse_mode = 2
# Mouslook settings
export var mouselook = true
export (float, 0.0, 1.0) var sensitivity = 0.5
export (float, 0.0, 0.999, 0.001) var smoothness = 0.5 setget set_smoothness
export(NodePath) var privot setget set_privot
export var distance = 5.0 setget set_distance
export var rotate_privot = false
export var collisions = true setget set_collisions
export (int, 0, 360) var yaw_limit = 360
export (int, 0, 360) var pitch_limit = 360
# Movement settings
export var movement = true
export (float, 0.0, 1.0) var acceleration = 1.0
export (float, 0.0, 0.0, 1.0) var deceleration = 1.0
export var max_speed = Vector3(1.0, 1.0, 1.0)
export var local = true
export var forward_action = "ui_up"
export var backward_action = "ui_down"
export var left_action = "ui_left"
export var right_action = "ui_right"
export var up_action = "ui_page_up"
export var down_action = "ui_page_down"
# Gui settings
export var use_gui = true
export var gui_action = "ui_cancel"
# Intern variables.
var _mouse_position = Vector2(0.0, 0.0)
var _yaw = 0.0
var _pitch = 0.0
var _total_yaw = 0.0
var _total_pitch = 0.0
var _direction = Vector3(0.0, 0.0, 0.0)
var _speed = Vector3(0.0, 0.0, 0.0)
var _gui
func _ready():
_check_actions([forward_action, backward_action, left_action, right_action, gui_action, up_action, down_action])
if privot:
privot = get_node(privot)
else:
privot = null
set_enabled(enabled)
if use_gui:
_gui = preload("camera_control_gui.gd")
_gui = _gui.new(self, gui_action)
add_child(_gui)
func _input(event):
if mouselook:
if event is InputEventMouseMotion:
_mouse_position = event.relative
if movement:
if event.is_action_pressed(forward_action):
_direction.z = -1
elif event.is_action_pressed(backward_action):
_direction.z = 1
elif not Input.is_action_pressed(forward_action) and not Input.is_action_pressed(backward_action):
_direction.z = 0
if event.is_action_pressed(left_action):
_direction.x = -1
elif event.is_action_pressed(right_action):
_direction.x = 1
elif not Input.is_action_pressed(left_action) and not Input.is_action_pressed(right_action):
_direction.x = 0
if event.is_action_pressed(up_action):
_direction.y = 1
if event.is_action_pressed(down_action):
_direction.y = -1
elif not Input.is_action_pressed(up_action) and not Input.is_action_pressed(down_action):
_direction.y = 0
func _process(delta):
if privot:
_update_distance()
if mouselook:
_update_mouselook()
if movement:
_update_movement(delta)
func _physics_process(delta):
# Called when collision are enabled
_update_distance()
if mouselook:
_update_mouselook()
var space_state = get_world().get_direct_space_state()
var obstacle = space_state.intersect_ray(privot.get_translation(), get_translation())
if not obstacle.empty():
set_translation(obstacle.position)
func _update_movement(delta):
var offset = max_speed * acceleration * _direction
_speed.x = clamp(_speed.x + offset.x, -max_speed.x, max_speed.x)
_speed.y = clamp(_speed.y + offset.y, -max_speed.y, max_speed.y)
_speed.z = clamp(_speed.z + offset.z, -max_speed.z, max_speed.z)
# Apply deceleration if no input
if _direction.x == 0:
_speed.x *= (1.0 - deceleration)
if _direction.y == 0:
_speed.y *= (1.0 - deceleration)
if _direction.z == 0:
_speed.z *= (1.0 - deceleration)
if local:
translate(_speed * delta)
else:
global_translate(_speed * delta)
func _update_mouselook():
_mouse_position *= sensitivity
_yaw = _yaw * smoothness + _mouse_position.x * (1.0 - smoothness)
_pitch = _pitch * smoothness + _mouse_position.y * (1.0 - smoothness)
_mouse_position = Vector2(0, 0)
if yaw_limit < 360:
_yaw = clamp(_yaw, -yaw_limit - _total_yaw, yaw_limit - _total_yaw)
if pitch_limit < 360:
_pitch = clamp(_pitch, -pitch_limit - _total_pitch, pitch_limit - _total_pitch)
_total_yaw += _yaw
_total_pitch += _pitch
if privot:
var target = privot.get_translation()
var offset = get_translation().distance_to(target)
set_translation(target)
rotate_y(deg2rad(-_yaw))
rotate_object_local(Vector3(1,0,0), deg2rad(-_pitch))
translate(Vector3(0.0, 0.0, offset))
if rotate_privot:
privot.rotate_y(deg2rad(-_yaw))
else:
rotate_y(deg2rad(-_yaw))
rotate_object_local(Vector3(1,0,0), deg2rad(-_pitch))
func _update_distance():
var t = privot.get_translation()
t.z -= distance
set_translation(t)
func _update_process_func():
# Use physics process if collision are enabled
if collisions and privot:
set_physics_process(true)
set_process(false)
else:
set_physics_process(false)
set_process(true)
func _check_actions(actions=[]):
if OS.is_debug_build():
for action in actions:
if not InputMap.has_action(action):
print('WARNING: No action "' + action + '"')
func set_privot(value):
privot = value
# TODO: fix parenting.
# if privot:
# if get_parent():
# get_parent().remove_child(self)
# privot.add_child(self)
_update_process_func()
func set_collisions(value):
collisions = value
_update_process_func()
func set_enabled(value):
enabled = value
if enabled:
Input.set_mouse_mode(mouse_mode)
set_process_input(true)
_update_process_func()
else:
set_process(false)
set_process_input(false)
set_physics_process(false)
func set_smoothness(value):
smoothness = clamp(value, 0.001, 0.999)
func set_distance(value):
distance = max(0, value)

View File

@ -0,0 +1,296 @@
# Licensed under the MIT License.
# Copyright (c) 2018 Jaccomo Lorenz (Maujoe)
extends Control
# Constant Gui Settings
#*******************************************************************************
const GUI_POS = Vector2(10, 10)
const GUI_SIZE = Vector2(200, 0)
const DRAGGABLE = true
const CUSTOM_BACKGROUND = false
const BACKGROUND_COLOR = Color(0.15, 0.17, 0.23, 0.75)
const MAX_SPEED = 50
#*******************************************************************************
var camera
var shortcut
var node_list
var privot
var panel
var mouse_over = false
var mouse_pressed = false
func _init(camera, shortcut):
self.camera = camera
self.shortcut = shortcut
func _ready():
if camera.enabled:
set_process_input(true)
# Create Gui
panel = PanelContainer.new()
panel.set_begin(GUI_POS)
panel.set_custom_minimum_size(GUI_SIZE)
if CUSTOM_BACKGROUND:
var style = StyleBoxFlat.new()
style.set_bg_color(BACKGROUND_COLOR)
style.set_expand_margin_all(5)
panel.add_stylebox_override("panel", style)
var container = VBoxContainer.new()
var lbl_mouse = Label.new()
lbl_mouse.set_text("Mousemode")
var mouse = OptionButton.new()
mouse.add_item("Visible")
mouse.add_item("Hidden")
mouse.add_item("Captured")
mouse.add_item("Confined")
mouse.select(camera.mouse_mode)
mouse.connect("item_selected",self,"_on_opt_mouse_item_selected")
# Mouselook
var mouselook = CheckButton.new()
mouselook.set_text("Mouselook")
mouselook.set_toggle_mode(true)
mouselook.set_pressed(camera.mouselook)
mouselook.connect("toggled",self,"_on_btn_mouselook_toggled")
var lbl_sensitivity = Label.new()
lbl_sensitivity.set_text("Sensitivity")
var sensitivity = HScrollBar.new()
sensitivity.set_max(1)
sensitivity.set_value(camera.sensitivity)
sensitivity.connect("value_changed",self,"_on_hsb_sensitivity_value_changed")
var lbl_smoothless = Label.new()
lbl_smoothless.set_text("Smoothness")
var smoothness = HScrollBar.new()
smoothness.set_max(0.999)
smoothness.set_min(0.5)
smoothness.set_value(camera.smoothness)
smoothness.connect("value_changed",self,"_on_hsb_smoothness_value_changed")
var lbl_privot = Label.new()
lbl_privot.set_text("Privot")
privot = OptionButton.new()
privot.set_text("Privot")
_update_privots(privot)
privot.connect("item_selected",self,"_on_opt_privot_item_selected")
privot.connect("pressed",self,"_on_opt_privot_pressed")
var btn_rot_privot = CheckButton.new()
btn_rot_privot.set_text("Rotate Privot")
btn_rot_privot.set_toggle_mode(true)
btn_rot_privot.set_pressed(camera.rotate_privot)
btn_rot_privot.connect("toggled",self,"_on_btn_rot_privot_toggled")
var lbl_distance = Label.new()
lbl_distance.set_text("Distance")
var distance = SpinBox.new()
distance.set_value(camera.distance)
distance.connect("value_changed",self,"_on_box_distance_value_changed")
var lbl_yaw = Label.new()
lbl_yaw.set_text("Yaw Limit")
var yaw = SpinBox.new()
yaw.set_max(360)
yaw.set_value(camera.yaw_limit)
yaw.connect("value_changed",self,"_on_box_yaw_value_changed")
var lbl_pitch = Label.new()
lbl_pitch.set_text("Pitch Limit")
var pitch = SpinBox.new()
pitch.set_max(360)
pitch.set_value(camera.pitch_limit)
pitch.connect("value_changed",self,"_on_box_pitch_value_changed")
var collisions = CheckButton.new()
collisions.set_text("Collisions")
collisions.set_toggle_mode(true)
collisions.set_pressed(camera.collisions)
collisions.connect("toggled",self,"_on_btn_collisions_toggled")
# Movement
var lbl_movement = Label.new()
lbl_movement.set_text("Movement")
var movement = CheckButton.new()
movement.set_pressed(camera.movement)
movement.connect("toggled",self,"_on_btn_movement_toggled")
var lbl_speed = Label.new()
lbl_speed.set_text("Max Speed")
var speed = HScrollBar.new()
speed.set_max(MAX_SPEED)
speed.set_value(camera.max_speed.x)
speed.connect("value_changed",self,"_on_hsb_speed_value_changed")
var lbl_acceleration = Label.new()
lbl_acceleration.set_text("Acceleration")
var acceleration = HScrollBar.new()
acceleration.set_max(1.0)
acceleration.set_value(camera.acceleration)
acceleration.connect("value_changed", self, "_in_hsb_acceleration_value_changed")
var lbl_deceleration = Label.new()
lbl_deceleration.set_text("Deceleration")
var deceleration = HScrollBar.new()
deceleration.set_max(1.0)
deceleration.set_value(camera.deceleration)
deceleration.connect("value_changed", self, "_in_hsb_deceleration_value_changed")
add_child(panel)
panel.add_child(container)
container.add_child(lbl_mouse)
container.add_child(mouse)
container.add_child(mouselook)
container.add_child(lbl_sensitivity)
container.add_child(sensitivity)
container.add_child(lbl_smoothless)
container.add_child(smoothness)
container.add_child(lbl_privot)
container.add_child(privot)
container.add_child(btn_rot_privot)
container.add_child(lbl_distance)
container.add_child(distance)
container.add_child(lbl_yaw)
container.add_child(yaw)
container.add_child(lbl_pitch)
container.add_child(pitch)
container.add_child(collisions)
container.add_child(lbl_movement)
container.add_child(movement)
container.add_child(lbl_speed)
container.add_child(speed)
container.add_child(lbl_acceleration)
container.add_child(acceleration)
container.add_child(lbl_deceleration)
container.add_child(deceleration)
if DRAGGABLE:
panel.connect("mouse_entered", self, "_panel_entered")
panel.connect("mouse_exited", self, "_panel_exited")
container.connect("mouse_entered", self, "_panel_entered")
container.connect("mouse_exited", self, "_panel_exited")
self.hide()
else:
set_process_input(false)
func _input(event):
if event.is_action_pressed(shortcut):
if camera.enabled:
camera.enabled = false
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
self.show()
else:
camera.enabled = true
self.hide()
if DRAGGABLE:
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
mouse_pressed = event.pressed
elif event is InputEventMouseMotion and mouse_over and mouse_pressed:
panel.set_begin(panel.get_begin() + event.relative)
func _update_privots(privot):
privot.clear()
privot.add_item("None")
node_list = _get_spatials_recusiv(get_tree().get_root(), [get_name(), camera.get_name()])
var size = node_list.size()
for i in range(0, size):
var node = node_list[i]
privot.add_item(node.get_name())
if node == camera.privot:
privot.select(i+1)
if not camera.privot:
privot.select(0)
func _get_spatials_recusiv(node, exceptions=[]):
var list = []
for child in node.get_children():
if not child.get_name() in exceptions:
if child is Spatial:
list.append(child)
if not child.get_children().empty():
for subchild in _get_spatials_recusiv(child, exceptions):
list.append(subchild)
return list
func _panel_entered():
mouse_over = true
func _panel_exited():
mouse_over = false
func _on_opt_mouse_item_selected(id):
camera.mouse_mode = id
func _on_btn_mouselook_toggled(pressed):
camera.mouselook = pressed
func _on_hsb_sensitivity_value_changed(value):
camera.sensitivity = value
func _on_hsb_smoothness_value_changed(value):
camera.smoothness = value
func _on_opt_privot_pressed():
_update_privots(privot)
func _on_opt_privot_item_selected(id):
if id > 0:
camera.privot = node_list[id-1]
else:
camera.privot = null
privot.select(id)
func _on_btn_rot_privot_toggled(pressed):
camera.rotate_privot = pressed
func _on_box_distance_value_changed(value):
camera.distance = value
func _on_box_yaw_value_changed(value):
camera.yaw_limit = value
func _on_box_pitch_value_changed(value):
camera.pitch_limit = value
func _on_btn_collisions_toggled(pressed):
camera.collisions = pressed
func _on_btn_movement_toggled(pressed):
camera.movement = pressed
func _on_hsb_speed_value_changed(value):
camera.max_speed.x = value
camera.max_speed.y = value
camera.max_speed.z = value
func _in_hsb_acceleration_value_changed(value):
camera.acceleration = value
func _in_hsb_deceleration_value_changed(value):
camera.deceleration = value

7
default_env.tres Normal file
View File

@ -0,0 +1,7 @@
[gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="PanoramaSky" id=1]
[resource]
background_mode = 2
background_sky = SubResource( 1 )

BIN
grass-1024.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

72
project.godot Normal file
View File

@ -0,0 +1,72 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
"base": "Node",
"class": "PlanetFace",
"language": "GDScript",
"path": "res://oldscripts/PlanetFace.gd"
}, {
"base": "Node",
"class": "PlanetFaceGenerator",
"language": "GDScript",
"path": "res://oldscripts/PlanetFaceGenerator.gd"
}, {
"base": "Spatial",
"class": "PlanetTerrain",
"language": "GDScript",
"path": "res://oldscripts/PlanetTerrain.gd"
} ]
_global_script_class_icons={
"PlanetFace": "",
"PlanetFaceGenerator": "",
"PlanetTerrain": ""
}
[application]
config/name="Planet"
run/main_scene="res://scenes/World.tscn"
config/icon="res://icon.png"
[input]
ui_left={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
]
}
ui_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
]
}
ui_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
]
}
ui_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
]
}
[rendering]
environment/default_environment="res://default_env.tres"

8
scenes/Planet.tscn Normal file
View File

@ -0,0 +1,8 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://oldscripts/Planet.gd" type="Script" id=1]
[node name="Planet" type="Spatial"]
script = ExtResource( 1 )

View File

@ -0,0 +1,10 @@
[gd_resource type="Environment" load_steps=3 format=2]
[ext_resource path="res://space.png" type="Texture" id=1]
[sub_resource type="PanoramaSky" id=1]
panorama = ExtResource( 1 )
[resource]
background_mode = 2
background_sky = SubResource( 1 )

27
scenes/World.tscn Normal file
View File

@ -0,0 +1,27 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://scenes/Planet.tscn" type="PackedScene" id=1]
[ext_resource path="res://scripts/Planet.gd" type="Script" id=2]
[ext_resource path="res://assets/maujoe.camera_control/scripts/camera_control.gd" type="Script" id=3]
[ext_resource path="res://default_env.tres" type="Environment" id=4]
[sub_resource type="SpatialMaterial" id=1]
albedo_color = Color( 0.00392157, 0.466667, 0, 1 )
metallic = 0.56
[node name="World" type="WorldEnvironment"]
environment = ExtResource( 4 )
[node name="Planet" parent="." instance=ExtResource( 1 )]
script = ExtResource( 2 )
face_resolution = 64
face_material = SubResource( 1 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 0.906308, 0.422618, 0, -0.422618, 0.906308, 0, 106.609, 211.095 )
far = 1000.0
script = ExtResource( 3 )
max_speed = Vector3( 100, 100, 100 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 1, 0, 0, 0, -0.736719, 0.676199, 0, -0.676199, -0.736719, -0.0353088, 35.3451, 41.178 )

290
scripts/Planet.gd Normal file
View File

@ -0,0 +1,290 @@
extends Spatial
export(int) var planet_radius = 128
export(int) var face_resolution = 16
export(Material) var face_material = null
export(Material) var atmosphere_material = null
export(float) var planet_terrain_seed = 0.0
export(int) var terrain_octaves = 3
export(float) var terrain_period = 64.0
export(float) var terrain_persistence = 0.5
export(float) var terrain_lacunarity = 2.0
const LOD_MAX = 5
const LOD_ENABLE = false
const WIREFRAME = false
class PlanetThreading:
var planet
func _init(planet):
self.planet = planet
func _recursive_generate(face):
var generated = false
for child in face.get_children():
if generated:
break
if child.is_leaf() and not child.generated:
child.generate_mesh()
generated = true
break
elif not child.is_leaf():
generated = self._recursive_generate(child)
return generated
func _recursive_tick(face, camera):
for child in face.get_children():
child.process_lod(camera)
if not child.is_leaf():
self._recursive_tick(child, camera)
func _tick():
var generated = false
for i in self.planet.get_children():
if generated: continue
generated = self._recursive_generate(self.planet)
if generated or not LOD_ENABLE:
return
var camera = self.planet.get_viewport().get_camera()
self._recursive_tick(self.planet, camera)
class PlanetMetadata:
var resolution
var radius
var material
var lods
var noise
func _init(resolution, radius, material, lods, noise):
self.resolution = resolution
self.radius = radius
self.material = material
self.lods = lods
self.noise = noise
func get_radius():
return self.radius
func get_resolution():
return self.resolution
func get_material():
return self.material
func get_detail_levels():
return self.lods
func get_noise():
return self.noise
class CubeFace extends MeshInstance:
var position
var normal
var left
var forward
var resolution
var radius
var level
var meta
var center
var generated = false
func _init(level, pos, normal, meta):
self.meta = meta
self.normal = normal
self.resolution = meta.get_resolution()
self.radius = meta.get_radius()
self.level = level
self.generated = false
# Calculate left (x) and forward (z) vectors from the normal (y)
self.left = Vector3(normal.y, normal.z, normal.x)
self.forward = normal.cross(self.left)
self.position = pos
# Center the first face
if level == 0:
self.position = self.position - (self.left * (self.radius / max(2.0, pow(2, self.level))))
self.position = self.position - (self.forward * (self.radius / max(2.0, pow(2, self.level))))
func process_lod(camera):
if not self.center:
return
var camera_pos_local = self.to_local(camera.get_translation())
var camera_dist_center = (camera_pos_local - self.center).length()
var divisionLevel = pow(2, self.level)
var split_distance = float(float(self.radius) / divisionLevel)
if camera_dist_center < split_distance * 1.5 and self.is_leaf():
self.subdivide()
elif camera_dist_center > split_distance * 2 and not self.is_leaf():
self.merge()
func is_leaf():
return self.level == self.meta.get_detail_levels() or self.get_child_count() == 0
func generate_mesh():
if (self.generated):
return
var vertices = self.resolution
var noise = self.meta.get_noise()
var st = SurfaceTool.new()
var mode = Mesh.PRIMITIVE_TRIANGLES
if WIREFRAME:
mode = Mesh.PRIMITIVE_LINES
st.begin(mode)
st.set_material(self.meta.get_material())
var divisionLevel = pow(2, self.level)
for i in range(0.0, vertices):
for j in range (0.0, vertices):
# Vertex index (0 to 1)
var iindex = i / (vertices - 1.0)
var jindex = j / (vertices - 1.0)
# From the left and forward vectors, we can calculate an oriented vertex
var iv = ((self.left * iindex) * self.radius) / divisionLevel
var jv = ((self.forward * jindex) * self.radius) / divisionLevel
# Add the scaled left and forward to the centered origin
var vertex = self.position + (iv + jv)
# Normalize and multiply by radius to create a spherical mesh
var vertNormal = vertex.normalized()
#var pos = vertNormal * (noise.get_noise_3dv(vertex) + self.radius)
var pos = vertNormal * self.radius
# Add to ST
st.add_uv(Vector2(j * (1 / vertices), i * (1 / vertices)))
st.add_vertex(pos)
# Set centerpoint
if (i == int(vertices / 2) and j == int(vertices / 2)):
self.center = pos
# Arrange planet face triangles
for gz in range(0, vertices - 1):
for gx in range(0, vertices - 1):
var topLeft = (gz * vertices) + gx
var topRight = topLeft + 1
var bottomLeft = ((gz + 1) * vertices) + gx
var bottomRight = bottomLeft + 1
#st.add_index(topRight)
#st.add_index(bottomRight)
#st.add_index(topLeft)
#st.add_index(topLeft)
#st.add_index(bottomRight)
#st.add_index(bottomLeft)
st.add_index(topLeft)
st.add_index(topRight)
st.add_index(bottomLeft)
st.add_index(bottomLeft)
st.add_index(topRight)
st.add_index(bottomRight)
if not WIREFRAME:
st.generate_normals()
self.mesh = st.commit()
self.generated = true
func dispose():
if self.mesh:
self.mesh = null
self.generated = false
func merge():
if self.level == 0:
return
if self.get_child_count() == 0:
return
for child in self.get_children():
child.merge()
child.dispose()
child.queue_free()
func subdivide():
if self.level == self.meta.get_detail_levels():
return
var lv = self.level + 1
var stepLeft = self.left * (self.radius / pow(2, lv))
var stepForward = self.forward * (self.radius / pow(2, lv))
self.add_child(CubeFace.new(lv, self.position + stepForward, self.normal, self.meta))
self.add_child(CubeFace.new(lv, (self.position + stepLeft) + stepForward, self.normal, self.meta))
self.add_child(CubeFace.new(lv, self.position, self.normal, self.meta))
self.add_child(CubeFace.new(lv, (self.position + stepLeft), self.normal, self.meta))
self.dispose()
class CubePlanet extends Spatial:
var faces = []
var meta
func _init(meta):
self.meta = meta
var hs = meta.get_radius() / 2.0
self.set_name("CubePlanet")
self.add_child(CubeFace.new(0, Vector3(0,0,-hs), Vector3(0,0,-1), self.meta)) # front
self.add_child(CubeFace.new(0, Vector3(0,0, hs), Vector3(0,0,1), self.meta)) # back
self.add_child(CubeFace.new(0, Vector3(-hs,0, 0), Vector3(-1,0,0), self.meta)) # left
self.add_child(CubeFace.new(0, Vector3(hs,0, 0), Vector3(1,0,0), self.meta)) # right
self.add_child(CubeFace.new(0, Vector3(0,hs,0), Vector3(0,1,0), self.meta)) # top
self.add_child(CubeFace.new(0, Vector3(0,-hs,0), Vector3(0,-1,0), self.meta)) # bottom
#self.get_child(0).subdivide()
var thread
# Called when the node enters the scene tree for the first time.
func _ready():
var noise = OpenSimplexNoise.new()
noise.seed = planet_terrain_seed
noise.octaves = terrain_octaves
noise.period = terrain_period
noise.persistence = terrain_period
noise.lacunarity = terrain_lacunarity
#var atmo = MeshInstance.new()
#var atmo_sphere = SphereMesh.new()
#var atmo_radius = planet_radius + 10
#atmo_sphere.set_radius(-atmo_radius)
#atmo_sphere.set_height(-atmo_radius * 2)
#atmo_sphere.material = atmosphere_material
#atmo_sphere.material.set_shader_param("ground_radius", atmo_radius)
#atmo_sphere.material.set_shader_param("atmosphere_radius", atmo_radius + .15)
#atmo.mesh = atmo_sphere
#add_child(atmo)
var planet = CubePlanet.new(PlanetMetadata.new(face_resolution, planet_radius, face_material, LOD_MAX, noise))
thread = PlanetThreading.new(planet)
add_child(planet)
func _process(delta):
if thread:
thread._tick()

BIN
space.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B