2016-06-18 14:46:12 +02:00
/**************************************************************************/
/* editor_preview_plugins.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2015-05-31 06:59:42 +02:00
# include "editor_preview_plugins.h"
2017-01-16 08:04:19 +01:00
2022-02-12 02:46:22 +01:00
# include "core/config/project_settings.h"
2018-09-11 18:13:45 +02:00
# include "core/io/file_access_memory.h"
# include "core/io/resource_loader.h"
2023-09-06 21:02:52 +02:00
# include "core/object/script_language.h"
2018-09-11 18:13:45 +02:00
# include "core/os/os.h"
2022-02-14 14:00:03 +01:00
# include "editor/editor_paths.h"
2017-03-05 14:21:25 +01:00
# include "editor/editor_settings.h"
2024-01-15 13:14:55 +01:00
# include "editor/themes/editor_scale.h"
2023-07-11 22:29:09 +02:00
# include "scene/resources/atlas_texture.h"
2019-02-12 17:18:13 +01:00
# include "scene/resources/bit_map.h"
2020-09-03 13:22:16 +02:00
# include "scene/resources/font.h"
2023-07-11 22:29:09 +02:00
# include "scene/resources/gradient_texture.h"
# include "scene/resources/image_texture.h"
2017-08-26 17:46:49 +02:00
# include "scene/resources/material.h"
2015-06-01 02:13:24 +02:00
# include "scene/resources/mesh.h"
2019-12-24 08:17:23 +01:00
# include "servers/audio/audio_stream.h"
2016-07-06 19:04:21 +02:00
2018-02-28 20:23:40 +01:00
void post_process_preview ( Ref < Image > p_image ) {
2020-05-14 16:41:43 +02:00
if ( p_image - > get_format ( ) ! = Image : : FORMAT_RGBA8 ) {
2017-12-30 13:38:51 +01:00
p_image - > convert ( Image : : FORMAT_RGBA8 ) ;
2020-05-14 16:41:43 +02:00
}
2017-12-30 13:38:51 +01:00
const int w = p_image - > get_width ( ) ;
const int h = p_image - > get_height ( ) ;
const int r = MIN ( w , h ) / 32 ;
const int r2 = r * r ;
Color transparent = Color ( 0 , 0 , 0 , 0 ) ;
for ( int i = 0 ; i < r ; i + + ) {
for ( int j = 0 ; j < r ; j + + ) {
int dx = i - r ;
int dy = j - r ;
if ( dx * dx + dy * dy > r2 ) {
p_image - > set_pixel ( i , j , transparent ) ;
p_image - > set_pixel ( w - 1 - i , j , transparent ) ;
p_image - > set_pixel ( w - 1 - i , h - 1 - j , transparent ) ;
p_image - > set_pixel ( i , h - 1 - j , transparent ) ;
} else {
break ;
}
}
}
}
2017-06-09 05:23:50 +02:00
bool EditorTexturePreviewPlugin : : handles ( const String & p_type ) const {
2019-06-11 20:43:37 +02:00
return ClassDB : : is_parent_class ( p_type , " Texture2D " ) ;
2015-05-31 06:59:42 +02:00
}
2019-05-20 10:45:12 +02:00
bool EditorTexturePreviewPlugin : : generate_small_preview_automatically ( ) const {
2018-09-12 13:10:49 +02:00
return true ;
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorTexturePreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2017-06-09 05:23:50 +02:00
Ref < Image > img ;
2016-01-19 04:27:27 +01:00
Ref < AtlasTexture > atex = p_from ;
if ( atex . is_valid ( ) ) {
2019-06-11 20:43:37 +02:00
Ref < Texture2D > tex = atex - > get_atlas ( ) ;
2016-01-19 04:27:27 +01:00
if ( ! tex . is_valid ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2016-01-19 04:27:27 +01:00
}
2019-02-27 01:44:09 +01:00
2021-03-28 13:32:17 +02:00
Ref < Image > atlas = tex - > get_image ( ) ;
2019-02-27 01:44:09 +01:00
if ( ! atlas . is_valid ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2019-02-27 01:44:09 +01:00
}
2022-09-18 02:19:55 +02:00
img = atlas - > get_region ( atex - > get_region ( ) ) ;
2017-06-09 05:23:50 +02:00
} else {
2019-06-11 20:43:37 +02:00
Ref < Texture2D > tex = p_from ;
2019-11-10 09:49:13 +01:00
if ( tex . is_valid ( ) ) {
2021-03-28 13:32:17 +02:00
img = tex - > get_image ( ) ;
2019-11-10 09:49:13 +01:00
if ( img . is_valid ( ) ) {
img = img - > duplicate ( ) ;
}
2019-01-27 17:39:16 +01:00
}
2016-01-19 04:27:27 +01:00
}
2020-12-15 13:04:21 +01:00
if ( img . is_null ( ) | | img - > is_empty ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2022-08-19 18:14:57 +02:00
p_metadata [ " dimensions " ] = img - > get_size ( ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
img - > clear_mipmaps ( ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
if ( img - > is_compressed ( ) ) {
2020-05-14 16:41:43 +02:00
if ( img - > decompress ( ) ! = OK ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-06-09 05:23:50 +02:00
} else if ( img - > get_format ( ) ! = Image : : FORMAT_RGB8 & & img - > get_format ( ) ! = Image : : FORMAT_RGBA8 ) {
img - > convert ( Image : : FORMAT_RGBA8 ) ;
2015-05-31 06:59:42 +02:00
}
2018-09-12 13:10:49 +02:00
Vector2 new_size = img - > get_size ( ) ;
if ( new_size . x > p_size . x ) {
new_size = Vector2 ( p_size . x , new_size . y * p_size . x / new_size . x ) ;
2015-05-31 06:59:42 +02:00
}
2018-09-12 13:10:49 +02:00
if ( new_size . y > p_size . y ) {
new_size = Vector2 ( new_size . x * p_size . y / new_size . y , p_size . y ) ;
}
2020-06-18 10:38:45 +02:00
Vector2i new_size_i ( MAX ( 1 , ( int ) new_size . x ) , MAX ( 1 , ( int ) new_size . y ) ) ;
img - > resize ( new_size_i . x , new_size_i . y , Image : : INTERPOLATE_CUBIC ) ;
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2015-05-31 06:59:42 +02:00
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2015-05-31 06:59:42 +02:00
}
EditorTexturePreviewPlugin : : EditorTexturePreviewPlugin ( ) {
2016-01-03 21:14:28 +01:00
}
////////////////////////////////////////////////////////////////////////////
2018-07-29 21:45:23 +02:00
bool EditorImagePreviewPlugin : : handles ( const String & p_type ) const {
return p_type = = " Image " ;
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorImagePreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2018-07-29 21:45:23 +02:00
Ref < Image > img = p_from ;
2020-12-15 13:04:21 +01:00
if ( img . is_null ( ) | | img - > is_empty ( ) ) {
2018-07-29 21:45:23 +02:00
return Ref < Image > ( ) ;
2020-05-14 16:41:43 +02:00
}
2018-07-29 21:45:23 +02:00
img = img - > duplicate ( ) ;
img - > clear_mipmaps ( ) ;
if ( img - > is_compressed ( ) ) {
2020-05-14 16:41:43 +02:00
if ( img - > decompress ( ) ! = OK ) {
2018-07-29 21:45:23 +02:00
return Ref < Image > ( ) ;
2020-05-14 16:41:43 +02:00
}
2018-07-29 21:45:23 +02:00
} else if ( img - > get_format ( ) ! = Image : : FORMAT_RGB8 & & img - > get_format ( ) ! = Image : : FORMAT_RGBA8 ) {
img - > convert ( Image : : FORMAT_RGBA8 ) ;
}
2018-09-12 13:10:49 +02:00
Vector2 new_size = img - > get_size ( ) ;
if ( new_size . x > p_size . x ) {
new_size = Vector2 ( p_size . x , new_size . y * p_size . x / new_size . x ) ;
}
if ( new_size . y > p_size . y ) {
new_size = Vector2 ( new_size . x * p_size . y / new_size . y , p_size . y ) ;
2018-07-29 21:45:23 +02:00
}
2018-09-12 13:10:49 +02:00
img - > resize ( new_size . x , new_size . y , Image : : INTERPOLATE_CUBIC ) ;
2018-07-29 21:45:23 +02:00
post_process_preview ( img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2018-07-29 21:45:23 +02:00
}
EditorImagePreviewPlugin : : EditorImagePreviewPlugin ( ) {
}
2019-05-20 10:45:12 +02:00
bool EditorImagePreviewPlugin : : generate_small_preview_automatically ( ) const {
2018-09-12 13:10:49 +02:00
return true ;
}
2020-05-14 14:29:06 +02:00
2018-07-29 21:45:23 +02:00
////////////////////////////////////////////////////////////////////////////
2022-02-06 14:12:19 +01:00
2017-06-09 05:23:50 +02:00
bool EditorBitmapPreviewPlugin : : handles ( const String & p_type ) const {
return ClassDB : : is_parent_class ( p_type , " BitMap " ) ;
2016-01-03 21:14:28 +01:00
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorBitmapPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2017-06-09 05:23:50 +02:00
Ref < BitMap > bm = p_from ;
2016-01-03 21:14:28 +01:00
2017-06-09 05:23:50 +02:00
if ( bm - > get_size ( ) = = Size2 ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2016-01-03 21:14:28 +01:00
}
2020-02-17 22:06:54 +01:00
Vector < uint8_t > data ;
2016-01-03 21:14:28 +01:00
2017-06-09 05:23:50 +02:00
data . resize ( bm - > get_size ( ) . width * bm - > get_size ( ) . height ) ;
2016-01-03 21:14:28 +01:00
{
2020-02-17 22:06:54 +01:00
uint8_t * w = data . ptrw ( ) ;
2016-01-03 21:14:28 +01:00
2017-06-09 05:23:50 +02:00
for ( int i = 0 ; i < bm - > get_size ( ) . width ; i + + ) {
for ( int j = 0 ; j < bm - > get_size ( ) . height ; j + + ) {
2022-09-01 18:39:17 +02:00
if ( bm - > get_bit ( i , j ) ) {
2020-02-17 22:06:54 +01:00
w [ j * ( int ) bm - > get_size ( ) . width + i ] = 255 ;
2016-01-03 21:14:28 +01:00
} else {
2020-02-17 22:06:54 +01:00
w [ j * ( int ) bm - > get_size ( ) . width + i ] = 0 ;
2016-01-03 21:14:28 +01:00
}
}
}
}
2022-07-22 20:06:19 +02:00
Ref < Image > img = Image : : create_from_data ( bm - > get_size ( ) . width , bm - > get_size ( ) . height , false , Image : : FORMAT_L8 , data ) ;
2016-01-03 21:14:28 +01:00
2017-06-09 05:23:50 +02:00
if ( img - > is_compressed ( ) ) {
2020-05-14 16:41:43 +02:00
if ( img - > decompress ( ) ! = OK ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-06-09 05:23:50 +02:00
} else if ( img - > get_format ( ) ! = Image : : FORMAT_RGB8 & & img - > get_format ( ) ! = Image : : FORMAT_RGBA8 ) {
img - > convert ( Image : : FORMAT_RGBA8 ) ;
2016-01-03 21:14:28 +01:00
}
2018-09-12 13:10:49 +02:00
Vector2 new_size = img - > get_size ( ) ;
if ( new_size . x > p_size . x ) {
new_size = Vector2 ( p_size . x , new_size . y * p_size . x / new_size . x ) ;
}
if ( new_size . y > p_size . y ) {
new_size = Vector2 ( new_size . x * p_size . y / new_size . y , p_size . y ) ;
2016-01-03 21:14:28 +01:00
}
2018-09-12 13:10:49 +02:00
img - > resize ( new_size . x , new_size . y , Image : : INTERPOLATE_CUBIC ) ;
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2016-01-03 21:14:28 +01:00
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2016-01-03 21:14:28 +01:00
}
2019-05-20 10:45:12 +02:00
bool EditorBitmapPreviewPlugin : : generate_small_preview_automatically ( ) const {
2018-09-12 13:10:49 +02:00
return true ;
}
2016-01-03 21:14:28 +01:00
EditorBitmapPreviewPlugin : : EditorBitmapPreviewPlugin ( ) {
2015-05-31 06:59:42 +02:00
}
///////////////////////////////////////////////////////////////////////////
2017-06-09 05:23:50 +02:00
bool EditorPackedScenePreviewPlugin : : handles ( const String & p_type ) const {
return ClassDB : : is_parent_class ( p_type , " PackedScene " ) ;
}
2019-06-11 20:43:37 +02:00
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorPackedScenePreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
return generate_from_path ( p_from - > get_path ( ) , p_size , p_metadata ) ;
2017-06-09 05:23:50 +02:00
}
2015-05-31 06:59:42 +02:00
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorPackedScenePreviewPlugin : : generate_from_path ( const String & p_path , const Size2 & p_size , Dictionary & p_metadata ) const {
2021-05-25 02:25:11 +02:00
String temp_path = EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) ;
2017-07-19 22:00:46 +02:00
String cache_base = ProjectSettings : : get_singleton ( ) - > globalize_path ( p_path ) . md5_text ( ) ;
2022-08-30 02:34:01 +02:00
cache_base = temp_path . path_join ( " resthumb- " + cache_base ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
//does not have it, try to load a cached thumbnail
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
String path = cache_base + " .png " ;
2015-05-31 06:59:42 +02:00
2020-05-14 16:41:43 +02:00
if ( ! FileAccess : : exists ( path ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
Ref < Image > img ;
2021-06-18 00:03:09 +02:00
img . instantiate ( ) ;
2017-06-09 05:23:50 +02:00
Error err = img - > load ( path ) ;
if ( err = = OK ) {
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
} else {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2017-06-09 05:23:50 +02:00
}
2015-05-31 06:59:42 +02:00
}
2017-06-09 05:23:50 +02:00
EditorPackedScenePreviewPlugin : : EditorPackedScenePreviewPlugin ( ) {
2015-05-31 06:59:42 +02:00
}
2017-06-09 05:23:50 +02:00
//////////////////////////////////////////////////////////////////
2021-11-05 07:43:03 +01:00
void EditorMaterialPreviewPlugin : : _generate_frame_started ( ) {
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_ONCE ) ; //once used for capture
RS : : get_singleton ( ) - > request_frame_drawn_callback ( callable_mp ( const_cast < EditorMaterialPreviewPlugin * > ( this ) , & EditorMaterialPreviewPlugin : : _preview_done ) ) ;
}
2021-11-05 06:59:38 +01:00
void EditorMaterialPreviewPlugin : : _preview_done ( ) {
2021-11-05 07:43:03 +01:00
preview_done . post ( ) ;
2015-05-31 06:59:42 +02:00
}
2023-11-10 15:27:51 +01:00
void EditorMaterialPreviewPlugin : : abort ( ) {
preview_done . post ( ) ;
}
2017-06-09 05:23:50 +02:00
bool EditorMaterialPreviewPlugin : : handles ( const String & p_type ) const {
2022-02-06 14:12:19 +01:00
return ClassDB : : is_parent_class ( p_type , " Material " ) ; // Any material.
2015-05-31 06:59:42 +02:00
}
2019-05-20 10:45:12 +02:00
bool EditorMaterialPreviewPlugin : : generate_small_preview_automatically ( ) const {
2018-09-12 13:10:49 +02:00
return true ;
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorMaterialPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2015-05-31 06:59:42 +02:00
Ref < Material > material = p_from ;
2019-06-11 20:43:37 +02:00
ERR_FAIL_COND_V ( material . is_null ( ) , Ref < Texture2D > ( ) ) ;
2015-05-31 06:59:42 +02:00
2017-12-06 23:43:22 +01:00
if ( material - > get_shader_mode ( ) = = Shader : : MODE_SPATIAL ) {
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > mesh_surface_set_material ( sphere , 0 , material - > get_rid ( ) ) ;
2015-05-31 06:59:42 +02:00
2022-09-01 15:44:42 +02:00
RS : : get_singleton ( ) - > connect ( SNAME ( " frame_pre_draw " ) , callable_mp ( const_cast < EditorMaterialPreviewPlugin * > ( this ) , & EditorMaterialPreviewPlugin : : _generate_frame_started ) , Object : : CONNECT_ONE_SHOT ) ;
2015-05-31 06:59:42 +02:00
2021-11-05 07:43:03 +01:00
preview_done . wait ( ) ;
2015-05-31 06:59:42 +02:00
2020-03-27 19:21:27 +01:00
Ref < Image > img = RS : : get_singleton ( ) - > texture_2d_get ( viewport_texture ) ;
RS : : get_singleton ( ) - > mesh_surface_set_material ( sphere , 0 , RID ( ) ) ;
2015-05-31 06:59:42 +02:00
2017-12-06 23:43:22 +01:00
ERR_FAIL_COND_V ( ! img . is_valid ( ) , Ref < ImageTexture > ( ) ) ;
img - > convert ( Image : : FORMAT_RGBA8 ) ;
2018-09-12 13:10:49 +02:00
int thumbnail_size = MAX ( p_size . x , p_size . y ) ;
img - > resize ( thumbnail_size , thumbnail_size , Image : : INTERPOLATE_CUBIC ) ;
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2017-12-06 23:43:22 +01:00
}
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2015-05-31 06:59:42 +02:00
}
EditorMaterialPreviewPlugin : : EditorMaterialPreviewPlugin ( ) {
2020-03-27 19:21:27 +01:00
scenario = RS : : get_singleton ( ) - > scenario_create ( ) ;
2015-05-31 06:59:42 +02:00
2020-03-27 19:21:27 +01:00
viewport = RS : : get_singleton ( ) - > viewport_create ( ) ;
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_DISABLED ) ;
RS : : get_singleton ( ) - > viewport_set_scenario ( viewport , scenario ) ;
RS : : get_singleton ( ) - > viewport_set_size ( viewport , 128 , 128 ) ;
RS : : get_singleton ( ) - > viewport_set_transparent_background ( viewport , true ) ;
RS : : get_singleton ( ) - > viewport_set_active ( viewport , true ) ;
viewport_texture = RS : : get_singleton ( ) - > viewport_get_texture ( viewport ) ;
2015-05-31 06:59:42 +02:00
2020-03-27 19:21:27 +01:00
camera = RS : : get_singleton ( ) - > camera_create ( ) ;
RS : : get_singleton ( ) - > viewport_attach_camera ( viewport , camera ) ;
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > camera_set_transform ( camera , Transform3D ( Basis ( ) , Vector3 ( 0 , 0 , 3 ) ) ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > camera_set_perspective ( camera , 45 , 0.1 , 10 ) ;
2015-05-31 06:59:42 +02:00
2022-08-01 01:20:24 +02:00
if ( GLOBAL_GET ( " rendering/lights_and_shadows/use_physical_light_units " ) ) {
camera_attributes = RS : : get_singleton ( ) - > camera_attributes_create ( ) ;
RS : : get_singleton ( ) - > camera_attributes_set_exposure ( camera_attributes , 1.0 , 0.000032552 ) ; // Matches default CameraAttributesPhysical to work well with default DirectionalLight3Ds.
RS : : get_singleton ( ) - > camera_set_camera_attributes ( camera , camera_attributes ) ;
}
2020-03-27 19:21:27 +01:00
light = RS : : get_singleton ( ) - > directional_light_create ( ) ;
light_instance = RS : : get_singleton ( ) - > instance_create2 ( light , scenario ) ;
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > instance_set_transform ( light_instance , Transform3D ( ) . looking_at ( Vector3 ( - 1 , - 1 , - 1 ) , Vector3 ( 0 , 1 , 0 ) ) ) ;
2015-05-31 06:59:42 +02:00
2020-03-27 19:21:27 +01:00
light2 = RS : : get_singleton ( ) - > directional_light_create ( ) ;
RS : : get_singleton ( ) - > light_set_color ( light2 , Color ( 0.7 , 0.7 , 0.7 ) ) ;
//RS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
2017-06-09 05:23:50 +02:00
2020-03-27 19:21:27 +01:00
light_instance2 = RS : : get_singleton ( ) - > instance_create2 ( light2 , scenario ) ;
2015-05-31 06:59:42 +02:00
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > instance_set_transform ( light_instance2 , Transform3D ( ) . looking_at ( Vector3 ( 0 , 1 , 0 ) , Vector3 ( 0 , 0 , 1 ) ) ) ;
2015-05-31 06:59:42 +02:00
2020-03-27 19:21:27 +01:00
sphere = RS : : get_singleton ( ) - > mesh_create ( ) ;
sphere_instance = RS : : get_singleton ( ) - > instance_create2 ( sphere , scenario ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
int lats = 32 ;
int lons = 32 ;
2020-04-03 11:50:40 +02:00
const double lat_step = Math_TAU / lats ;
const double lon_step = Math_TAU / lons ;
real_t radius = 1.0 ;
2015-05-31 06:59:42 +02:00
2020-02-17 22:06:54 +01:00
Vector < Vector3 > vertices ;
Vector < Vector3 > normals ;
Vector < Vector2 > uvs ;
2021-08-10 00:15:17 +02:00
Vector < real_t > tangents ;
2017-06-09 05:23:50 +02:00
Basis tt = Basis ( Vector3 ( 0 , 1 , 0 ) , Math_PI * 0.5 ) ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
for ( int i = 1 ; i < = lats ; i + + ) {
2020-04-03 11:50:40 +02:00
double lat0 = lat_step * ( i - 1 ) - Math_TAU / 4 ;
2017-06-09 05:23:50 +02:00
double z0 = Math : : sin ( lat0 ) ;
double zr0 = Math : : cos ( lat0 ) ;
2015-05-31 06:59:42 +02:00
2020-04-03 11:50:40 +02:00
double lat1 = lat_step * i - Math_TAU / 4 ;
2015-05-31 06:59:42 +02:00
double z1 = Math : : sin ( lat1 ) ;
double zr1 = Math : : cos ( lat1 ) ;
2017-06-09 05:23:50 +02:00
for ( int j = lons ; j > = 1 ; j - - ) {
2020-04-03 11:50:40 +02:00
double lng0 = lon_step * ( j - 1 ) ;
2015-05-31 06:59:42 +02:00
double x0 = Math : : cos ( lng0 ) ;
double y0 = Math : : sin ( lng0 ) ;
2020-04-03 11:50:40 +02:00
double lng1 = lon_step * j ;
2015-05-31 06:59:42 +02:00
double x1 = Math : : cos ( lng1 ) ;
double y1 = Math : : sin ( lng1 ) ;
2017-06-09 05:23:50 +02:00
Vector3 v [ 4 ] = {
Vector3 ( x1 * zr0 , z0 , y1 * zr0 ) ,
Vector3 ( x1 * zr1 , z1 , y1 * zr1 ) ,
Vector3 ( x0 * zr1 , z1 , y0 * zr1 ) ,
Vector3 ( x0 * zr0 , z0 , y0 * zr0 )
2015-05-31 06:59:42 +02:00
} ;
# define ADD_POINT(m_idx) \
normals . push_back ( v [ m_idx ] ) ; \
vertices . push_back ( v [ m_idx ] * radius ) ; \
{ \
Vector2 uv ( Math : : atan2 ( v [ m_idx ] . x , v [ m_idx ] . z ) , Math : : atan2 ( - v [ m_idx ] . y , v [ m_idx ] . z ) ) ; \
uv / = Math_PI ; \
uv * = 4.0 ; \
uv = uv * 0.5 + Vector2 ( 0.5 , 0.5 ) ; \
uvs . push_back ( uv ) ; \
} \
{ \
Vector3 t = tt . xform ( v [ m_idx ] ) ; \
tangents . push_back ( t . x ) ; \
tangents . push_back ( t . y ) ; \
tangents . push_back ( t . z ) ; \
tangents . push_back ( 1.0 ) ; \
}
ADD_POINT ( 0 ) ;
ADD_POINT ( 1 ) ;
ADD_POINT ( 2 ) ;
ADD_POINT ( 2 ) ;
ADD_POINT ( 3 ) ;
ADD_POINT ( 0 ) ;
}
}
Array arr ;
2020-03-27 19:21:27 +01:00
arr . resize ( RS : : ARRAY_MAX ) ;
arr [ RS : : ARRAY_VERTEX ] = vertices ;
arr [ RS : : ARRAY_NORMAL ] = normals ;
arr [ RS : : ARRAY_TANGENT ] = tangents ;
arr [ RS : : ARRAY_TEX_UV ] = uvs ;
RS : : get_singleton ( ) - > mesh_add_surface_from_arrays ( sphere , RS : : PRIMITIVE_TRIANGLES , arr ) ;
2015-05-31 06:59:42 +02:00
}
EditorMaterialPreviewPlugin : : ~ EditorMaterialPreviewPlugin ( ) {
2022-12-12 18:42:37 +01:00
ERR_FAIL_NULL ( RenderingServer : : get_singleton ( ) ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > free ( sphere ) ;
RS : : get_singleton ( ) - > free ( sphere_instance ) ;
RS : : get_singleton ( ) - > free ( viewport ) ;
RS : : get_singleton ( ) - > free ( light ) ;
RS : : get_singleton ( ) - > free ( light_instance ) ;
RS : : get_singleton ( ) - > free ( light2 ) ;
RS : : get_singleton ( ) - > free ( light_instance2 ) ;
RS : : get_singleton ( ) - > free ( camera ) ;
2022-08-01 01:20:24 +02:00
RS : : get_singleton ( ) - > free ( camera_attributes ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > free ( scenario ) ;
2015-05-31 06:59:42 +02:00
}
///////////////////////////////////////////////////////////////////////////
2017-06-09 05:23:50 +02:00
bool EditorScriptPreviewPlugin : : handles ( const String & p_type ) const {
return ClassDB : : is_parent_class ( p_type , " Script " ) ;
2015-05-31 06:59:42 +02:00
}
2024-01-26 13:03:32 +01:00
Ref < Texture2D > EditorScriptPreviewPlugin : : generate_from_path ( const String & p_path , const Size2 & p_size , Dictionary & p_metadata ) const {
Error err ;
String code = FileAccess : : get_file_as_string ( p_path , & err ) ;
if ( err ! = OK ) {
return Ref < Texture2D > ( ) ;
}
ScriptLanguage * lang = ScriptServer : : get_language_for_extension ( p_path . get_extension ( ) ) ;
return _generate_from_source_code ( lang , code , p_size , p_metadata ) ;
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorScriptPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2015-05-31 06:59:42 +02:00
Ref < Script > scr = p_from ;
2020-05-14 16:41:43 +02:00
if ( scr . is_null ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2015-05-31 06:59:42 +02:00
String code = scr - > get_source_code ( ) . strip_edges ( ) ;
2024-01-26 13:03:32 +01:00
return _generate_from_source_code ( scr - > get_language ( ) , code , p_size , p_metadata ) ;
}
Ref < Texture2D > EditorScriptPreviewPlugin : : _generate_from_source_code ( const ScriptLanguage * p_language , const String & p_source_code , const Size2 & p_size , Dictionary & p_metadata ) const {
if ( p_source_code . is_empty ( ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2015-05-31 06:59:42 +02:00
List < String > kwors ;
2024-01-26 13:03:32 +01:00
if ( p_language ) {
p_language - > get_reserved_words ( & kwors ) ;
}
2015-05-31 06:59:42 +02:00
2022-05-19 17:00:06 +02:00
HashSet < String > control_flow_keywords ;
HashSet < String > keywords ;
2015-05-31 06:59:42 +02:00
2021-07-24 15:46:25 +02:00
for ( const String & E : kwors ) {
2024-01-26 13:03:32 +01:00
if ( p_language & & p_language - > is_control_flow_keyword ( E ) ) {
2021-07-16 05:45:57 +02:00
control_flow_keywords . insert ( E ) ;
2021-04-08 16:12:22 +02:00
} else {
2021-07-16 05:45:57 +02:00
keywords . insert ( E ) ;
2021-04-08 16:12:22 +02:00
}
2015-05-31 06:59:42 +02:00
}
int line = 0 ;
2017-06-09 05:23:50 +02:00
int col = 0 ;
2018-09-12 13:10:49 +02:00
int thumbnail_size = MAX ( p_size . x , p_size . y ) ;
2022-07-22 20:06:19 +02:00
Ref < Image > img = Image : : create_empty ( thumbnail_size , thumbnail_size , false , Image : : FORMAT_RGBA8 ) ;
2015-05-31 06:59:42 +02:00
2022-10-18 16:43:37 +02:00
Color bg_color = EDITOR_GET ( " text_editor/theme/highlighting/background_color " ) ;
Color keyword_color = EDITOR_GET ( " text_editor/theme/highlighting/keyword_color " ) ;
Color control_flow_keyword_color = EDITOR_GET ( " text_editor/theme/highlighting/control_flow_keyword_color " ) ;
Color text_color = EDITOR_GET ( " text_editor/theme/highlighting/text_color " ) ;
Color symbol_color = EDITOR_GET ( " text_editor/theme/highlighting/symbol_color " ) ;
Color comment_color = EDITOR_GET ( " text_editor/theme/highlighting/comment_color " ) ;
2023-02-05 10:01:01 +01:00
Color doc_comment_color = EDITOR_GET ( " text_editor/theme/highlighting/doc_comment_color " ) ;
2015-05-31 06:59:42 +02:00
2020-05-14 16:41:43 +02:00
if ( bg_color . a = = 0 ) {
2017-12-30 13:38:51 +01:00
bg_color = Color ( 0 , 0 , 0 , 0 ) ;
2020-05-14 16:41:43 +02:00
}
2024-01-26 13:03:32 +01:00
bg_color . a = MAX ( bg_color . a , 0.2 ) ; // Ensure we have some background, regardless of the text editor setting.
2017-12-30 13:38:51 +01:00
2022-01-08 12:58:15 +01:00
img - > fill ( bg_color ) ;
2015-05-31 06:59:42 +02:00
2017-12-30 13:38:51 +01:00
const int x0 = thumbnail_size / 8 ;
const int y0 = thumbnail_size / 8 ;
const int available_height = thumbnail_size - 2 * y0 ;
col = x0 ;
2017-06-09 05:23:50 +02:00
bool prev_is_text = false ;
2021-04-08 16:12:22 +02:00
bool in_control_flow_keyword = false ;
2017-06-09 05:23:50 +02:00
bool in_keyword = false ;
2021-05-03 02:48:37 +02:00
bool in_comment = false ;
2023-02-05 10:01:01 +01:00
bool in_doc_comment = false ;
2024-01-26 13:03:32 +01:00
for ( int i = 0 ; i < p_source_code . length ( ) ; i + + ) {
char32_t c = p_source_code [ i ] ;
2017-06-09 05:23:50 +02:00
if ( c > 32 ) {
if ( col < thumbnail_size ) {
2015-05-31 06:59:42 +02:00
Color color = text_color ;
2021-05-03 02:48:37 +02:00
if ( c = = ' # ' ) {
2024-01-26 13:03:32 +01:00
if ( i < p_source_code . length ( ) - 1 & & p_source_code [ i + 1 ] = = ' # ' ) {
2023-02-05 10:01:01 +01:00
in_doc_comment = true ;
} else {
in_comment = true ;
}
2021-05-03 02:48:37 +02:00
}
2015-05-31 06:59:42 +02:00
2021-05-03 02:48:37 +02:00
if ( in_comment ) {
color = comment_color ;
2023-02-05 10:01:01 +01:00
} else if ( in_doc_comment ) {
color = doc_comment_color ;
2021-05-03 02:48:37 +02:00
} else {
2022-02-04 09:32:20 +01:00
if ( is_symbol ( c ) ) {
2024-01-26 13:03:32 +01:00
// Make symbol a little visible.
2021-05-03 02:48:37 +02:00
color = symbol_color ;
2021-04-08 16:12:22 +02:00
in_control_flow_keyword = false ;
2021-05-03 02:48:37 +02:00
in_keyword = false ;
2022-02-04 09:32:20 +01:00
} else if ( ! prev_is_text & & is_ascii_identifier_char ( c ) ) {
2021-05-03 02:48:37 +02:00
int pos = i ;
2024-01-26 13:03:32 +01:00
while ( is_ascii_identifier_char ( p_source_code [ pos ] ) ) {
2021-05-03 02:48:37 +02:00
pos + + ;
}
2024-01-26 13:03:32 +01:00
String word = p_source_code . substr ( i , pos - i ) ;
2021-04-08 16:12:22 +02:00
if ( control_flow_keywords . has ( word ) ) {
in_control_flow_keyword = true ;
} else if ( keywords . has ( word ) ) {
2021-05-03 02:48:37 +02:00
in_keyword = true ;
}
2022-02-04 09:32:20 +01:00
} else if ( ! is_ascii_identifier_char ( c ) ) {
2021-05-03 02:48:37 +02:00
in_keyword = false ;
2020-05-14 16:41:43 +02:00
}
2015-05-31 06:59:42 +02:00
2021-04-08 16:12:22 +02:00
if ( in_control_flow_keyword ) {
color = control_flow_keyword_color ;
} else if ( in_keyword ) {
2021-05-03 02:48:37 +02:00
color = keyword_color ;
}
2020-05-14 16:41:43 +02:00
}
2017-06-09 05:23:50 +02:00
Color ul = color ;
ul . a * = 0.5 ;
2017-12-30 13:38:51 +01:00
img - > set_pixel ( col , y0 + line * 2 , bg_color . blend ( ul ) ) ;
img - > set_pixel ( col , y0 + line * 2 + 1 , color ) ;
2015-05-31 06:59:42 +02:00
2022-02-04 09:32:20 +01:00
prev_is_text = is_ascii_identifier_char ( c ) ;
2015-05-31 06:59:42 +02:00
}
2021-05-03 02:48:37 +02:00
col + + ;
2015-05-31 06:59:42 +02:00
} else {
2017-06-09 05:23:50 +02:00
prev_is_text = false ;
2021-04-08 16:12:22 +02:00
in_control_flow_keyword = false ;
2017-06-09 05:23:50 +02:00
in_keyword = false ;
2015-05-31 06:59:42 +02:00
2017-06-09 05:23:50 +02:00
if ( c = = ' \n ' ) {
2021-05-03 02:48:37 +02:00
in_comment = false ;
2023-02-05 10:01:01 +01:00
in_doc_comment = false ;
2021-05-03 02:48:37 +02:00
2017-12-30 13:38:51 +01:00
col = x0 ;
2015-05-31 06:59:42 +02:00
line + + ;
2020-05-14 16:41:43 +02:00
if ( line > = available_height / 2 ) {
2015-05-31 06:59:42 +02:00
break ;
2020-05-14 16:41:43 +02:00
}
2017-06-09 05:23:50 +02:00
} else if ( c = = ' \t ' ) {
col + = 3 ;
2021-05-03 02:48:37 +02:00
} else {
col + + ;
2015-05-31 06:59:42 +02:00
}
}
}
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2015-05-31 06:59:42 +02:00
}
EditorScriptPreviewPlugin : : EditorScriptPreviewPlugin ( ) {
}
2020-05-14 14:29:06 +02:00
2015-05-31 06:59:42 +02:00
///////////////////////////////////////////////////////////////////
2017-08-26 17:46:49 +02:00
2018-06-07 17:46:14 +02:00
bool EditorAudioStreamPreviewPlugin : : handles ( const String & p_type ) const {
return ClassDB : : is_parent_class ( p_type , " AudioStream " ) ;
2015-05-31 06:59:42 +02:00
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorAudioStreamPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2018-06-07 17:46:14 +02:00
Ref < AudioStream > stream = p_from ;
2019-06-11 20:43:37 +02:00
ERR_FAIL_COND_V ( stream . is_null ( ) , Ref < Texture2D > ( ) ) ;
2015-05-31 06:59:42 +02:00
2020-02-17 22:06:54 +01:00
Vector < uint8_t > img ;
2018-09-12 13:10:49 +02:00
int w = p_size . x ;
int h = p_size . y ;
2018-06-07 17:46:14 +02:00
img . resize ( w * h * 3 ) ;
2015-05-31 06:59:42 +02:00
2020-02-17 22:06:54 +01:00
uint8_t * imgdata = img . ptrw ( ) ;
uint8_t * imgw = imgdata ;
2015-05-31 06:59:42 +02:00
2022-07-21 01:00:58 +02:00
Ref < AudioStreamPlayback > playback = stream - > instantiate_playback ( ) ;
2019-06-11 20:43:37 +02:00
ERR_FAIL_COND_V ( playback . is_null ( ) , Ref < Texture2D > ( ) ) ;
2015-05-31 06:59:42 +02:00
2021-08-10 00:15:17 +02:00
real_t len_s = stream - > get_length ( ) ;
2018-06-07 17:46:14 +02:00
if ( len_s = = 0 ) {
len_s = 60 ; //one minute audio if no length specified
}
int frame_length = AudioServer : : get_singleton ( ) - > get_mix_rate ( ) * len_s ;
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
Vector < AudioFrame > frames ;
frames . resize ( frame_length ) ;
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
playback - > start ( ) ;
playback - > mix ( frames . ptrw ( ) , 1 , frames . size ( ) ) ;
playback - > stop ( ) ;
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
for ( int i = 0 ; i < w ; i + + ) {
2021-08-10 00:15:17 +02:00
real_t max = - 1000 ;
real_t min = 1000 ;
2018-06-07 17:46:14 +02:00
int from = uint64_t ( i ) * frame_length / w ;
2019-06-03 21:52:50 +02:00
int to = ( uint64_t ( i ) + 1 ) * frame_length / w ;
2018-06-07 17:46:14 +02:00
to = MIN ( to , frame_length ) ;
from = MIN ( from , frame_length - 1 ) ;
if ( to = = from ) {
to = from + 1 ;
}
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
for ( int j = from ; j < to ; j + + ) {
max = MAX ( max , frames [ j ] . l ) ;
max = MAX ( max , frames [ j ] . r ) ;
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
min = MIN ( min , frames [ j ] . l ) ;
min = MIN ( min , frames [ j ] . r ) ;
}
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
int pfrom = CLAMP ( ( min * 0.5 + 0.5 ) * h / 2 , 0 , h / 2 ) + h / 4 ;
int pto = CLAMP ( ( max * 0.5 + 0.5 ) * h / 2 , 0 , h / 2 ) + h / 4 ;
2015-05-31 06:59:42 +02:00
2018-06-07 17:46:14 +02:00
for ( int j = 0 ; j < h ; j + + ) {
uint8_t * p = & imgw [ ( j * w + i ) * 3 ] ;
if ( j < pfrom | | j > pto ) {
p [ 0 ] = 100 ;
p [ 1 ] = 100 ;
p [ 2 ] = 100 ;
2015-05-31 06:59:42 +02:00
} else {
2018-06-07 17:46:14 +02:00
p [ 0 ] = 180 ;
p [ 1 ] = 180 ;
p [ 2 ] = 180 ;
2015-05-31 06:59:42 +02:00
}
}
}
2018-06-07 17:46:14 +02:00
//post_process_preview(img);
2015-05-31 06:59:42 +02:00
2022-07-22 20:06:19 +02:00
Ref < Image > image = Image : : create_from_data ( w , h , false , Image : : FORMAT_RGB8 , img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( image ) ;
2015-05-31 06:59:42 +02:00
}
2018-06-07 17:46:14 +02:00
EditorAudioStreamPreviewPlugin : : EditorAudioStreamPreviewPlugin ( ) {
2015-05-31 06:59:42 +02:00
}
2017-08-26 17:46:49 +02:00
2015-05-31 06:59:42 +02:00
///////////////////////////////////////////////////////////////////////////
2015-06-01 02:13:24 +02:00
2021-11-05 07:43:03 +01:00
void EditorMeshPreviewPlugin : : _generate_frame_started ( ) {
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_ONCE ) ; //once used for capture
RS : : get_singleton ( ) - > request_frame_drawn_callback ( callable_mp ( const_cast < EditorMeshPreviewPlugin * > ( this ) , & EditorMeshPreviewPlugin : : _preview_done ) ) ;
}
2021-11-05 06:59:38 +01:00
void EditorMeshPreviewPlugin : : _preview_done ( ) {
2021-11-05 07:43:03 +01:00
preview_done . post ( ) ;
2015-06-01 02:13:24 +02:00
}
2023-11-10 15:27:51 +01:00
void EditorMeshPreviewPlugin : : abort ( ) {
preview_done . post ( ) ;
}
2017-06-09 05:23:50 +02:00
bool EditorMeshPreviewPlugin : : handles ( const String & p_type ) const {
2022-02-06 14:12:19 +01:00
return ClassDB : : is_parent_class ( p_type , " Mesh " ) ; // Any mesh.
2017-06-09 05:23:50 +02:00
}
2015-06-01 02:13:24 +02:00
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorMeshPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2015-06-01 02:13:24 +02:00
Ref < Mesh > mesh = p_from ;
2019-06-11 20:43:37 +02:00
ERR_FAIL_COND_V ( mesh . is_null ( ) , Ref < Texture2D > ( ) ) ;
2015-06-01 02:13:24 +02:00
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > instance_set_base ( mesh_instance , mesh - > get_rid ( ) ) ;
2015-06-01 02:13:24 +02:00
2017-11-17 03:09:00 +01:00
AABB aabb = mesh - > get_aabb ( ) ;
2021-09-20 20:48:52 +02:00
Vector3 ofs = aabb . get_center ( ) ;
2017-06-06 20:33:51 +02:00
aabb . position - = ofs ;
2020-10-17 07:08:21 +02:00
Transform3D xform ;
2017-06-09 05:23:50 +02:00
xform . basis = Basis ( ) . rotated ( Vector3 ( 0 , 1 , 0 ) , - Math_PI * 0.125 ) ;
xform . basis = Basis ( ) . rotated ( Vector3 ( 1 , 0 , 0 ) , Math_PI * 0.125 ) * xform . basis ;
2017-11-17 03:09:00 +01:00
AABB rot_aabb = xform . xform ( aabb ) ;
2021-06-21 05:30:19 +02:00
real_t m = MAX ( rot_aabb . size . x , rot_aabb . size . y ) * 0.5 ;
2020-05-14 16:41:43 +02:00
if ( m = = 0 ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2020-05-14 16:41:43 +02:00
}
2017-06-09 05:23:50 +02:00
m = 1.0 / m ;
m * = 0.5 ;
xform . basis . scale ( Vector3 ( m , m , m ) ) ;
xform . origin = - xform . basis . xform ( ofs ) ; //-ofs*m;
xform . origin . z - = rot_aabb . size . z * 2 ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > instance_set_transform ( mesh_instance , xform ) ;
2015-06-01 02:13:24 +02:00
2022-09-01 15:44:42 +02:00
RS : : get_singleton ( ) - > connect ( SNAME ( " frame_pre_draw " ) , callable_mp ( const_cast < EditorMeshPreviewPlugin * > ( this ) , & EditorMeshPreviewPlugin : : _generate_frame_started ) , Object : : CONNECT_ONE_SHOT ) ;
2015-06-01 02:13:24 +02:00
2021-11-05 07:43:03 +01:00
preview_done . wait ( ) ;
2015-06-01 02:13:24 +02:00
2020-03-27 19:21:27 +01:00
Ref < Image > img = RS : : get_singleton ( ) - > texture_2d_get ( viewport_texture ) ;
2017-06-09 05:23:50 +02:00
ERR_FAIL_COND_V ( img . is_null ( ) , Ref < ImageTexture > ( ) ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > instance_set_base ( mesh_instance , RID ( ) ) ;
2015-06-01 02:13:24 +02:00
2017-06-09 05:23:50 +02:00
img - > convert ( Image : : FORMAT_RGBA8 ) ;
2018-09-12 13:10:49 +02:00
Vector2 new_size = img - > get_size ( ) ;
if ( new_size . x > p_size . x ) {
new_size = Vector2 ( p_size . x , new_size . y * p_size . x / new_size . x ) ;
}
if ( new_size . y > p_size . y ) {
new_size = Vector2 ( new_size . x * p_size . y / new_size . y , p_size . y ) ;
}
img - > resize ( new_size . x , new_size . y , Image : : INTERPOLATE_CUBIC ) ;
2017-12-30 13:38:51 +01:00
post_process_preview ( img ) ;
2015-06-01 02:13:24 +02:00
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2015-06-01 02:13:24 +02:00
}
EditorMeshPreviewPlugin : : EditorMeshPreviewPlugin ( ) {
2020-03-27 19:21:27 +01:00
scenario = RS : : get_singleton ( ) - > scenario_create ( ) ;
2017-06-09 05:23:50 +02:00
2020-03-27 19:21:27 +01:00
viewport = RS : : get_singleton ( ) - > viewport_create ( ) ;
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_DISABLED ) ;
RS : : get_singleton ( ) - > viewport_set_scenario ( viewport , scenario ) ;
RS : : get_singleton ( ) - > viewport_set_size ( viewport , 128 , 128 ) ;
RS : : get_singleton ( ) - > viewport_set_transparent_background ( viewport , true ) ;
RS : : get_singleton ( ) - > viewport_set_active ( viewport , true ) ;
viewport_texture = RS : : get_singleton ( ) - > viewport_get_texture ( viewport ) ;
2015-06-01 02:13:24 +02:00
2020-03-27 19:21:27 +01:00
camera = RS : : get_singleton ( ) - > camera_create ( ) ;
RS : : get_singleton ( ) - > viewport_attach_camera ( viewport , camera ) ;
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > camera_set_transform ( camera , Transform3D ( Basis ( ) , Vector3 ( 0 , 0 , 3 ) ) ) ;
2020-03-27 19:21:27 +01:00
//RS::get_singleton()->camera_set_perspective(camera,45,0.1,10);
RS : : get_singleton ( ) - > camera_set_orthogonal ( camera , 1.0 , 0.01 , 1000.0 ) ;
2015-06-01 02:13:24 +02:00
2022-08-01 01:20:24 +02:00
if ( GLOBAL_GET ( " rendering/lights_and_shadows/use_physical_light_units " ) ) {
camera_attributes = RS : : get_singleton ( ) - > camera_attributes_create ( ) ;
RS : : get_singleton ( ) - > camera_attributes_set_exposure ( camera_attributes , 1.0 , 0.000032552 ) ; // Matches default CameraAttributesPhysical to work well with default DirectionalLight3Ds.
RS : : get_singleton ( ) - > camera_set_camera_attributes ( camera , camera_attributes ) ;
}
2020-03-27 19:21:27 +01:00
light = RS : : get_singleton ( ) - > directional_light_create ( ) ;
light_instance = RS : : get_singleton ( ) - > instance_create2 ( light , scenario ) ;
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > instance_set_transform ( light_instance , Transform3D ( ) . looking_at ( Vector3 ( - 1 , - 1 , - 1 ) , Vector3 ( 0 , 1 , 0 ) ) ) ;
2015-06-01 02:13:24 +02:00
2020-03-27 19:21:27 +01:00
light2 = RS : : get_singleton ( ) - > directional_light_create ( ) ;
RS : : get_singleton ( ) - > light_set_color ( light2 , Color ( 0.7 , 0.7 , 0.7 ) ) ;
//RS::get_singleton()->light_set_color(light2, RS::LIGHT_COLOR_SPECULAR, Color(0.0, 0.0, 0.0));
light_instance2 = RS : : get_singleton ( ) - > instance_create2 ( light2 , scenario ) ;
2015-06-01 02:13:24 +02:00
2020-10-17 07:08:21 +02:00
RS : : get_singleton ( ) - > instance_set_transform ( light_instance2 , Transform3D ( ) . looking_at ( Vector3 ( 0 , 1 , 0 ) , Vector3 ( 0 , 0 , 1 ) ) ) ;
2015-06-01 02:13:24 +02:00
2020-03-27 19:21:27 +01:00
//sphere = RS::get_singleton()->mesh_create();
mesh_instance = RS : : get_singleton ( ) - > instance_create ( ) ;
RS : : get_singleton ( ) - > instance_set_scenario ( mesh_instance , scenario ) ;
2015-06-01 02:13:24 +02:00
}
EditorMeshPreviewPlugin : : ~ EditorMeshPreviewPlugin ( ) {
2022-12-12 18:42:37 +01:00
ERR_FAIL_NULL ( RenderingServer : : get_singleton ( ) ) ;
2020-03-27 19:21:27 +01:00
//RS::get_singleton()->free(sphere);
RS : : get_singleton ( ) - > free ( mesh_instance ) ;
RS : : get_singleton ( ) - > free ( viewport ) ;
RS : : get_singleton ( ) - > free ( light ) ;
RS : : get_singleton ( ) - > free ( light_instance ) ;
RS : : get_singleton ( ) - > free ( light2 ) ;
RS : : get_singleton ( ) - > free ( light_instance2 ) ;
RS : : get_singleton ( ) - > free ( camera ) ;
2022-08-01 01:20:24 +02:00
RS : : get_singleton ( ) - > free ( camera_attributes ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > free ( scenario ) ;
2015-06-01 02:13:24 +02:00
}
2018-04-16 05:00:56 +02:00
///////////////////////////////////////////////////////////////////////////
2021-11-05 07:43:03 +01:00
void EditorFontPreviewPlugin : : _generate_frame_started ( ) {
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_ONCE ) ; //once used for capture
RS : : get_singleton ( ) - > request_frame_drawn_callback ( callable_mp ( const_cast < EditorFontPreviewPlugin * > ( this ) , & EditorFontPreviewPlugin : : _preview_done ) ) ;
}
2021-11-05 06:59:38 +01:00
void EditorFontPreviewPlugin : : _preview_done ( ) {
2021-11-05 07:43:03 +01:00
preview_done . post ( ) ;
2018-04-16 05:00:56 +02:00
}
2023-11-10 15:27:51 +01:00
void EditorFontPreviewPlugin : : abort ( ) {
preview_done . post ( ) ;
}
2018-04-16 05:00:56 +02:00
bool EditorFontPreviewPlugin : : handles ( const String & p_type ) const {
2022-05-09 11:47:10 +02:00
return ClassDB : : is_parent_class ( p_type , " Font " ) ;
2020-09-03 13:22:16 +02:00
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorFontPreviewPlugin : : generate_from_path ( const String & p_path , const Size2 & p_size , Dictionary & p_metadata ) const {
2022-05-09 11:47:10 +02:00
Ref < Font > sampled_font = ResourceLoader : : load ( p_path ) ;
ERR_FAIL_COND_V ( sampled_font . is_null ( ) , Ref < Texture2D > ( ) ) ;
2018-04-16 05:00:56 +02:00
2020-09-03 13:22:16 +02:00
String sample ;
2020-12-27 14:30:33 +01:00
static const String sample_base = U " 12漢字ԱբΑ α А б Α α אבا بܐܒހށआআਆઆଆஆఆಆആආกิກິༀကႠა한글ሀ ᎣᐁᚁᚠᜀᜠᝀᝠកᠠᤁᥐAb😀 " ;
for ( int i = 0 ; i < sample_base . length ( ) ; i + + ) {
if ( sampled_font - > has_char ( sample_base [ i ] ) ) {
sample + = sample_base [ i ] ;
2020-09-03 13:22:16 +02:00
}
}
2020-12-27 14:30:33 +01:00
if ( sample . is_empty ( ) ) {
sample = sampled_font - > get_supported_chars ( ) . substr ( 0 , 6 ) ;
}
2022-05-09 11:47:10 +02:00
Vector2 size = sampled_font - > get_string_size ( sample , HORIZONTAL_ALIGNMENT_LEFT , - 1 , 50 ) ;
2018-04-16 05:00:56 +02:00
Vector2 pos ;
pos . x = 64 - size . x / 2 ;
pos . y = 80 ;
2021-12-16 06:59:04 +01:00
const Color c = GLOBAL_GET ( " rendering/environment/defaults/default_clear_color " ) ;
const float fg = c . get_luminance ( ) < 0.5 ? 1.0 : 0.0 ;
2022-05-09 11:47:10 +02:00
sampled_font - > draw_string ( canvas_item , pos , sample , HORIZONTAL_ALIGNMENT_LEFT , - 1.f , 50 , Color ( fg , fg , fg ) ) ;
2018-04-16 05:00:56 +02:00
2022-09-01 15:44:42 +02:00
RS : : get_singleton ( ) - > connect ( SNAME ( " frame_pre_draw " ) , callable_mp ( const_cast < EditorFontPreviewPlugin * > ( this ) , & EditorFontPreviewPlugin : : _generate_frame_started ) , Object : : CONNECT_ONE_SHOT ) ;
2018-04-16 05:00:56 +02:00
2021-11-05 07:43:03 +01:00
preview_done . wait ( ) ;
2018-04-16 05:00:56 +02:00
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > canvas_item_clear ( canvas_item ) ;
2019-02-24 01:30:39 +01:00
2020-03-27 19:21:27 +01:00
Ref < Image > img = RS : : get_singleton ( ) - > texture_2d_get ( viewport_texture ) ;
2018-04-16 05:00:56 +02:00
ERR_FAIL_COND_V ( img . is_null ( ) , Ref < ImageTexture > ( ) ) ;
img - > convert ( Image : : FORMAT_RGBA8 ) ;
2018-09-12 13:10:49 +02:00
Vector2 new_size = img - > get_size ( ) ;
if ( new_size . x > p_size . x ) {
new_size = Vector2 ( p_size . x , new_size . y * p_size . x / new_size . x ) ;
}
if ( new_size . y > p_size . y ) {
new_size = Vector2 ( new_size . x * p_size . y / new_size . y , p_size . y ) ;
}
img - > resize ( new_size . x , new_size . y , Image : : INTERPOLATE_CUBIC ) ;
2018-04-16 05:00:56 +02:00
post_process_preview ( img ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( img ) ;
2018-04-16 05:00:56 +02:00
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorFontPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2019-02-24 01:30:39 +01:00
String path = p_from - > get_path ( ) ;
if ( ! FileAccess : : exists ( path ) ) {
2019-06-11 20:43:37 +02:00
return Ref < Texture2D > ( ) ;
2019-02-24 01:30:39 +01:00
}
2022-08-19 18:14:57 +02:00
return generate_from_path ( path , p_size , p_metadata ) ;
2018-04-16 05:00:56 +02:00
}
EditorFontPreviewPlugin : : EditorFontPreviewPlugin ( ) {
2020-03-27 19:21:27 +01:00
viewport = RS : : get_singleton ( ) - > viewport_create ( ) ;
RS : : get_singleton ( ) - > viewport_set_update_mode ( viewport , RS : : VIEWPORT_UPDATE_DISABLED ) ;
RS : : get_singleton ( ) - > viewport_set_size ( viewport , 128 , 128 ) ;
RS : : get_singleton ( ) - > viewport_set_active ( viewport , true ) ;
viewport_texture = RS : : get_singleton ( ) - > viewport_get_texture ( viewport ) ;
2018-07-29 21:45:23 +02:00
2020-03-27 19:21:27 +01:00
canvas = RS : : get_singleton ( ) - > canvas_create ( ) ;
canvas_item = RS : : get_singleton ( ) - > canvas_item_create ( ) ;
2018-07-29 21:45:23 +02:00
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > viewport_attach_canvas ( viewport , canvas ) ;
RS : : get_singleton ( ) - > canvas_item_set_parent ( canvas_item , canvas ) ;
2018-04-16 05:00:56 +02:00
}
EditorFontPreviewPlugin : : ~ EditorFontPreviewPlugin ( ) {
2022-12-12 18:42:37 +01:00
ERR_FAIL_NULL ( RenderingServer : : get_singleton ( ) ) ;
2020-03-27 19:21:27 +01:00
RS : : get_singleton ( ) - > free ( canvas_item ) ;
RS : : get_singleton ( ) - > free ( canvas ) ;
RS : : get_singleton ( ) - > free ( viewport ) ;
2018-04-16 05:00:56 +02:00
}
2022-04-21 00:08:35 +02:00
////////////////////////////////////////////////////////////////////////////
static const real_t GRADIENT_PREVIEW_TEXTURE_SCALE_FACTOR = 4.0 ;
bool EditorGradientPreviewPlugin : : handles ( const String & p_type ) const {
return ClassDB : : is_parent_class ( p_type , " Gradient " ) ;
}
bool EditorGradientPreviewPlugin : : generate_small_preview_automatically ( ) const {
return true ;
}
2022-08-19 18:14:57 +02:00
Ref < Texture2D > EditorGradientPreviewPlugin : : generate ( const Ref < Resource > & p_from , const Size2 & p_size , Dictionary & p_metadata ) const {
2022-04-21 00:08:35 +02:00
Ref < Gradient > gradient = p_from ;
if ( gradient . is_valid ( ) ) {
Ref < GradientTexture1D > ptex ;
ptex . instantiate ( ) ;
ptex - > set_width ( p_size . width * GRADIENT_PREVIEW_TEXTURE_SCALE_FACTOR * EDSCALE ) ;
ptex - > set_gradient ( gradient ) ;
2022-05-04 01:49:20 +02:00
return ImageTexture : : create_from_image ( ptex - > get_image ( ) ) ;
2022-04-21 00:08:35 +02:00
}
return Ref < Texture2D > ( ) ;
}
EditorGradientPreviewPlugin : : EditorGradientPreviewPlugin ( ) {
}