diff options
Diffstat (limited to 'scene')
72 files changed, 3153 insertions, 1663 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index eba638b0f5..6a3238b64e 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -32,6 +32,8 @@ #include "scene/scene_string_names.h" #include "scene/scene_string_names.h" +#define NORMAL_SUFFIX "_normal" + //////////////////////////// void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos) { @@ -82,6 +84,7 @@ void SpriteFrames::add_animation(const StringName &p_anim) { ERR_FAIL_COND(animations.has(p_anim)); animations[p_anim] = Anim(); + animations[p_anim].normal_name = String(p_anim) + NORMAL_SUFFIX; } bool SpriteFrames::has_animation(const StringName &p_anim) const { @@ -101,6 +104,7 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName & Anim anim = animations[p_prev]; animations.erase(p_prev); animations[p_next] = anim; + animations[p_next].normal_name = String(p_next) + NORMAL_SUFFIX; } Vector<String> SpriteFrames::_get_animation_list() const { @@ -374,6 +378,8 @@ void AnimatedSprite::_notification(int p_what) { return; } + Ref<Texture> normal = frames->get_normal_frame(animation, frame); + //print_line("DECIDED TO DRAW"); RID ci = get_canvas_item(); @@ -400,7 +406,7 @@ void AnimatedSprite::_notification(int p_what) { dst_rect.size.y = -dst_rect.size.y; //texture->draw_rect(ci,dst_rect,false,modulate); - texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size())); + texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal); //VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate); } break; diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 64794b0ca3..2274450647 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -47,6 +47,8 @@ class SpriteFrames : public Resource { loop = true; speed = 5; } + + StringName normal_name; }; Map<StringName, Anim> animations; @@ -89,6 +91,20 @@ public: return E->get().frames[p_idx]; } + _FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const { + + const Map<StringName, Anim>::Element *E = animations.find(p_anim); + ERR_FAIL_COND_V(!E, Ref<Texture>()); + ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>()); + + const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name); + + if (p_idx >= EN->get().frames.size()) + return Ref<Texture>(); + + return EN->get().frames[p_idx]; + } + void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture> &p_frame) { Map<StringName, Anim>::Element *E = animations.find(p_anim); ERR_FAIL_COND(!E); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 8bce489624..db22a38cec 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -29,7 +29,9 @@ /*************************************************************************/ #include "area_2d.h" #include "scene/scene_string_names.h" +#include "servers/audio_server.h" #include "servers/physics_2d_server.h" + void Area2D::set_space_override_mode(SpaceOverride p_mode) { space_override = p_mode; @@ -501,15 +503,15 @@ uint32_t Area2D::get_collision_mask() const { return collision_mask; } -void Area2D::set_layer_mask(uint32_t p_mask) { +void Area2D::set_collision_layer(uint32_t p_layer) { - layer_mask = p_mask; - Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask); + collision_layer = p_layer; + Physics2DServer::get_singleton()->area_set_collision_layer(get_rid(), p_layer); } -uint32_t Area2D::get_layer_mask() const { +uint32_t Area2D::get_collision_layer() const { - return layer_mask; + return collision_layer; } void Area2D::set_collision_mask_bit(int p_bit, bool p_value) { @@ -527,19 +529,60 @@ bool Area2D::get_collision_mask_bit(int p_bit) const { return get_collision_mask() & (1 << p_bit); } -void Area2D::set_layer_mask_bit(int p_bit, bool p_value) { +void Area2D::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t mask = get_layer_mask(); + uint32_t layer = get_collision_layer(); if (p_value) - mask |= 1 << p_bit; + layer |= 1 << p_bit; else - mask &= ~(1 << p_bit); - set_layer_mask(mask); + layer &= ~(1 << p_bit); + set_collision_layer(layer); +} + +bool Area2D::get_collision_layer_bit(int p_bit) const { + + return get_collision_layer() & (1 << p_bit); +} + +void Area2D::set_audio_bus_override(bool p_override) { + + audio_bus_override = p_override; } -bool Area2D::get_layer_mask_bit(int p_bit) const { +bool Area2D::is_overriding_audio_bus() const { - return get_layer_mask() & (1 << p_bit); + return audio_bus_override; +} + +void Area2D::set_audio_bus(const StringName &p_audio_bus) { + + audio_bus = p_audio_bus; +} + +StringName Area2D::get_audio_bus() const { + + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) { + return audio_bus; + } + } + return "Master"; +} + +void Area2D::_validate_property(PropertyInfo &property) const { + + if (property.name == "audio_bus_name") { + + String options; + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (i > 0) + options += ","; + String name = AudioServer::get_singleton()->get_bus_name(i); + options += name; + } + + property.hint_string = options; + } } void Area2D::_bind_methods() { @@ -577,14 +620,14 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &Area2D::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &Area2D::get_collision_mask); - ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Area2D::set_layer_mask); - ClassDB::bind_method(D_METHOD("get_layer_mask"), &Area2D::get_layer_mask); + ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Area2D::set_collision_layer); + ClassDB::bind_method(D_METHOD("get_collision_layer"), &Area2D::get_collision_layer); ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &Area2D::set_collision_mask_bit); ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &Area2D::get_collision_mask_bit); - ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "bit", "value"), &Area2D::set_layer_mask_bit); - ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "bit"), &Area2D::get_layer_mask_bit); + ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &Area2D::set_collision_layer_bit); + ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &Area2D::get_collision_layer_bit); ClassDB::bind_method(D_METHOD("set_monitoring", "enable"), &Area2D::set_monitoring); ClassDB::bind_method(D_METHOD("is_monitoring"), &Area2D::is_monitoring); @@ -598,6 +641,12 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area2D::overlaps_body); ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area2D::overlaps_area); + ClassDB::bind_method(D_METHOD("set_audio_bus", "name"), &Area2D::set_audio_bus); + ClassDB::bind_method(D_METHOD("get_audio_bus"), &Area2D::get_audio_bus); + + ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override); + ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus); + ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); @@ -622,8 +671,12 @@ void Area2D::_bind_methods() { ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); ADD_GROUP("Collision", "collision_"); - ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_layer_mask", "get_layer_mask"); + ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); + + ADD_GROUP("Audio Bus", "audio_bus_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus"); } Area2D::Area2D() @@ -641,7 +694,8 @@ Area2D::Area2D() monitoring = false; monitorable = false; collision_mask = 1; - layer_mask = 1; + collision_layer = 1; + audio_bus_override = false; set_monitoring(true); set_monitorable(true); } diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 3efc1abbd4..12d71f3911 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -55,7 +55,7 @@ private: real_t linear_damp; real_t angular_damp; uint32_t collision_mask; - uint32_t layer_mask; + uint32_t collision_layer; int priority; bool monitoring; bool monitorable; @@ -126,9 +126,13 @@ private: Map<ObjectID, AreaState> area_map; void _clear_monitoring(); + bool audio_bus_override; + StringName audio_bus; + protected: void _notification(int p_what); static void _bind_methods(); + void _validate_property(PropertyInfo &property) const; public: void set_space_override_mode(SpaceOverride p_mode); @@ -164,14 +168,14 @@ public: void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; - void set_layer_mask(uint32_t p_mask); - uint32_t get_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - void set_layer_mask_bit(int p_bit, bool p_value); - bool get_layer_mask_bit(int p_bit) const; + void set_collision_layer_bit(int p_bit, bool p_value); + bool get_collision_layer_bit(int p_bit) const; Array get_overlapping_bodies() const; //function for script Array get_overlapping_areas() const; //function for script @@ -179,6 +183,12 @@ public: bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; + void set_audio_bus_override(bool p_override); + bool is_overriding_audio_bus() const; + + void set_audio_bus(const StringName &p_audio_bus); + StringName get_audio_bus() const; + Area2D(); ~Area2D(); }; diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp new file mode 100644 index 0000000000..3d9e64ae79 --- /dev/null +++ b/scene/2d/audio_stream_player_2d.cpp @@ -0,0 +1,463 @@ + +#include "audio_stream_player_2d.h" +#include "scene/2d/area_2d.h" +#include "scene/main/viewport.h" +void AudioStreamPlayer2D::_mix_audio() { + + if (!stream_playback.is_valid()) { + return; + } + + if (!active) { + return; + } + + if (setseek >= 0.0) { + stream_playback->start(setseek); + setseek = -1.0; //reset seek + } + + //get data + AudioFrame *buffer = mix_buffer.ptr(); + int buffer_size = mix_buffer.size(); + + //mix + stream_playback->mix(buffer, 1.0, buffer_size); + + //write all outputs + for (int i = 0; i < output_count; i++) { + + Output current = outputs[i]; + + //see if current output exists, to keep volume ramp + bool found = false; + for (int j = i; j < prev_output_count; j++) { + if (prev_outputs[j].viewport == current.viewport) { + if (j != i) { + SWAP(prev_outputs[j], prev_outputs[i]); + } + found = true; + break; + } + } + + if (!found) { + //create new if was not used before + if (prev_output_count < MAX_OUTPUTS) { + prev_outputs[prev_output_count] = prev_outputs[i]; //may be owned by another viewport + prev_output_count++; + } + prev_outputs[i] = current; + } + + //mix! + AudioFrame vol_inc = (current.vol - prev_outputs[i].vol) / float(buffer_size); + AudioFrame vol = current.vol; + + switch (AudioServer::get_singleton()->get_speaker_mode()) { + + case AudioServer::SPEAKER_MODE_STEREO: { + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0); + + for (int j = 0; j < buffer_size; j++) { + + target[j] = buffer[j] * vol; + vol += vol_inc; + } + + } break; + case AudioServer::SPEAKER_SURROUND_51: { + + AudioFrame *targets[2] = { + AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1), + AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2), + }; + + for (int j = 0; j < buffer_size; j++) { + + AudioFrame frame = buffer[j] * vol; + targets[0][j] = frame; + targets[1][j] = frame; + vol += vol_inc; + } + + } break; + case AudioServer::SPEAKER_SURROUND_71: { + + AudioFrame *targets[3] = { + AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1), + AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2), + AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 3) + }; + + for (int j = 0; j < buffer_size; j++) { + + AudioFrame frame = buffer[j] * vol; + targets[0][j] = frame; + targets[1][j] = frame; + targets[2][j] = frame; + vol += vol_inc; + } + + } break; + } + + prev_outputs[i] = current; + } + + prev_output_count = output_count; + + //stream is no longer active, disable this. + if (!stream_playback->is_playing()) { + active = false; + } + + output_ready = false; +} + +void AudioStreamPlayer2D::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE) { + + AudioServer::get_singleton()->add_callback(_mix_audios, this); + if (autoplay && !get_tree()->is_editor_hint()) { + play(); + } + } + + if (p_what == NOTIFICATION_EXIT_TREE) { + + AudioServer::get_singleton()->remove_callback(_mix_audios, this); + } + + if (p_what == NOTIFICATION_INTERNAL_FIXED_PROCESS) { + + //update anything related to position first, if possible of course + + if (!output_ready) { + List<Viewport *> viewports; + Ref<World2D> world_2d = get_world_2d(); + ERR_FAIL_COND(world_2d.is_null()); + + int new_output_count = 0; + + Vector2 global_pos = get_global_position(); + + int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); + + //check if any area is diverting sound into a bus + + Physics2DDirectSpaceState *space_state = Physics2DServer::get_singleton()->space_get_direct_state(world_2d->get_space()); + + Physics2DDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS]; + + int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, Physics2DDirectSpaceState::TYPE_MASK_AREA); + + for (int i = 0; i < areas; i++) { + if (!sr[i].collider) + continue; + + Area2D *area2d = sr[i].collider->cast_to<Area2D>(); + if (!area2d) + continue; + + if (!area2d->is_overriding_audio_bus()) + continue; + + StringName bus_name = area2d->get_audio_bus(); + bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name); + break; + } + + world_2d->get_viewport_list(&viewports); + for (List<Viewport *>::Element *E = viewports.front(); E; E = E->next()) { + + Viewport *vp = E->get(); + if (vp->is_audio_listener_2d()) { + + //compute matrix to convert to screen + Transform2D to_screen = vp->get_global_canvas_transform() * vp->get_canvas_transform(); + Vector2 screen_size = vp->get_visible_rect().size; + + //screen in global is used for attenuation + Vector2 screen_in_global = to_screen.affine_inverse().xform(screen_size * 0.5); + + float dist = global_pos.distance_to(screen_in_global); //distance to screen center + + if (dist > max_distance) + continue; //cant hear this sound in this viewport + + float multiplier = Math::pow(1.0f - dist / max_distance, attenuation); + multiplier *= Math::db2linear(volume_db); //also apply player volume! + + //point in screen is used for panning + Vector2 point_in_screen = to_screen.xform(global_pos); + + float pan = CLAMP(point_in_screen.x / screen_size.width, 0.0, 1.0); + + float l = 1.0 - pan; + float r = pan; + + outputs[new_output_count].vol = AudioFrame(l, r) * multiplier; + outputs[new_output_count].bus_index = bus_index; + outputs[new_output_count].viewport = vp; //keep pointer only for reference + new_output_count++; + if (new_output_count == MAX_OUTPUTS) + break; + } + } + + output_count = new_output_count; + output_ready = true; + } + + //start playing if requested + if (setplay >= 0.0) { + setseek = setplay; + active = true; + setplay = -1; + _change_notify("playing"); //update property in editor + } + + //stop playing if no longer active + if (!active) { + set_fixed_process_internal(false); + _change_notify("playing"); //update property in editor + } + } +} + +void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { + + ERR_FAIL_COND(!p_stream.is_valid()); + AudioServer::get_singleton()->lock(); + + mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); + + if (stream_playback.is_valid()) { + stream_playback.unref(); + stream.unref(); + active = false; + setseek = -1; + } + + stream = p_stream; + stream_playback = p_stream->instance_playback(); + + if (stream_playback.is_null()) { + stream.unref(); + ERR_FAIL_COND(stream_playback.is_null()); + } + + AudioServer::get_singleton()->unlock(); +} + +Ref<AudioStream> AudioStreamPlayer2D::get_stream() const { + + return stream; +} + +void AudioStreamPlayer2D::set_volume_db(float p_volume) { + + volume_db = p_volume; +} +float AudioStreamPlayer2D::get_volume_db() const { + + return volume_db; +} + +void AudioStreamPlayer2D::play(float p_from_pos) { + + if (stream_playback.is_valid()) { + setplay = p_from_pos; + output_ready = false; + set_fixed_process_internal(true); + } +} + +void AudioStreamPlayer2D::seek(float p_seconds) { + + if (stream_playback.is_valid()) { + setseek = p_seconds; + } +} + +void AudioStreamPlayer2D::stop() { + + if (stream_playback.is_valid()) { + active = false; + set_fixed_process_internal(false); + setplay = -1; + } +} + +bool AudioStreamPlayer2D::is_playing() const { + + if (stream_playback.is_valid()) { + return active; // && stream_playback->is_playing(); + } + + return false; +} + +float AudioStreamPlayer2D::get_pos() { + + if (stream_playback.is_valid()) { + return stream_playback->get_pos(); + } + + return 0; +} + +void AudioStreamPlayer2D::set_bus(const StringName &p_bus) { + + //if audio is active, must lock this + AudioServer::get_singleton()->lock(); + bus = p_bus; + AudioServer::get_singleton()->unlock(); +} +StringName AudioStreamPlayer2D::get_bus() const { + + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (AudioServer::get_singleton()->get_bus_name(i) == bus) { + return bus; + } + } + return "Master"; +} + +void AudioStreamPlayer2D::set_autoplay(bool p_enable) { + + autoplay = p_enable; +} +bool AudioStreamPlayer2D::is_autoplay_enabled() { + + return autoplay; +} + +void AudioStreamPlayer2D::_set_playing(bool p_enable) { + + if (p_enable) + play(); + else + stop(); +} +bool AudioStreamPlayer2D::_is_active() const { + + return active; +} + +void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const { + + if (property.name == "bus") { + + String options; + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (i > 0) + options += ","; + String name = AudioServer::get_singleton()->get_bus_name(i); + options += name; + } + + property.hint_string = options; + } +} + +void AudioStreamPlayer2D::_bus_layout_changed() { + + _change_notify(); +} + +void AudioStreamPlayer2D::set_max_distance(float p_pixels) { + + ERR_FAIL_COND(p_pixels <= 0.0); + max_distance = p_pixels; +} + +float AudioStreamPlayer2D::get_max_distance() const { + + return max_distance; +} + +void AudioStreamPlayer2D::set_attenuation(float p_curve) { + + attenuation = p_curve; +} +float AudioStreamPlayer2D::get_attenuation() const { + + return attenuation; +} + +void AudioStreamPlayer2D::set_area_mask(uint32_t p_mask) { + + area_mask = p_mask; +} + +uint32_t AudioStreamPlayer2D::get_area_mask() const { + + return area_mask; +} + +void AudioStreamPlayer2D::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioStreamPlayer2D::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer2D::get_stream); + + ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer2D::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer2D::get_volume_db); + + ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioStreamPlayer2D::play, DEFVAL(0.0)); + ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioStreamPlayer2D::seek); + ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer2D::stop); + + ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer2D::is_playing); + ClassDB::bind_method(D_METHOD("get_pos"), &AudioStreamPlayer2D::get_pos); + + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer2D::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer2D::get_bus); + + ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer2D::set_autoplay); + ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer2D::is_autoplay_enabled); + + ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer2D::_set_playing); + ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer2D::_is_active); + + ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &AudioStreamPlayer2D::set_max_distance); + ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer2D::get_max_distance); + + ClassDB::bind_method(D_METHOD("set_attenuation", "curve"), &AudioStreamPlayer2D::set_attenuation); + ClassDB::bind_method(D_METHOD("get_attenuation"), &AudioStreamPlayer2D::get_attenuation); + + ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer2D::set_area_mask); + ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer2D::get_area_mask); + + ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer2D::_bus_layout_changed); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "1,65536,1"), "set_max_distance", "get_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING), "set_attenuation", "get_attenuation"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); +} + +AudioStreamPlayer2D::AudioStreamPlayer2D() { + + volume_db = 0; + autoplay = false; + setseek = -1; + active = false; + output_count = 0; + prev_output_count = 0; + max_distance = 2000; + attenuation = 1; + setplay = -1; + output_ready = false; + area_mask = 1; + AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); +} + +AudioStreamPlayer2D::~AudioStreamPlayer2D() { +} diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h new file mode 100644 index 0000000000..25eff61b76 --- /dev/null +++ b/scene/2d/audio_stream_player_2d.h @@ -0,0 +1,96 @@ +#ifndef AUDIO_STREAM_PLAYER_2D_H +#define AUDIO_STREAM_PLAYER_2D_H + +#include "scene/2d/node_2d.h" +#include "servers/audio/audio_stream.h" +#include "servers/audio_server.h" + +class AudioStreamPlayer2D : public Node2D { + + GDCLASS(AudioStreamPlayer2D, Node2D) + +private: + enum { + MAX_OUTPUTS = 8, + MAX_INTERSECT_AREAS = 32 + + }; + + struct Output { + + AudioFrame vol; + int bus_index; + Viewport *viewport; //pointer only used for reference to previous mix + }; + + Output outputs[MAX_OUTPUTS]; + volatile int output_count; + volatile bool output_ready; + + //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks) + Output prev_outputs[MAX_OUTPUTS]; + int prev_output_count; + + Ref<AudioStreamPlayback> stream_playback; + Ref<AudioStream> stream; + Vector<AudioFrame> mix_buffer; + + volatile float setseek; + volatile bool active; + volatile float setplay; + + float volume_db; + bool autoplay; + StringName bus; + + void _mix_audio(); + static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->_mix_audio(); } + + void _set_playing(bool p_enable); + bool _is_active() const; + + void _bus_layout_changed(); + + uint32_t area_mask; + + float max_distance; + float attenuation; + +protected: + void _validate_property(PropertyInfo &property) const; + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_stream(Ref<AudioStream> p_stream); + Ref<AudioStream> get_stream() const; + + void set_volume_db(float p_volume); + float get_volume_db() const; + + void play(float p_from_pos = 0.0); + void seek(float p_seconds); + void stop(); + bool is_playing() const; + float get_pos(); + + void set_bus(const StringName &p_bus); + StringName get_bus() const; + + void set_autoplay(bool p_enable); + bool is_autoplay_enabled(); + + void set_max_distance(float p_pixels); + float get_max_distance() const; + + void set_attenuation(float p_curve); + float get_attenuation() const; + + void set_area_mask(uint32_t p_mask); + uint32_t get_area_mask() const; + + AudioStreamPlayer2D(); + ~AudioStreamPlayer2D(); +}; + +#endif diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index b2258ec94b..471f529713 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "canvas_item.h" +#include "core/method_bind_ext.inc" #include "message_queue.h" #include "os/input.h" #include "scene/main/canvas_layer.h" @@ -436,7 +437,7 @@ void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color); } -void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate) { +void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -448,7 +449,7 @@ void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos p_texture->draw(canvas_item, p_pos, p_modulate); } -void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) { +void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -456,16 +457,16 @@ void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose); + p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map); } -void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) { +void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); ERR_FAIL(); } ERR_FAIL_COND(p_texture.is_null()); - p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose); + p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv); } void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) { @@ -478,7 +479,7 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p p_style_box->draw(canvas_item, p_rect); } -void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width) { +void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -486,8 +487,9 @@ void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Col } RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width); + VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal); } void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) { @@ -511,7 +513,7 @@ void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) { VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix); } -void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) { +void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -519,11 +521,12 @@ void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color } RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid); + VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal); } -void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) { +void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -533,8 +536,9 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo Vector<Color> colors; colors.push_back(p_color); RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid); + VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal); } void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) { @@ -752,13 +756,13 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color"), &CanvasItem::draw_rect); ClassDB::bind_method(D_METHOD("draw_circle", "pos", "radius", "color"), &CanvasItem::draw_circle); - ClassDB::bind_method(D_METHOD("draw_texture", "texture:Texture", "pos", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1))); - ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw_texture", "texture:Texture", "pos", "modulate", "normal_map:Texture"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); ClassDB::bind_method(D_METHOD("draw_style_box", "style_box:StyleBox", "rect"), &CanvasItem::draw_style_box); - ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0)); - ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture:Texture"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture:Texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width", "normal_map:Texture"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture:Texture", "normal_map:Texture"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture:Texture", "normal_map:Texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_string", "font:Font", "pos", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("draw_char", "font:Font", "pos", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1))); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index bea4301326..595dd03057 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -158,13 +158,13 @@ public: void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_rect(const Rect2 &p_rect, const Color &p_color); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); - void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1)); - void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false); - void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false); + void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>()); + void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()); + void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true); void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect); - void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1); - void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>()); - void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>()); + void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1, const Ref<Texture> &p_normal_map = Ref<Texture>()); + void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>()); + void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>()); void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1); float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1)); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 34413074c1..e8c2122bd1 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -336,6 +336,17 @@ String Light2D::get_configuration_warning() const { return String(); } +void Light2D::set_shadow_smooth(float p_amount) { + + shadow_smooth = p_amount; + VS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth); +} + +float Light2D::get_shadow_smooth() const { + + return shadow_smooth; +} + void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled); @@ -389,6 +400,9 @@ void Light2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_buffer_size", "size"), &Light2D::set_shadow_buffer_size); ClassDB::bind_method(D_METHOD("get_shadow_buffer_size"), &Light2D::get_shadow_buffer_size); + ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth); + ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth); + ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length); ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length); @@ -420,6 +434,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "1,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); BIND_CONSTANT(MODE_ADD); @@ -449,6 +464,7 @@ Light2D::Light2D() { energy = 1.0; shadow_color = Color(0, 0, 0, 0); shadow_filter = SHADOW_FILTER_NONE; + shadow_smooth = 0; set_notify_transform(true); } diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 9b09d54dd8..90e55aeda4 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -69,6 +69,7 @@ private: int item_mask; int item_shadow_mask; int shadow_buffer_size; + float shadow_smooth; float shadow_gradient_length; Mode mode; Ref<Texture> texture; @@ -146,6 +147,9 @@ public: void set_shadow_color(const Color &p_shadow_color); Color get_shadow_color() const; + void set_shadow_smooth(float p_amount); + float get_shadow_smooth() const; + virtual Rect2 get_item_rect() const; String get_configuration_warning() const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 80969d11b3..1a57d24342 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -310,7 +310,7 @@ void Line2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "ColorRamp"), "set_gradient", "get_gradient"); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile"), "set_texture_mode", "get_texture_mode"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode"); diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index ea059d133d..3c1410edbb 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -337,7 +337,7 @@ void LineBuilder::build() { } else if (current_joint_mode == LINE_JOINT_ROUND) { Vector2 vbegin = cbegin - pos1; Vector2 vend = cend - pos1; - strip_add_arc(pos1, vend.angle_to(vbegin), orientation); + strip_add_arc(pos1, vbegin.angle_to(vend), orientation); } if (intersection_result != SEGMENT_INTERSECT) @@ -498,7 +498,7 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o if (angle_delta < 0.f) angle_step = -angle_step; - float t = vbegin.angle_to(Vector2(1, 0)); + float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; Vector2 rpos(0, 0); @@ -525,7 +525,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col if (angle_delta < 0.f) angle_step = -angle_step; - float t = vbegin.angle_to(Vector2(1, 0)); + float t = Vector2(1, 0).angle_to(vbegin); float end_angle = t + angle_delta; Vector2 rpos(0, 0); float tt_begin = -Math_PI / 2.f; diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 27d0d07c0f..21d64c5d64 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -505,8 +505,8 @@ void Particles2D::_notification(int p_what) { Color color; - if (color_ramp.is_valid()) { - color = color_ramp->get_color_at_offset(ptime); + if (gradient.is_valid()) { + color = gradient->get_color_at_offset(ptime); } else { color = default_color; } @@ -774,14 +774,14 @@ Color Particles2D::get_color() const { return default_color; } -void Particles2D::set_color_ramp(const Ref<Gradient> &p_color_ramp) { +void Particles2D::set_gradient(const Ref<Gradient> &p_gradient) { - color_ramp = p_color_ramp; + gradient = p_gradient; } -Ref<Gradient> Particles2D::get_color_ramp() const { +Ref<Gradient> Particles2D::get_gradient() const { - return color_ramp; + return gradient; } void Particles2D::set_emissor_offset(const Point2 &p_offset) { @@ -809,19 +809,19 @@ void Particles2D::set_color_phases(int p_phases) { //Create color ramp if we have 2 or more phases. //Otherwise first phase phase will be assigned to default color. - if (p_phases > 1 && color_ramp.is_null()) { - color_ramp = Ref<Gradient>(memnew(Gradient())); + if (p_phases > 1 && gradient.is_null()) { + gradient = Ref<Gradient>(memnew(Gradient())); } - if (color_ramp.is_valid()) { - color_ramp->get_points().resize(p_phases); + if (gradient.is_valid()) { + gradient->get_points().resize(p_phases); } } //Deprecated. int Particles2D::get_color_phases() const { - if (color_ramp.is_valid()) { - return color_ramp->get_points_count(); + if (gradient.is_valid()) { + return gradient->get_points_count(); } return 0; } @@ -830,9 +830,9 @@ int Particles2D::get_color_phases() const { void Particles2D::set_color_phase_color(int p_phase, const Color &p_color) { ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES); - if (color_ramp.is_valid()) { - if (color_ramp->get_points_count() > p_phase) - color_ramp->set_color(p_phase, p_color); + if (gradient.is_valid()) { + if (gradient->get_points_count() > p_phase) + gradient->set_color(p_phase, p_color); } else { if (p_phase == 0) default_color = p_color; @@ -843,8 +843,8 @@ void Particles2D::set_color_phase_color(int p_phase, const Color &p_color) { Color Particles2D::get_color_phase_color(int p_phase) const { ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, Color()); - if (color_ramp.is_valid()) { - return color_ramp->get_color(p_phase); + if (gradient.is_valid()) { + return gradient->get_color(p_phase); } return Color(0, 0, 0, 1); } @@ -853,8 +853,8 @@ Color Particles2D::get_color_phase_color(int p_phase) const { void Particles2D::set_color_phase_pos(int p_phase, float p_pos) { ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES); ERR_FAIL_COND(p_pos < 0.0 || p_pos > 1.0); - if (color_ramp.is_valid() && color_ramp->get_points_count() > p_phase) { - return color_ramp->set_offset(p_phase, p_pos); + if (gradient.is_valid() && gradient->get_points_count() > p_phase) { + return gradient->set_offset(p_phase, p_pos); } } @@ -862,8 +862,8 @@ void Particles2D::set_color_phase_pos(int p_phase, float p_pos) { float Particles2D::get_color_phase_pos(int p_phase) const { ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, 0); - if (color_ramp.is_valid()) { - return color_ramp->get_offset(p_phase); + if (gradient.is_valid()) { + return gradient->get_offset(p_phase); } return 0; } @@ -996,8 +996,8 @@ void Particles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color", "color"), &Particles2D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Particles2D::get_color); - ClassDB::bind_method(D_METHOD("set_color_ramp:ColorRamp", "color_ramp"), &Particles2D::set_color_ramp); - ClassDB::bind_method(D_METHOD("get_color_ramp:ColorRamp"), &Particles2D::get_color_ramp); + ClassDB::bind_method(D_METHOD("set_gradient:Gradient", "gradient"), &Particles2D::set_gradient); + ClassDB::bind_method(D_METHOD("get_gradient:Gradient"), &Particles2D::get_gradient); ClassDB::bind_method(D_METHOD("set_emissor_offset", "offset"), &Particles2D::set_emissor_offset); ClassDB::bind_method(D_METHOD("get_emissor_offset"), &Particles2D::get_emissor_offset); @@ -1078,7 +1078,7 @@ void Particles2D::_bind_methods() { } ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "color/color"), "set_color", "get_color"); - ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "color/color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "ColorRamp"), "set_color_ramp", "get_color_ramp"); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "color/color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); ADD_PROPERTYNZ(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_points", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_emission_points", "get_emission_points"); diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h index 5769fdd251..856beaa836 100644 --- a/scene/2d/particles_2d.h +++ b/scene/2d/particles_2d.h @@ -169,7 +169,7 @@ private: //If no color ramp is set then default color is used. Created as simple alternative to color_ramp. Color default_color; - Ref<Gradient> color_ramp; + Ref<Gradient> gradient; void _process_particles(float p_delta); friend class ParticleAttractor2D; @@ -241,8 +241,8 @@ public: void set_color(const Color &p_color); Color get_color() const; - void set_color_ramp(const Ref<Gradient> &p_texture); - Ref<Gradient> get_color_ramp() const; + void set_gradient(const Ref<Gradient> &p_texture); + Ref<Gradient> get_gradient() const; void set_emissor_offset(const Point2 &p_offset); Point2 get_emissor_offset() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 626ea10515..68270ed771 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -79,7 +79,7 @@ uint32_t PhysicsBody2D::_get_layers() const { void PhysicsBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_collision_layer", "mask"), &PhysicsBody2D::set_collision_layer); + ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody2D::set_collision_layer); ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody2D::get_collision_layer); ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &PhysicsBody2D::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsBody2D::get_collision_mask); @@ -108,15 +108,15 @@ void PhysicsBody2D::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "one_way_collision/max_depth"), "set_one_way_collision_max_depth", "get_one_way_collision_max_depth"); } -void PhysicsBody2D::set_collision_layer(uint32_t p_mask) { +void PhysicsBody2D::set_collision_layer(uint32_t p_layer) { - mask = p_mask; - Physics2DServer::get_singleton()->body_set_layer_mask(get_rid(), p_mask); + collision_layer = p_layer; + Physics2DServer::get_singleton()->body_set_collision_layer(get_rid(), p_layer); } uint32_t PhysicsBody2D::get_collision_layer() const { - return mask; + return collision_layer; } void PhysicsBody2D::set_collision_mask(uint32_t p_mask) { @@ -146,12 +146,12 @@ bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const { void PhysicsBody2D::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t mask = get_collision_layer(); + uint32_t collision_layer = get_collision_layer(); if (p_value) - mask |= 1 << p_bit; + collision_layer |= 1 << p_bit; else - mask &= ~(1 << p_bit); - set_collision_layer(mask); + collision_layer &= ~(1 << p_bit); + set_collision_layer(collision_layer); } bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const { @@ -162,7 +162,7 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const { PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D(Physics2DServer::get_singleton()->body_create(p_mode), false) { - mask = 1; + collision_layer = 1; collision_mask = 1; set_one_way_collision_max_depth(0); set_pickable(false); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index f706111e7e..50c9865f18 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -38,7 +38,7 @@ class PhysicsBody2D : public CollisionObject2D { GDCLASS(PhysicsBody2D, CollisionObject2D); - uint32_t mask; + uint32_t collision_layer; uint32_t collision_mask; Vector2 one_way_collision_direction; float one_way_collision_max_depth; @@ -53,7 +53,7 @@ protected: static void _bind_methods(); public: - void set_collision_layer(uint32_t p_mask); + void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; void set_collision_mask(uint32_t p_mask); diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 0a1a8b56ff..cfb4059714 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -44,14 +44,14 @@ Vector2 RayCast2D::get_cast_to() const { return cast_to; } -void RayCast2D::set_layer_mask(uint32_t p_mask) { +void RayCast2D::set_collision_layer(uint32_t p_layer) { - layer_mask = p_mask; + collision_layer = p_layer; } -uint32_t RayCast2D::get_layer_mask() const { +uint32_t RayCast2D::get_collision_layer() const { - return layer_mask; + return collision_layer; } void RayCast2D::set_type_mask(uint32_t p_mask) { @@ -201,7 +201,7 @@ void RayCast2D::_update_raycast_state() { Physics2DDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) { + if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_layer, type_mask)) { collided = true; against = rr.collider_id; @@ -274,8 +274,8 @@ void RayCast2D::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast2D::clear_exceptions); - ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast2D::set_layer_mask); - ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast2D::get_layer_mask); + ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &RayCast2D::set_collision_layer); + ClassDB::bind_method(D_METHOD("get_collision_layer"), &RayCast2D::get_collision_layer); ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast2D::set_type_mask); ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast2D::get_type_mask); @@ -286,7 +286,7 @@ void RayCast2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_layer_mask", "get_layer_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask"); } @@ -296,7 +296,7 @@ RayCast2D::RayCast2D() { against = 0; collided = false; against_shape = 0; - layer_mask = 1; + collision_layer = 1; type_mask = Physics2DDirectSpaceState::TYPE_MASK_COLLISION; cast_to = Vector2(0, 50); exclude_parent_body = true; diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index cfecfa2585..244f4302ad 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -43,7 +43,7 @@ class RayCast2D : public Node2D { Vector2 collision_point; Vector2 collision_normal; Set<RID> exclude; - uint32_t layer_mask; + uint32_t collision_layer; uint32_t type_mask; bool exclude_parent_body; @@ -61,8 +61,8 @@ public: void set_cast_to(const Vector2 &p_point); Vector2 get_cast_to() const; - void set_layer_mask(uint32_t p_mask); - uint32_t get_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; void set_type_mask(uint32_t p_mask); uint32_t get_type_mask() const; diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index ea68a111af..37139b2b93 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -194,40 +194,27 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { if (p_event->get_device() != 0) return; + ERR_FAIL_COND(!is_visible_in_tree()); + + const InputEventScreenTouch *st = p_event->cast_to<InputEventScreenTouch>(); + if (passby_press) { - Ref<InputEventScreenTouch> st = p_event; - Ref<InputEventScreenTouch> sd = p_event; + const InputEventScreenDrag *sd = p_event->cast_to<InputEventScreenDrag>(); - if (st.is_valid() && !st->is_pressed() && finger_pressed == st->get_index()) { + if (st && !st->is_pressed() && finger_pressed == st->get_index()) { _release(); } - if ((st.is_valid() && st->is_pressed()) || sd.is_valid()) { + if ((st && st->is_pressed()) || sd) { - int index = st.is_valid() ? st->get_index() : sd->get_index(); - Vector2 coord = st.is_valid() ? st->get_position() : sd->get_position(); + int index = st ? st->get_index() : sd->get_index(); + Point2 coord = st ? st->get_position() : sd->get_position(); if (finger_pressed == -1 || index == finger_pressed) { - coord = (get_global_transform_with_canvas()).affine_inverse().xform(coord); - - bool touched = false; - if (bitmask.is_valid()) { - - if (Rect2(Point2(), bitmask->get_size()).has_point(coord)) { - - if (bitmask->get_bit(coord)) - touched = true; - } - } else { - - if (texture.is_valid()) - touched = Rect2(Point2(), texture->get_size()).has_point(coord); - } - - if (touched) { + if (_is_point_inside(coord)) { if (finger_pressed == -1) { _press(index); } @@ -241,47 +228,15 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { } else { - Ref<InputEventScreenTouch> st = p_event; - - if (st.is_valid()) { + if (st) { if (st->is_pressed()) { - if (!is_visible_in_tree()) - return; - const bool can_press = finger_pressed == -1; if (!can_press) return; //already fingering - Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(st->get_position()); - Rect2 item_rect = get_item_rect(); - - bool touched = false; - bool check_rect = true; - if (shape.is_valid()) { - - check_rect = false; - Transform2D xform = shape_centered ? Transform2D().translated(get_item_rect().size * 0.5f) : Transform2D(); - touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); - } - - if (bitmask.is_valid()) { - - check_rect = false; - if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) { - - if (bitmask->get_bit(coord)) - touched = true; - } - } - - if (!touched && check_rect) { - if (!texture.is_null()) - touched = item_rect.has_point(coord); - } - - if (touched) { + if (_is_point_inside(st->get_position())) { _press(st->get_index()); } } else { @@ -293,6 +248,39 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { } } +bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { + + Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point); + Rect2 item_rect = get_item_rect(); + + bool touched = false; + bool check_rect = true; + + if (shape.is_valid()) { + + check_rect = false; + Transform2D xform = shape_centered ? Transform2D().translated(item_rect.size * 0.5f) : Transform2D(); + touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5))); + } + + if (bitmask.is_valid()) { + + check_rect = false; + if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) { + + if (bitmask->get_bit(coord)) + touched = true; + } + } + + if (!touched && check_rect) { + if (texture.is_valid()) + touched = item_rect.has_point(coord); + } + + return touched; +} + void TouchScreenButton::_press(int p_finger_pressed) { finger_pressed = p_finger_pressed; diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h index e44f556c31..8923da2ae4 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/screen_button.h @@ -63,6 +63,8 @@ private: void _input(const Ref<InputEvent> &p_Event); + bool _is_point_inside(const Point2 &p_point); + void _press(int p_finger_pressed); void _release(bool p_exiting_tree = false); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index c1eb90e52a..ff574a6bd6 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -65,11 +65,13 @@ void Sprite::_notification(int p_what) { Size2 s; Rect2 src_rect; + bool filter_clip = false; if (region) { s = region_rect.size; src_rect = region_rect; + filter_clip = region_filter_clip; } else { s = Size2(texture->get_size()); s = s / Size2(hframes, vframes); @@ -93,7 +95,7 @@ void Sprite::_notification(int p_what) { if (vflip) dst_rect.size.y = -dst_rect.size.y; - texture->draw_rect_region(ci, dst_rect, src_rect); + texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip); } break; } @@ -109,17 +111,30 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { } #endif texture = p_texture; + /* this should no longer be needed in 3.0 #ifdef DEBUG_ENABLED if (texture.is_valid()) { texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites texture->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->update); } #endif +*/ update(); emit_signal("texture_changed"); item_rect_changed(); } +void Sprite::set_normal_map(const Ref<Texture> &p_texture) { + + normal_map = p_texture; + update(); +} + +Ref<Texture> Sprite::get_normal_map() const { + + return normal_map; +} + Ref<Texture> Sprite::get_texture() const { return texture; @@ -201,6 +216,15 @@ Rect2 Sprite::get_region_rect() const { return region_rect; } +void Sprite::set_region_filter_clip(bool p_enable) { + region_filter_clip = p_enable; + update(); +} + +bool Sprite::is_region_filter_clip_enabled() const { + return region_filter_clip; +} + void Sprite::set_frame(int p_frame) { ERR_FAIL_INDEX(p_frame, vframes * hframes); @@ -289,6 +313,9 @@ void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &Sprite::set_texture); ClassDB::bind_method(D_METHOD("get_texture:Texture"), &Sprite::get_texture); + ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map:Texture"), &Sprite::set_normal_map); + ClassDB::bind_method(D_METHOD("get_normal_map:Texture"), &Sprite::get_normal_map); + ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite::set_centered); ClassDB::bind_method(D_METHOD("is_centered"), &Sprite::is_centered); @@ -307,6 +334,9 @@ void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite::set_region_rect); ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite::get_region_rect); + ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite::set_region_filter_clip); + ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite::is_region_filter_clip_enabled); + ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame); ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame); @@ -320,6 +350,7 @@ void Sprite::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h"); @@ -327,8 +358,11 @@ void Sprite::_bind_methods() { ADD_PROPERTYNO(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); ADD_PROPERTYNO(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame"); - ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region"), "set_region", "is_region"); + + ADD_GROUP("Region", "region_"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled"); } Sprite::Sprite() { @@ -337,6 +371,7 @@ Sprite::Sprite() { hflip = false; vflip = false; region = false; + region_filter_clip = false; frame = 0; diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 86ef335d42..d3f9a5f032 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -38,6 +38,7 @@ class Sprite : public Node2D { GDCLASS(Sprite, Node2D); Ref<Texture> texture; + Ref<Texture> normal_map; bool centered; Point2 offset; @@ -46,6 +47,7 @@ class Sprite : public Node2D { bool vflip; bool region; Rect2 region_rect; + bool region_filter_clip; int frame; @@ -67,6 +69,9 @@ public: void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; + void set_normal_map(const Ref<Texture> &p_texture); + Ref<Texture> get_normal_map() const; + void set_centered(bool p_center); bool is_centered() const; @@ -82,6 +87,9 @@ public: void set_region(bool p_region); bool is_region() const; + void set_region_filter_clip(bool p_enable); + bool is_region_filter_clip_enabled() const; + void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index eebf0efd1e..4f892a31fc 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -587,7 +587,7 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons //q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); q.body = Physics2DServer::get_singleton()->body_create(use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body, get_instance_ID()); - Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer); + Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask); Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction); Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce); @@ -863,7 +863,7 @@ void TileMap::set_collision_layer(uint32_t p_layer) { for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) { Quadrant &q = E->get(); - Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer); + Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer); } } @@ -1286,7 +1286,7 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask"); ADD_GROUP("Occluder", "occluder_"); diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 8dae078e5b..39a4e926b2 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -489,15 +489,15 @@ uint32_t Area::get_collision_mask() const { return collision_mask; } -void Area::set_layer_mask(uint32_t p_mask) { +void Area::set_collision_layer(uint32_t p_layer) { - layer_mask = p_mask; - PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask); + collision_layer = p_layer; + PhysicsServer::get_singleton()->area_set_collision_layer(get_rid(), p_layer); } -uint32_t Area::get_layer_mask() const { +uint32_t Area::get_collision_layer() const { - return layer_mask; + return collision_layer; } void Area::set_collision_mask_bit(int p_bit, bool p_value) { @@ -515,19 +515,19 @@ bool Area::get_collision_mask_bit(int p_bit) const { return get_collision_mask() & (1 << p_bit); } -void Area::set_layer_mask_bit(int p_bit, bool p_value) { +void Area::set_collision_layer_bit(int p_bit, bool p_value) { - uint32_t mask = get_layer_mask(); + uint32_t layer = get_collision_layer(); if (p_value) - mask |= 1 << p_bit; + layer |= 1 << p_bit; else - mask &= ~(1 << p_bit); - set_layer_mask(mask); + layer &= ~(1 << p_bit); + set_collision_layer(layer); } -bool Area::get_layer_mask_bit(int p_bit) const { +bool Area::get_collision_layer_bit(int p_bit) const { - return get_layer_mask() & (1 << p_bit); + return get_collision_layer() & (1 << p_bit); } void Area::_bind_methods() { @@ -565,14 +565,14 @@ void Area::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &Area::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &Area::get_collision_mask); - ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Area::set_layer_mask); - ClassDB::bind_method(D_METHOD("get_layer_mask"), &Area::get_layer_mask); + ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Area::set_collision_layer); + ClassDB::bind_method(D_METHOD("get_collision_layer"), &Area::get_collision_layer); ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &Area::set_collision_mask_bit); ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &Area::get_collision_mask_bit); - ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "bit", "value"), &Area::set_layer_mask_bit); - ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "bit"), &Area::get_layer_mask_bit); + ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &Area::set_collision_layer_bit); + ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &Area::get_collision_layer_bit); ClassDB::bind_method(D_METHOD("set_monitorable", "enable"), &Area::set_monitorable); ClassDB::bind_method(D_METHOD("is_monitorable"), &Area::is_monitorable); @@ -610,7 +610,7 @@ void Area::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable"); ADD_GROUP("Collision", "collision_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask"); } @@ -628,7 +628,7 @@ Area::Area() priority = 0; monitoring = false; collision_mask = 1; - layer_mask = 1; + collision_layer = 1; set_ray_pickable(false); set_monitoring(true); set_monitorable(true); diff --git a/scene/3d/area.h b/scene/3d/area.h index 64bbae9236..279a52ee69 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -55,7 +55,7 @@ private: real_t angular_damp; real_t linear_damp; uint32_t collision_mask; - uint32_t layer_mask; + uint32_t collision_layer; int priority; bool monitoring; bool monitorable; @@ -164,14 +164,14 @@ public: void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; - void set_layer_mask(uint32_t p_mask); - uint32_t get_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; void set_collision_mask_bit(int p_bit, bool p_value); bool get_collision_mask_bit(int p_bit) const; - void set_layer_mask_bit(int p_bit, bool p_value); - bool get_layer_mask_bit(int p_bit) const; + void set_collision_layer_bit(int p_bit, bool p_value); + bool get_collision_layer_bit(int p_bit) const; Array get_overlapping_bodies() const; Array get_overlapping_areas() const; //function for script diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index d648ff078c..0f4378acdd 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -626,7 +626,7 @@ Camera::Camera() { current = false; force_change = false; mode = PROJECTION_PERSPECTIVE; - set_perspective(60.0, 0.1, 100.0); + set_perspective(65.0, 0.1, 100.0); keep_aspect = KEEP_HEIGHT; layers = 0xfffff; v_offset = 0; diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 6ab65d3994..9c87acec6e 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -234,7 +234,7 @@ void Light::_bind_methods() { BIND_CONSTANT(PARAM_SHADOW_SPLIT_3_OFFSET); BIND_CONSTANT(PARAM_SHADOW_NORMAL_BIAS); BIND_CONSTANT(PARAM_SHADOW_BIAS); - BIND_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE); + BIND_CONSTANT(PARAM_MAX); } @@ -261,9 +261,8 @@ Light::Light(VisualServer::LightType p_type) { set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1); set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2); set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5); - set_param(PARAM_SHADOW_NORMAL_BIAS, 0.1); - set_param(PARAM_SHADOW_BIAS, 0.1); - set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.1); + set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0); + set_param(PARAM_SHADOW_BIAS, 0.15); } Light::Light() { @@ -318,7 +317,6 @@ void DirectionalLight::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); BIND_CONSTANT(SHADOW_ORTHOGONAL); BIND_CONSTANT(SHADOW_PARALLEL_2_SPLITS); @@ -328,7 +326,11 @@ void DirectionalLight::_bind_methods() { DirectionalLight::DirectionalLight() : Light(VisualServer::LIGHT_DIRECTIONAL) { + set_param(PARAM_SHADOW_NORMAL_BIAS, 0.2); + set_param(PARAM_SHADOW_BIAS, 1.0); + set_param(PARAM_SHADOW_MAX_DISTANCE, 200); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); + blend_splits = false; } @@ -371,7 +373,7 @@ void OmniLight::_bind_methods() { OmniLight::OmniLight() : Light(VisualServer::LIGHT_OMNI) { - set_shadow_mode(SHADOW_DUAL_PARABOLOID); + set_shadow_mode(SHADOW_CUBE); set_shadow_detail(SHADOW_DETAIL_HORIZONTAL); } diff --git a/scene/3d/light.h b/scene/3d/light.h index c02f9d12d3..22ff5c0763 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -60,7 +60,6 @@ public: PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET, PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS, PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS, - PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE, PARAM_MAX = VS::LIGHT_PARAM_MAX }; diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 98babedf0d..3a55a2bc32 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -59,15 +59,15 @@ float PhysicsBody::get_inverse_mass() const { return 0; } -void PhysicsBody::set_collision_layer(uint32_t p_mask) { +void PhysicsBody::set_collision_layer(uint32_t p_layer) { - layer_mask = p_mask; - PhysicsServer::get_singleton()->body_set_layer_mask(get_rid(), p_mask); + collision_layer = p_layer; + PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), p_layer); } uint32_t PhysicsBody::get_collision_layer() const { - return layer_mask; + return collision_layer; } void PhysicsBody::set_collision_mask(uint32_t p_mask) { @@ -167,7 +167,7 @@ void PhysicsBody::_bind_methods() { PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) : CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) { - layer_mask = 1; + collision_layer = 1; collision_mask = 1; } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index d13f84dc15..db4147f8f6 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -38,7 +38,7 @@ class PhysicsBody : public CollisionObject { GDCLASS(PhysicsBody, CollisionObject); - uint32_t layer_mask; + uint32_t collision_layer; uint32_t collision_mask; void _set_layers(uint32_t p_mask); @@ -54,7 +54,7 @@ public: virtual Vector3 get_angular_velocity() const; virtual float get_inverse_mass() const; - void set_collision_layer(uint32_t p_mask); + void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; void set_collision_mask(uint32_t p_mask); diff --git a/scene/3d/quad.cpp b/scene/3d/quad.cpp deleted file mode 100644 index c3d83ad50d..0000000000 --- a/scene/3d/quad.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************/ -/* quad.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#include "quad.h" -#include "servers/visual_server.h" - -void Quad::_update() { - - if (!is_inside_tree()) - return; - - Vector3 normal; - normal[axis] = 1.0; - - const int axis_order_1[3] = { 1, 2, 0 }; - const int axis_order_2[3] = { 2, 0, 1 }; - const int a1 = axis_order_1[axis]; - const int a2 = axis_order_2[axis]; - - PoolVector<Vector3> points; - points.resize(4); - PoolVector<Vector3>::Write pointsw = points.write(); - - Vector2 s2 = size * 0.5; - Vector2 o = offset; - if (!centered) - o += s2; - - pointsw[0][a1] = -s2.x + offset.x; - pointsw[0][a2] = s2.y + offset.y; - - pointsw[1][a1] = s2.x + offset.x; - pointsw[1][a2] = s2.y + offset.y; - - pointsw[2][a1] = s2.x + offset.x; - pointsw[2][a2] = -s2.y + offset.y; - - pointsw[3][a1] = -s2.x + offset.x; - pointsw[3][a2] = -s2.y + offset.y; - - aabb = Rect3(pointsw[0], Vector3()); - for (int i = 1; i < 4; i++) - aabb.expand_to(pointsw[i]); - - pointsw = PoolVector<Vector3>::Write(); - - PoolVector<Vector3> normals; - normals.resize(4); - PoolVector<Vector3>::Write normalsw = normals.write(); - - for (int i = 0; i < 4; i++) - normalsw[i] = normal; - - normalsw = PoolVector<Vector3>::Write(); - - PoolVector<Vector2> uvs; - uvs.resize(4); - PoolVector<Vector2>::Write uvsw = uvs.write(); - - uvsw[0] = Vector2(0, 0); - uvsw[1] = Vector2(1, 0); - uvsw[2] = Vector2(1, 1); - uvsw[3] = Vector2(0, 1); - - uvsw = PoolVector<Vector2>::Write(); - - PoolVector<int> indices; - indices.resize(6); - - PoolVector<int>::Write indicesw = indices.write(); - indicesw[0] = 0; - indicesw[1] = 1; - indicesw[2] = 2; - indicesw[3] = 2; - indicesw[4] = 3; - indicesw[5] = 0; - - indicesw = PoolVector<int>::Write(); - - Array arr; - arr.resize(VS::ARRAY_MAX); - arr[VS::ARRAY_VERTEX] = points; - arr[VS::ARRAY_NORMAL] = normals; - arr[VS::ARRAY_TEX_UV] = uvs; - arr[VS::ARRAY_INDEX] = indices; - - if (configured) { - VS::get_singleton()->mesh_remove_surface(mesh, 0); - } else { - configured = true; - } - VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr); - - pending_update = false; -} - -void Quad::set_axis(Vector3::Axis p_axis) { - - axis = p_axis; - _update(); -} - -Vector3::Axis Quad::get_axis() const { - - return axis; -} - -void Quad::set_size(const Vector2 &p_size) { - - size = p_size; - _update(); -} -Vector2 Quad::get_size() const { - - return size; -} - -void Quad::set_offset(const Vector2 &p_offset) { - - offset = p_offset; - _update(); -} -Vector2 Quad::get_offset() const { - - return offset; -} - -void Quad::set_centered(bool p_enabled) { - - centered = p_enabled; - _update(); -} -bool Quad::is_centered() const { - - return centered; -} - -void Quad::_notification(int p_what) { - - switch (p_what) { - - case NOTIFICATION_ENTER_TREE: { - - if (pending_update) - _update(); - - } break; - case NOTIFICATION_EXIT_TREE: { - - pending_update = true; - - } break; - } -} - -PoolVector<Face3> Quad::get_faces(uint32_t p_usage_flags) const { - - return PoolVector<Face3>(); -} - -Rect3 Quad::get_aabb() const { - - return aabb; -} - -void Quad::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_axis", "axis"), &Quad::set_axis); - ClassDB::bind_method(D_METHOD("get_axis"), &Quad::get_axis); - - ClassDB::bind_method(D_METHOD("set_size", "size"), &Quad::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &Quad::get_size); - - ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Quad::set_centered); - ClassDB::bind_method(D_METHOD("is_centered"), &Quad::is_centered); - - ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Quad::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"), &Quad::get_offset); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X,Y,Z"), "set_axis", "get_axis"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered"); -} - -Quad::Quad() { - - pending_update = true; - centered = true; - //offset=0; - size = Vector2(1, 1); - axis = Vector3::AXIS_Z; - mesh = VisualServer::get_singleton()->mesh_create(); - set_base(mesh); - configured = false; -} - -Quad::~Quad() { - VisualServer::get_singleton()->free(mesh); -} diff --git a/scene/3d/quad.h b/scene/3d/quad.h deleted file mode 100644 index bb6c1219ad..0000000000 --- a/scene/3d/quad.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************/ -/* quad.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#ifndef QUAD_H -#define QUAD_H - -#include "rid.h" -#include "scene/3d/visual_instance.h" - -class Quad : public GeometryInstance { - - GDCLASS(Quad, GeometryInstance); - - Vector3::Axis axis; - bool centered; - Vector2 offset; - Vector2 size; - - Rect3 aabb; - bool configured; - bool pending_update; - RID mesh; - - void _update(); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_axis(Vector3::Axis p_axis); - Vector3::Axis get_axis() const; - - void set_size(const Vector2 &p_sizze); - Vector2 get_size() const; - - void set_offset(const Vector2 &p_offset); - Vector2 get_offset() const; - - void set_centered(bool p_enabled); - bool is_centered() const; - - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; - virtual Rect3 get_aabb() const; - - Quad(); - ~Quad(); -}; - -#endif // QUAD_H diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp index 345afd3edf..67e7fb0e12 100644 --- a/scene/3d/ray_cast.cpp +++ b/scene/3d/ray_cast.cpp @@ -46,14 +46,14 @@ Vector3 RayCast::get_cast_to() const { return cast_to; } -void RayCast::set_layer_mask(uint32_t p_mask) { +void RayCast::set_collision_layer(uint32_t p_layer) { - layer_mask = p_mask; + collision_layer = p_layer; } -uint32_t RayCast::get_layer_mask() const { +uint32_t RayCast::get_collision_layer() const { - return layer_mask; + return collision_layer; } void RayCast::set_type_mask(uint32_t p_mask) { @@ -170,7 +170,7 @@ void RayCast::_update_raycast_state() { PhysicsDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) { + if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_layer, type_mask)) { collided = true; against = rr.collider_id; @@ -243,15 +243,15 @@ void RayCast::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast::clear_exceptions); - ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast::set_layer_mask); - ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast::get_layer_mask); + ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &RayCast::set_collision_layer); + ClassDB::bind_method(D_METHOD("get_collision_layer"), &RayCast::get_collision_layer); ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast::set_type_mask); ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast::get_type_mask); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer"); ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask"); } @@ -323,7 +323,7 @@ RayCast::RayCast() { against = 0; collided = false; against_shape = 0; - layer_mask = 1; + collision_layer = 1; type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION; cast_to = Vector3(0, -1, 0); debug_shape = NULL; diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h index 63a53d724f..e9b34c4f75 100644 --- a/scene/3d/ray_cast.h +++ b/scene/3d/ray_cast.h @@ -47,7 +47,7 @@ class RayCast : public Spatial { Set<RID> exclude; - uint32_t layer_mask; + uint32_t collision_layer; uint32_t type_mask; Node *debug_shape; @@ -69,8 +69,8 @@ public: void set_cast_to(const Vector3 &p_point); Vector3 get_cast_to() const; - void set_layer_mask(uint32_t p_mask); - uint32_t get_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; void set_type_mask(uint32_t p_mask); uint32_t get_type_mask() const; diff --git a/scene/3d/test_cube.cpp b/scene/3d/test_cube.cpp deleted file mode 100644 index af09bef7a7..0000000000 --- a/scene/3d/test_cube.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************/ -/* test_cube.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#include "test_cube.h" -#include "servers/visual_server.h" - -Rect3 TestCube::get_aabb() const { - - return Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2)); -} -PoolVector<Face3> TestCube::get_faces(uint32_t p_usage_flags) const { - - return PoolVector<Face3>(); -} - -TestCube::TestCube() { - - set_base(VisualServer::get_singleton()->get_test_cube()); -} - -TestCube::~TestCube() { -} diff --git a/scene/3d/test_cube.h b/scene/3d/test_cube.h deleted file mode 100644 index db2bef67fe..0000000000 --- a/scene/3d/test_cube.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************/ -/* test_cube.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#ifndef TEST_CUBE_H -#define TEST_CUBE_H - -#include "rid.h" -#include "scene/3d/visual_instance.h" - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class TestCube : public GeometryInstance { - - GDCLASS(TestCube, GeometryInstance); - - RID instance; - -public: - virtual Rect3 get_aabb() const; - virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; - - TestCube(); - ~TestCube(); -}; - -#endif diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp index ad72a512d8..bcca834642 100644 --- a/scene/audio/audio_player.cpp +++ b/scene/audio/audio_player.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "audio_player.h" -void AudioPlayer::_mix_audio() { +void AudioStreamPlayer::_mix_audio() { if (!stream_playback.is_valid()) { return; @@ -95,7 +95,7 @@ void AudioPlayer::_mix_audio() { } } -void AudioPlayer::_notification(int p_what) { +void AudioStreamPlayer::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { @@ -111,7 +111,7 @@ void AudioPlayer::_notification(int p_what) { } } -void AudioPlayer::set_stream(Ref<AudioStream> p_stream) { +void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) { ERR_FAIL_COND(!p_stream.is_valid()); AudioServer::get_singleton()->lock(); @@ -136,21 +136,21 @@ void AudioPlayer::set_stream(Ref<AudioStream> p_stream) { AudioServer::get_singleton()->unlock(); } -Ref<AudioStream> AudioPlayer::get_stream() const { +Ref<AudioStream> AudioStreamPlayer::get_stream() const { return stream; } -void AudioPlayer::set_volume_db(float p_volume) { +void AudioStreamPlayer::set_volume_db(float p_volume) { volume_db = p_volume; } -float AudioPlayer::get_volume_db() const { +float AudioStreamPlayer::get_volume_db() const { return volume_db; } -void AudioPlayer::play(float p_from_pos) { +void AudioStreamPlayer::play(float p_from_pos) { if (stream_playback.is_valid()) { mix_volume_db = volume_db; //reset volume ramp @@ -159,21 +159,21 @@ void AudioPlayer::play(float p_from_pos) { } } -void AudioPlayer::seek(float p_seconds) { +void AudioStreamPlayer::seek(float p_seconds) { if (stream_playback.is_valid()) { setseek = p_seconds; } } -void AudioPlayer::stop() { +void AudioStreamPlayer::stop() { if (stream_playback.is_valid()) { active = false; } } -bool AudioPlayer::is_playing() const { +bool AudioStreamPlayer::is_playing() const { if (stream_playback.is_valid()) { return active && stream_playback->is_playing(); @@ -182,7 +182,7 @@ bool AudioPlayer::is_playing() const { return false; } -float AudioPlayer::get_pos() { +float AudioStreamPlayer::get_pos() { if (stream_playback.is_valid()) { return stream_playback->get_pos(); @@ -191,14 +191,14 @@ float AudioPlayer::get_pos() { return 0; } -void AudioPlayer::set_bus(const StringName &p_bus) { +void AudioStreamPlayer::set_bus(const StringName &p_bus) { //if audio is active, must lock this AudioServer::get_singleton()->lock(); bus = p_bus; AudioServer::get_singleton()->unlock(); } -StringName AudioPlayer::get_bus() const { +StringName AudioStreamPlayer::get_bus() const { for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { if (AudioServer::get_singleton()->get_bus_name(i) == bus) { @@ -208,38 +208,38 @@ StringName AudioPlayer::get_bus() const { return "Master"; } -void AudioPlayer::set_autoplay(bool p_enable) { +void AudioStreamPlayer::set_autoplay(bool p_enable) { autoplay = p_enable; } -bool AudioPlayer::is_autoplay_enabled() { +bool AudioStreamPlayer::is_autoplay_enabled() { return autoplay; } -void AudioPlayer::set_mix_target(MixTarget p_target) { +void AudioStreamPlayer::set_mix_target(MixTarget p_target) { mix_target = p_target; } -AudioPlayer::MixTarget AudioPlayer::get_mix_target() const { +AudioStreamPlayer::MixTarget AudioStreamPlayer::get_mix_target() const { return mix_target; } -void AudioPlayer::_set_playing(bool p_enable) { +void AudioStreamPlayer::_set_playing(bool p_enable) { if (p_enable) play(); else stop(); } -bool AudioPlayer::_is_active() const { +bool AudioStreamPlayer::_is_active() const { return active; } -void AudioPlayer::_validate_property(PropertyInfo &property) const { +void AudioStreamPlayer::_validate_property(PropertyInfo &property) const { if (property.name == "bus") { @@ -255,39 +255,39 @@ void AudioPlayer::_validate_property(PropertyInfo &property) const { } } -void AudioPlayer::_bus_layout_changed() { +void AudioStreamPlayer::_bus_layout_changed() { _change_notify(); } -void AudioPlayer::_bind_methods() { +void AudioStreamPlayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioPlayer::set_stream); - ClassDB::bind_method(D_METHOD("get_stream"), &AudioPlayer::get_stream); + ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioStreamPlayer::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer::get_stream); - ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioPlayer::set_volume_db); - ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioPlayer::get_volume_db); + ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer::get_volume_db); - ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioPlayer::play, DEFVAL(0.0)); - ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioPlayer::seek); - ClassDB::bind_method(D_METHOD("stop"), &AudioPlayer::stop); + ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioStreamPlayer::play, DEFVAL(0.0)); + ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioStreamPlayer::seek); + ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer::stop); - ClassDB::bind_method(D_METHOD("is_playing"), &AudioPlayer::is_playing); - ClassDB::bind_method(D_METHOD("get_pos"), &AudioPlayer::get_pos); + ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing); + ClassDB::bind_method(D_METHOD("get_pos"), &AudioStreamPlayer::get_pos); - ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioPlayer::set_bus); - ClassDB::bind_method(D_METHOD("get_bus"), &AudioPlayer::get_bus); + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus); - ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioPlayer::set_autoplay); - ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioPlayer::is_autoplay_enabled); + ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer::set_autoplay); + ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer::is_autoplay_enabled); - ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioPlayer::set_mix_target); - ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioPlayer::get_mix_target); + ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioStreamPlayer::set_mix_target); + ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioStreamPlayer::get_mix_target); - ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioPlayer::_set_playing); - ClassDB::bind_method(D_METHOD("_is_active"), &AudioPlayer::_is_active); + ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer::_set_playing); + ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer::_is_active); - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioPlayer::_bus_layout_changed); + ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer::_bus_layout_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); @@ -297,7 +297,7 @@ void AudioPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); } -AudioPlayer::AudioPlayer() { +AudioStreamPlayer::AudioStreamPlayer() { mix_volume_db = 0; volume_db = 0; @@ -309,5 +309,5 @@ AudioPlayer::AudioPlayer() { AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); } -AudioPlayer::~AudioPlayer() { +AudioStreamPlayer::~AudioStreamPlayer() { } diff --git a/scene/audio/audio_player.h b/scene/audio/audio_player.h index 5a8a8494e1..8bd6844dec 100644 --- a/scene/audio/audio_player.h +++ b/scene/audio/audio_player.h @@ -33,9 +33,9 @@ #include "scene/main/node.h" #include "servers/audio/audio_stream.h" -class AudioPlayer : public Node { +class AudioStreamPlayer : public Node { - GDCLASS(AudioPlayer, Node) + GDCLASS(AudioStreamPlayer, Node) public: enum MixTarget { @@ -60,7 +60,7 @@ private: MixTarget mix_target; void _mix_audio(); - static void _mix_audios(void *self) { reinterpret_cast<AudioPlayer *>(self)->_mix_audio(); } + static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer *>(self)->_mix_audio(); } void _set_playing(bool p_enable); bool _is_active() const; @@ -94,9 +94,9 @@ public: void set_mix_target(MixTarget p_target); MixTarget get_mix_target() const; - AudioPlayer(); - ~AudioPlayer(); + AudioStreamPlayer(); + ~AudioStreamPlayer(); }; -VARIANT_ENUM_CAST(AudioPlayer::MixTarget) +VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget) #endif // AUDIOPLAYER_H diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp deleted file mode 100644 index 1616272e66..0000000000 --- a/scene/gui/button_array.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/*************************************************************************/ -/* button_array.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#include "button_array.h" - -bool ButtonArray::_set(const StringName &p_name, const Variant &p_value) { - - String n = String(p_name); - if (n.begins_with("button/")) { - - String what = n.get_slicec('/', 1); - if (what == "count") { - int new_size = p_value; - if (new_size > 0 && buttons.size() == 0) { - selected = 0; - } - - if (new_size < buttons.size()) { - if (selected >= new_size) - selected = new_size - 1; - } - buttons.resize(new_size); - _change_notify(); - minimum_size_changed(); - } else if (what == "align") { - set_align(Align(p_value.operator int())); - } else if (what == "selected") { - set_selected(p_value); - } else if (what == "min_button_size") { - min_button_size = p_value; - } else { - int idx = what.to_int(); - ERR_FAIL_INDEX_V(idx, buttons.size(), false); - String f = n.get_slicec('/', 2); - if (f == "text") { - buttons[idx].text = p_value; - buttons[idx].xl_text = XL_MESSAGE(p_value); - } else if (f == "tooltip") - buttons[idx].tooltip = p_value; - else if (f == "icon") - buttons[idx].icon = p_value; - else - return false; - } - - update(); - return true; - } - - return false; -} - -bool ButtonArray::_get(const StringName &p_name, Variant &r_ret) const { - - String n = String(p_name); - if (n.begins_with("button/")) { - - String what = n.get_slicec('/', 1); - if (what == "count") { - r_ret = buttons.size(); - } else if (what == "align") { - r_ret = get_align(); - } else if (what == "selected") { - r_ret = get_selected(); - } else if (what == "min_button_size") { - r_ret = min_button_size; - } else { - int idx = what.to_int(); - ERR_FAIL_INDEX_V(idx, buttons.size(), false); - String f = n.get_slicec('/', 2); - if (f == "text") - r_ret = buttons[idx].text; - else if (f == "tooltip") - r_ret = buttons[idx].tooltip; - else if (f == "icon") - r_ret = buttons[idx].icon; - else - return false; - } - - return true; - } - - return false; -} -void ButtonArray::_get_property_list(List<PropertyInfo> *p_list) const { - - p_list->push_back(PropertyInfo(Variant::INT, "button/count", PROPERTY_HINT_RANGE, "0,512,1")); - p_list->push_back(PropertyInfo(Variant::INT, "button/min_button_size", PROPERTY_HINT_RANGE, "0,1024,1")); - p_list->push_back(PropertyInfo(Variant::INT, "button/align", PROPERTY_HINT_ENUM, "Begin,Center,End,Fill,Expand")); - for (int i = 0; i < buttons.size(); i++) { - String base = "button/" + itos(i) + "/"; - p_list->push_back(PropertyInfo(Variant::STRING, base + "text")); - p_list->push_back(PropertyInfo(Variant::STRING, base + "tooltip")); - p_list->push_back(PropertyInfo(Variant::OBJECT, base + "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture")); - } - if (buttons.size() > 0) { - p_list->push_back(PropertyInfo(Variant::INT, "button/selected", PROPERTY_HINT_RANGE, "0," + itos(buttons.size() - 1) + ",1")); - } -} - -Size2 ButtonArray::get_minimum_size() const { - - Ref<StyleBox> style_normal = get_stylebox("normal"); - Ref<StyleBox> style_selected = get_stylebox("selected"); - Ref<Font> font_normal = get_font("font"); - Ref<Font> font_selected = get_font("font_selected"); - int icon_sep = get_constant("icon_separator"); - int button_sep = get_constant("button_separator"); - - Size2 minsize; - - for (int i = 0; i < buttons.size(); i++) { - - Ref<StyleBox> sb = i == selected ? style_selected : style_normal; - Ref<Font> f = i == selected ? font_selected : font_normal; - - Size2 ms; - ms = f->get_string_size(buttons[i].xl_text); - if (buttons[i].icon.is_valid()) { - - Size2 bs = buttons[i].icon->get_size(); - ms.height = MAX(ms.height, bs.height); - ms.width += bs.width + icon_sep; - } - - ms += sb->get_minimum_size(); - - buttons[i]._ms_cache = ms[orientation]; - - minsize[orientation] += ms[orientation]; - if (i > 0) - minsize[orientation] += button_sep; - minsize[!orientation] = MAX(minsize[!orientation], ms[!orientation]); - } - - return minsize; -} - -void ButtonArray::_notification(int p_what) { - - switch (p_what) { - case NOTIFICATION_MOUSE_EXIT: { - hover = -1; - update(); - } break; - case NOTIFICATION_READY: { - MethodInfo mi; - mi.name = "mouse_sub_enter"; - - add_user_signal(mi); - - } break; - case NOTIFICATION_DRAW: { - - Size2 size = get_size(); - Size2 minsize = get_combined_minimum_size(); - Ref<StyleBox> style_normal = get_stylebox("normal"); - Ref<StyleBox> style_selected = get_stylebox("selected"); - Ref<StyleBox> style_focus = get_stylebox("focus"); - Ref<StyleBox> style_hover = get_stylebox("hover"); - Ref<Font> font_normal = get_font("font"); - Ref<Font> font_selected = get_font("font_selected"); - int icon_sep = get_constant("icon_separator"); - int button_sep = get_constant("button_separator"); - Color color_normal = get_color("font_color"); - Color color_selected = get_color("font_color_selected"); - - int sep = button_sep; - int ofs = 0; - int expand = 0; - - switch (align) { - case ALIGN_BEGIN: { - - ofs = 0; - } break; - case ALIGN_CENTER: { - - ofs = Math::floor((size[orientation] - minsize[orientation]) / 2); - } break; - case ALIGN_END: { - - ofs = Math::floor((size[orientation] - minsize[orientation])); - } break; - case ALIGN_FILL: { - - if (buttons.size() > 1) - sep += Math::floor((size[orientation] - minsize[orientation]) / (buttons.size() - 1.0)); - ofs = 0; - } break; - case ALIGN_EXPAND_FILL: { - - ofs = 0; - expand = size[orientation] - minsize[orientation]; - } break; - } - - int op_size = orientation == VERTICAL ? size.width : size.height; - - for (int i = 0; i < buttons.size(); i++) { - - int ms = buttons[i]._ms_cache; - int s = ms; - if (expand > 0) { - s += expand / buttons.size(); - } - if (min_button_size != -1 && s < min_button_size) { - s = min_button_size; - } - - Rect2 r; - r.position[orientation] = ofs; - r.position[!orientation] = 0; - r.size[orientation] = s; - r.size[!orientation] = op_size; - - Ref<Font> f; - Color c; - Point2 sbsize; - Point2 sbofs; - if (i == selected) { - draw_style_box(style_selected, r); - sbsize = style_selected->get_minimum_size(); - sbofs = style_selected->get_offset(); - f = font_selected; - c = color_selected; - if (has_focus()) - draw_style_box(style_focus, r); - } else { - if (hover == i) - draw_style_box(style_hover, r); - else if (!flat) - draw_style_box(style_normal, r); - sbsize = style_normal->get_minimum_size(); - sbofs = style_normal->get_offset(); - f = font_normal; - c = color_normal; - } - - Size2 ssize = f->get_string_size(buttons[i].xl_text); - if (buttons[i].icon.is_valid()) { - - ssize.x += buttons[i].icon->get_width(); - } - Point2 text_ofs = ((r.size - ssize - sbsize) / 2.0 + Point2(0, f->get_ascent())).floor() + sbofs; - if (buttons[i].icon.is_valid()) { - - draw_texture(buttons[i].icon, r.position + Point2(text_ofs.x, Math::floor((r.size.height - buttons[i].icon->get_height()) / 2.0))); - text_ofs.x += buttons[i].icon->get_width() + icon_sep; - } - draw_string(f, text_ofs + r.position, buttons[i].xl_text, c); - buttons[i]._pos_cache = ofs; - buttons[i]._size_cache = s; - - ofs += s; - ofs += sep; - } - - } break; - } -} - -void ButtonArray::_gui_input(const Ref<InputEvent> &p_event) { - - if ( - ((orientation == HORIZONTAL && p_event->is_action("ui_left")) || - (orientation == VERTICAL && p_event->is_action("ui_up"))) && - p_event->is_pressed() && selected > 0) { - set_selected(selected - 1); - accept_event(); - emit_signal("button_selected", selected); - return; - } - - if ( - ((orientation == HORIZONTAL && p_event->is_action("ui_right")) || - (orientation == VERTICAL && p_event->is_action("ui_down"))) && - p_event->is_pressed() && selected < (buttons.size() - 1)) { - set_selected(selected + 1); - accept_event(); - emit_signal("button_selected", selected); - return; - } - - Ref<InputEventMouseButton> mb = p_event; - - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - - int ofs = orientation == HORIZONTAL ? mb->get_position().x : mb->get_position().y; - - for (int i = 0; i < buttons.size(); i++) { - - if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache) { - - set_selected(i); - emit_signal("button_selected", i); - return; - } - } - } - - Ref<InputEventMouseMotion> mm = p_event; - - if (mm.is_valid()) { - - int ofs = orientation == HORIZONTAL ? mm->get_position().x : mm->get_position().y; - int new_hover = -1; - for (int i = 0; i < buttons.size(); i++) { - - if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache) { - - new_hover = i; - break; - } - } - - if (new_hover != hover) { - hover = new_hover; - emit_signal("mouse_sub_enter"); - update(); - } - } -} - -String ButtonArray::get_tooltip(const Point2 &p_pos) const { - - int ofs = orientation == HORIZONTAL ? p_pos.x : p_pos.y; - for (int i = 0; i < buttons.size(); i++) { - - if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache) - return buttons[i].tooltip; - } - return Control::get_tooltip(p_pos); -} - -void ButtonArray::set_align(Align p_align) { - - align = p_align; - update(); -} - -ButtonArray::Align ButtonArray::get_align() const { - - return align; -} - -void ButtonArray::set_flat(bool p_flat) { - - flat = p_flat; - update(); -} - -bool ButtonArray::is_flat() const { - - return flat; -} - -void ButtonArray::add_button(const String &p_text, const String &p_tooltip) { - - Button button; - button.text = p_text; - button.xl_text = XL_MESSAGE(p_text); - button.tooltip = p_tooltip; - buttons.push_back(button); - update(); - - if (selected == -1) - selected = 0; - - minimum_size_changed(); -} - -void ButtonArray::add_icon_button(const Ref<Texture> &p_icon, const String &p_text, const String &p_tooltip) { - - Button button; - button.text = p_text; - button.xl_text = XL_MESSAGE(p_text); - button.icon = p_icon; - button.tooltip = p_tooltip; - buttons.push_back(button); - if (selected == -1) - selected = 0; - - update(); -} - -void ButtonArray::set_button_text(int p_button, const String &p_text) { - - ERR_FAIL_INDEX(p_button, buttons.size()); - buttons[p_button].text = p_text; - buttons[p_button].xl_text = XL_MESSAGE(p_text); - update(); - minimum_size_changed(); -} - -void ButtonArray::set_button_tooltip(int p_button, const String &p_text) { - - ERR_FAIL_INDEX(p_button, buttons.size()); - buttons[p_button].tooltip = p_text; -} - -void ButtonArray::set_button_icon(int p_button, const Ref<Texture> &p_icon) { - - ERR_FAIL_INDEX(p_button, buttons.size()); - buttons[p_button].icon = p_icon; - update(); - minimum_size_changed(); -} - -String ButtonArray::get_button_text(int p_button) const { - - ERR_FAIL_INDEX_V(p_button, buttons.size(), ""); - return buttons[p_button].text; -} - -String ButtonArray::get_button_tooltip(int p_button) const { - - ERR_FAIL_INDEX_V(p_button, buttons.size(), ""); - return buttons[p_button].tooltip; -} - -Ref<Texture> ButtonArray::get_button_icon(int p_button) const { - - ERR_FAIL_INDEX_V(p_button, buttons.size(), Ref<Texture>()); - return buttons[p_button].icon; -} - -int ButtonArray::get_selected() const { - - return selected; -} - -int ButtonArray::get_hovered() const { - - return hover; -} - -void ButtonArray::set_selected(int p_selected) { - - ERR_FAIL_INDEX(p_selected, buttons.size()); - selected = p_selected; - update(); -} - -void ButtonArray::erase_button(int p_button) { - - ERR_FAIL_INDEX(p_button, buttons.size()); - buttons.remove(p_button); - if (p_button >= selected) - selected--; - if (selected < 0) - selected = 0; - if (selected >= buttons.size()) - selected = buttons.size() - 1; - - update(); -} - -void ButtonArray::clear() { - - buttons.clear(); - selected = -1; - update(); -} - -int ButtonArray::get_button_count() const { - - return buttons.size(); -} - -void ButtonArray::get_translatable_strings(List<String> *p_strings) const { - - for (int i = 0; i < buttons.size(); i++) { - p_strings->push_back(buttons[i].text); - p_strings->push_back(buttons[i].tooltip); - } -} - -void ButtonArray::_bind_methods() { - - ClassDB::bind_method(D_METHOD("add_button", "text", "tooltip"), &ButtonArray::add_button, DEFVAL("")); - ClassDB::bind_method(D_METHOD("add_icon_button", "icon:Texture", "text", "tooltip"), &ButtonArray::add_icon_button, DEFVAL(""), DEFVAL("")); - ClassDB::bind_method(D_METHOD("set_button_text", "button_idx", "text"), &ButtonArray::set_button_text); - ClassDB::bind_method(D_METHOD("set_button_tooltip", "button_idx", "text"), &ButtonArray::set_button_tooltip); - ClassDB::bind_method(D_METHOD("set_button_icon", "button_idx", "icon:Texture"), &ButtonArray::set_button_icon); - ClassDB::bind_method(D_METHOD("get_button_text", "button_idx"), &ButtonArray::get_button_text); - ClassDB::bind_method(D_METHOD("get_button_tooltip", "button_idx"), &ButtonArray::get_button_tooltip); - ClassDB::bind_method(D_METHOD("get_button_icon:Texture", "button_idx"), &ButtonArray::get_button_icon); - ClassDB::bind_method(D_METHOD("get_button_count"), &ButtonArray::get_button_count); - ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &ButtonArray::set_flat); - ClassDB::bind_method(D_METHOD("is_flat"), &ButtonArray::is_flat); - ClassDB::bind_method(D_METHOD("get_selected"), &ButtonArray::get_selected); - ClassDB::bind_method(D_METHOD("get_hovered"), &ButtonArray::get_hovered); - ClassDB::bind_method(D_METHOD("set_selected", "button_idx"), &ButtonArray::set_selected); - ClassDB::bind_method(D_METHOD("erase_button", "button_idx"), &ButtonArray::erase_button); - ClassDB::bind_method(D_METHOD("clear"), &ButtonArray::clear); - - ClassDB::bind_method(D_METHOD("_gui_input"), &ButtonArray::_gui_input); - - BIND_CONSTANT(ALIGN_BEGIN); - BIND_CONSTANT(ALIGN_CENTER); - BIND_CONSTANT(ALIGN_END); - BIND_CONSTANT(ALIGN_FILL); - BIND_CONSTANT(ALIGN_EXPAND_FILL); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); - - ADD_SIGNAL(MethodInfo("button_selected", PropertyInfo(Variant::INT, "button_idx"))); -} - -ButtonArray::ButtonArray(Orientation p_orientation) { - - orientation = p_orientation; - selected = -1; - set_focus_mode(FOCUS_ALL); - hover = -1; - flat = false; - min_button_size = -1; -} diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h deleted file mode 100644 index 0ebf681cb6..0000000000 --- a/scene/gui/button_array.h +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************/ -/* button_array.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 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. */ -/*************************************************************************/ -#ifndef BUTTON_ARRAY_H -#define BUTTON_ARRAY_H - -#include "scene/gui/control.h" - -class ButtonArray : public Control { - - GDCLASS(ButtonArray, Control); - -public: - enum Align { - ALIGN_BEGIN, - ALIGN_CENTER, - ALIGN_END, - ALIGN_FILL, - ALIGN_EXPAND_FILL - }; - -private: - Orientation orientation; - Align align; - - struct Button { - - String text; - String xl_text; - String tooltip; - Ref<Texture> icon; - mutable int _ms_cache; - mutable int _pos_cache; - mutable int _size_cache; - }; - - int selected; - int hover; - bool flat; - double min_button_size; - - Vector<Button> buttons; - -protected: - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List<PropertyInfo> *p_list) const; - - void _notification(int p_what); - static void _bind_methods(); - -public: - void _gui_input(const Ref<InputEvent> &p_event); - - void set_align(Align p_align); - Align get_align() const; - - void set_flat(bool p_flat); - bool is_flat() const; - - void add_button(const String &p_button, const String &p_tooltip = ""); - void add_icon_button(const Ref<Texture> &p_icon, const String &p_button = "", const String &p_tooltip = ""); - - void set_button_text(int p_button, const String &p_text); - void set_button_tooltip(int p_button, const String &p_text); - void set_button_icon(int p_button, const Ref<Texture> &p_icon); - - String get_button_text(int p_button) const; - String get_button_tooltip(int p_button) const; - Ref<Texture> get_button_icon(int p_button) const; - - int get_selected() const; - int get_hovered() const; - void set_selected(int p_selected); - - int get_button_count() const; - - void erase_button(int p_button); - void clear(); - - virtual Size2 get_minimum_size() const; - - virtual void get_translatable_strings(List<String> *p_strings) const; - virtual String get_tooltip(const Point2 &p_pos) const; - - ButtonArray(Orientation p_orientation = HORIZONTAL); -}; - -class HButtonArray : public ButtonArray { - GDCLASS(HButtonArray, ButtonArray); - -public: - HButtonArray() - : ButtonArray(HORIZONTAL){}; -}; - -class VButtonArray : public ButtonArray { - GDCLASS(VButtonArray, ButtonArray); - -public: - VButtonArray() - : ButtonArray(VERTICAL){}; -}; - -#endif // BUTTON_ARRAY_H diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index f0e486aa50..ee6af21dbd 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -48,7 +48,15 @@ void ColorPicker::_notification(int p_what) { btn_pick->set_icon(get_icon("screen_picker", "ColorPicker")); _update_color(); - } + } break; + + case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { + if (screen != NULL) { + if (screen->is_visible()) { + screen->hide(); + } + } + } break; } } @@ -84,9 +92,6 @@ void ColorPicker::set_pick_color(const Color &p_color) { if (!is_inside_tree()) return; - return; //it crashes, so returning - uv_edit->get_child(0)->cast_to<Control>()->update(); - w_edit->get_child(0)->cast_to<Control>()->update(); _update_color(); } @@ -156,6 +161,8 @@ void ColorPicker::_update_color() { _update_text_value(); sample->update(); + uv_edit->update(); + w_edit->update(); updating = false; } @@ -263,10 +270,10 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) { points.push_back(c->get_size()); points.push_back(Vector2(0, c->get_size().y)); Vector<Color> colors; - colors.push_back(Color(1, 1, 1)); - colors.push_back(Color(1, 1, 1)); - colors.push_back(Color()); - colors.push_back(Color()); + colors.push_back(Color(1, 1, 1, 1)); + colors.push_back(Color(1, 1, 1, 1)); + colors.push_back(Color(0, 0, 0, 1)); + colors.push_back(Color(0, 0, 0, 1)); c->draw_polygon(points, colors); Vector<Color> colors2; Color col = color; @@ -279,7 +286,7 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) { colors2.push_back(col); col.a = 0; colors2.push_back(col); - c->draw_polygon(points, colors); + c->draw_polygon(points, colors2); int x = CLAMP(c->get_size().x * s, 0, c->get_size().x); int y = CLAMP(c->get_size().y - c->get_size().y * v, 0, c->get_size().y); col = color; @@ -290,7 +297,7 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) { } else if (p_wich == 1) { Ref<Texture> hue = get_icon("color_hue", "ColorPicker"); c->draw_texture_rect(hue, Rect2(Point2(), c->get_size())); - int y = c->get_size().y - c->get_size().y * h; + int y = c->get_size().y - c->get_size().y * (1.0 - h); Color col = Color(); col.set_hsv(h, 1, 1); c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted()); @@ -343,7 +350,7 @@ void ColorPicker::_w_input(const Ref<InputEvent> &ev) { if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) { changing_color = true; - h = 1 - ((float)bev->get_position().y) / 256.0; + h = 1 - (256.0 - (float)bev->get_position().y) / 256.0; } else { changing_color = false; @@ -362,7 +369,8 @@ void ColorPicker::_w_input(const Ref<InputEvent> &ev) { if (!changing_color) return; float y = CLAMP((float)mev->get_position().y, 0, 256); - h = 1.0 - y / 256.0; + //h = 1.0 - y / 256.0; + h = y / 256.0; color.set_hsv(h, s, v, color.a); last_hsv = color; set_pick_color(color); @@ -424,19 +432,12 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &ev) { Viewport *r = get_tree()->get_root(); if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y))) return; - Ref<Image> img = r->get_screen_capture(); - if (!img.is_null()) { - last_capture = img; - r->queue_screen_capture(); - } - if (last_capture.is_valid() && !last_capture->empty()) { - int pw = last_capture->get_format() == Image::FORMAT_RGBA8 ? 4 : 3; - int ofs = (mev->get_global_position().y * last_capture->get_width() + mev->get_global_position().x) * pw; - - PoolVector<uint8_t>::Read r = last_capture->get_data().read(); - - Color c(r[ofs + 0] / 255.0, r[ofs + 1] / 255.0, r[ofs + 2] / 255.0); - + Ref<Image> img = r->get_texture()->get_data(); + if (img.is_valid() && !img->empty()) { + img->lock(); + Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position(); + Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y); + img->unlock(); set_pick_color(c); } } @@ -453,11 +454,11 @@ void ColorPicker::_screen_pick_pressed() { r->add_child(screen); screen->set_as_toplevel(true); screen->set_area_as_parent_rect(); + screen->set_default_cursor_shape(CURSOR_POINTING_HAND); screen->connect("gui_input", this, "_screen_input"); } screen->raise(); screen->show_modal(); - r->queue_screen_capture(); } void ColorPicker::_bind_methods() { @@ -629,6 +630,10 @@ void ColorPickerButton::_notification(int p_what) { Ref<StyleBox> normal = get_stylebox("normal"); draw_rect(Rect2(normal->get_offset(), get_size() - normal->get_minimum_size()), picker->get_pick_color()); } + + if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) { + popup->hide(); + } } void ColorPickerButton::set_pick_color(const Color &p_color) { diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index ca47c3a5f4..de624fd029 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -47,7 +47,6 @@ class ColorPicker : public BoxContainer { private: Control *screen; - Ref<Image> last_capture; Control *uv_edit; Control *w_edit; TextureRect *sample; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index ae30acf52e..45485b768e 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1184,6 +1184,7 @@ Size2 Control::get_parent_area_size() const { parent_size = get_viewport()->get_visible_rect().size; } + return parent_size; } diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/gradient_edit.cpp index 33e4ce0403..58bce57580 100644 --- a/scene/gui/color_ramp_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -27,10 +27,10 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "color_ramp_edit.h" +#include "gradient_edit.h" #include "os/keyboard.h" -ColorRampEdit::ColorRampEdit() { +GradientEdit::GradientEdit() { grabbed = -1; grabbing = false; set_focus_mode(FOCUS_ALL); @@ -46,7 +46,7 @@ ColorRampEdit::ColorRampEdit() { checker->create_from_image(img, ImageTexture::FLAG_REPEAT); } -int ColorRampEdit::_get_point_from_pos(int x) { +int GradientEdit::_get_point_from_pos(int x) { int result = -1; int total_w = get_size().width - get_size().height - 3; for (int i = 0; i < points.size(); i++) { @@ -58,7 +58,7 @@ int ColorRampEdit::_get_point_from_pos(int x) { return result; } -void ColorRampEdit::_show_color_picker() { +void GradientEdit::_show_color_picker() { if (grabbed == -1) return; Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10); @@ -68,10 +68,10 @@ void ColorRampEdit::_show_color_picker() { popup->popup(); } -ColorRampEdit::~ColorRampEdit() { +GradientEdit::~GradientEdit() { } -void ColorRampEdit::_gui_input(const Ref<InputEvent> &p_event) { +void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; @@ -272,7 +272,7 @@ void ColorRampEdit::_gui_input(const Ref<InputEvent> &p_event) { } } -void ColorRampEdit::_notification(int p_what) { +void GradientEdit::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { if (!picker->is_connected("color_changed", this, "_color_changed")) { @@ -370,7 +370,7 @@ void ColorRampEdit::_notification(int p_what) { } } -void ColorRampEdit::_draw_checker(int x, int y, int w, int h) { +void GradientEdit::_draw_checker(int x, int y, int w, int h) { //Draw it with polygon to insert UVs for scale Vector<Vector2> backPoints; backPoints.push_back(Vector2(x, y)); @@ -391,12 +391,12 @@ void ColorRampEdit::_draw_checker(int x, int y, int w, int h) { draw_polygon(backPoints, colorPoints, uvPoints, checker); } -Size2 ColorRampEdit::get_minimum_size() const { +Size2 GradientEdit::get_minimum_size() const { return Vector2(0, 16); } -void ColorRampEdit::_color_changed(const Color &p_color) { +void GradientEdit::_color_changed(const Color &p_color) { if (grabbed == -1) return; @@ -405,7 +405,7 @@ void ColorRampEdit::_color_changed(const Color &p_color) { emit_signal("ramp_changed"); } -void ColorRampEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) { +void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) { ERR_FAIL_COND(p_offsets.size() != p_colors.size()); points.clear(); @@ -420,33 +420,33 @@ void ColorRampEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> update(); } -Vector<float> ColorRampEdit::get_offsets() const { +Vector<float> GradientEdit::get_offsets() const { Vector<float> ret; for (int i = 0; i < points.size(); i++) ret.push_back(points[i].offset); return ret; } -Vector<Color> ColorRampEdit::get_colors() const { +Vector<Color> GradientEdit::get_colors() const { Vector<Color> ret; for (int i = 0; i < points.size(); i++) ret.push_back(points[i].color); return ret; } -void ColorRampEdit::set_points(Vector<Gradient::Point> &p_points) { +void GradientEdit::set_points(Vector<Gradient::Point> &p_points) { if (points.size() != p_points.size()) grabbed = -1; points.clear(); points = p_points; } -Vector<Gradient::Point> &ColorRampEdit::get_points() { +Vector<Gradient::Point> &GradientEdit::get_points() { return points; } -void ColorRampEdit::_bind_methods() { - ClassDB::bind_method(D_METHOD("_gui_input"), &ColorRampEdit::_gui_input); - ClassDB::bind_method(D_METHOD("_color_changed"), &ColorRampEdit::_color_changed); +void GradientEdit::_bind_methods() { + ClassDB::bind_method(D_METHOD("_gui_input"), &GradientEdit::_gui_input); + ClassDB::bind_method(D_METHOD("_color_changed"), &GradientEdit::_color_changed); ADD_SIGNAL(MethodInfo("ramp_changed")); } diff --git a/scene/gui/color_ramp_edit.h b/scene/gui/gradient_edit.h index 0fe447c43a..6c4ae6fd15 100644 --- a/scene/gui/color_ramp_edit.h +++ b/scene/gui/gradient_edit.h @@ -37,9 +37,9 @@ #define POINT_WIDTH 8 -class ColorRampEdit : public Control { +class GradientEdit : public Control { - GDCLASS(ColorRampEdit, Control); + GDCLASS(GradientEdit, Control); PopupPanel *popup; ColorPicker *picker; @@ -68,8 +68,8 @@ public: Vector<Gradient::Point> &get_points(); virtual Size2 get_minimum_size() const; - ColorRampEdit(); - virtual ~ColorRampEdit(); + GradientEdit(); + virtual ~GradientEdit(); }; /*class ColorRampEditPanel : public Panel diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index cdb7965444..600493b439 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -103,13 +103,17 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { } // test hovering to display right or close button + int hover_now = -1; int hover_buttons = -1; - hover = -1; for (int i = 0; i < tabs.size(); i++) { if (i < offset) continue; + Rect2 rect = get_tab_rect(i); + if (rect.has_point(pos)) { + hover_now = i; + } if (tabs[i].rb_rect.has_point(pos)) { rb_hover = i; cb_hover = -1; @@ -122,6 +126,10 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { break; } } + if (hover != hover_now) { + hover = hover_now; + emit_signal("tab_hover", hover); + } if (hover_buttons == -1) { // no hover rb_hover = hover_buttons; @@ -234,11 +242,13 @@ void Tabs::_notification(int p_what) { update(); } break; case NOTIFICATION_RESIZED: { - + _update_cache(); _ensure_no_over_offset(); + ensure_tab_visible(current); + } break; case NOTIFICATION_DRAW: { - + _update_cache(); RID ci = get_canvas_item(); Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); @@ -286,18 +296,7 @@ void Tabs::_notification(int p_what) { tabs[i].ofs_cache = w; - int lsize = get_tab_width(i); - - String text = tabs[i].text; - int slen = font->get_string_size(text).width; - - if (w + lsize > limit) { - max_drawn_tab = i - 1; - missing_right = true; - break; - } else { - max_drawn_tab = i; - } + int lsize = tabs[i].size_cache; Ref<StyleBox> sb; Color col; @@ -313,7 +312,15 @@ void Tabs::_notification(int p_what) { col = color_bg; } - Rect2 sb_rect = Rect2(w, 0, lsize, h); + if (w + lsize > limit) { + max_drawn_tab = i - 1; + missing_right = true; + break; + } else { + max_drawn_tab = i; + } + + Rect2 sb_rect = Rect2(w, 0, tabs[i].size_cache, h); sb->draw(ci, sb_rect); w += sb->get_margin(MARGIN_LEFT); @@ -323,13 +330,13 @@ void Tabs::_notification(int p_what) { if (icon.is_valid()) { icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2)); - if (text != "") + if (tabs[i].text != "") w += icon->get_width() + get_constant("hseparation"); } - font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), text, col); + font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), tabs[i].text, col, tabs[i].size_text); - w += slen; + w += tabs[i].size_text; if (tabs[i].right_button.is_valid()) { @@ -380,8 +387,6 @@ void Tabs::_notification(int p_what) { } w += sb->get_margin(MARGIN_RIGHT); - - tabs[i].size_cache = w - tabs[i].ofs_cache; } if (offset > 0 || missing_right) { @@ -419,6 +424,7 @@ void Tabs::set_current_tab(int p_current) { current = p_current; _change_notify("current_tab"); + _update_cache(); update(); } @@ -427,6 +433,10 @@ int Tabs::get_current_tab() const { return current; } +int Tabs::get_hovered_tab() const { + return hover; +} + void Tabs::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); @@ -480,15 +490,81 @@ Ref<Texture> Tabs::get_tab_right_button(int p_tab) const { return tabs[p_tab].right_button; } +void Tabs::_update_cache() { + Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); + Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); + Ref<StyleBox> tab_fg = get_stylebox("tab_fg"); + Ref<Font> font = get_font("font"); + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + int limit = get_size().width - incr->get_width() - decr->get_width(); + + int w = 0; + int mw = 0; + int size_fixed = 0; + int count_resize = 0; + for (int i = 0; i < tabs.size(); i++) { + tabs[i].ofs_cache = mw; + tabs[i].size_cache = get_tab_width(i); + tabs[i].size_text = font->get_string_size(tabs[i].text).width; + mw += tabs[i].size_cache; + if (tabs[i].size_cache <= min_width || i == current) { + size_fixed += tabs[i].size_cache; + } else { + count_resize++; + } + } + int m_width = min_width; + if (count_resize > 0) { + m_width = MAX((limit - size_fixed) / count_resize, min_width); + } + for (int i = 0; i < tabs.size(); i++) { + if (i < offset) + continue; + Ref<StyleBox> sb; + if (tabs[i].disabled) { + sb = tab_disabled; + } else if (i == current) { + sb = tab_fg; + } else { + sb = tab_bg; + } + int lsize = tabs[i].size_cache; + int slen = tabs[i].size_text; + if (min_width > 0 && mw > limit && i != current) { + if (lsize > m_width) { + slen = m_width - (sb->get_margin(MARGIN_LEFT) + sb->get_margin(MARGIN_RIGHT)); + if (tabs[i].icon.is_valid()) { + slen -= tabs[i].icon->get_width(); + slen -= get_constant("hseparation"); + } + if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) { + Ref<Texture> cb = get_icon("close"); + slen -= cb->get_width(); + slen -= get_constant("hseparation"); + } + slen = MAX(slen, 1); + lsize = m_width; + } + } + tabs[i].ofs_cache = w; + tabs[i].size_cache = lsize; + tabs[i].size_text = slen; + w += lsize; + } +} + void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { Tab t; t.text = p_str; t.icon = p_icon; t.disabled = false; + t.ofs_cache = 0; + t.size_cache = 0; tabs.push_back(t); - + _update_cache(); update(); minimum_size_changed(); } @@ -505,6 +581,7 @@ void Tabs::remove_tab(int p_idx) { tabs.remove(p_idx); if (current >= p_idx) current--; + _update_cache(); update(); minimum_size_changed(); @@ -587,7 +664,7 @@ void Tabs::_ensure_no_over_offset() { if (i < offset - 1) continue; - total_w += get_tab_width(i); + total_w += tabs[i].size_cache; } if (total_w < limit) { @@ -604,37 +681,35 @@ void Tabs::ensure_tab_visible(int p_idx) { if (!is_inside_tree()) return; + if (tabs.size() == 0) return; ERR_FAIL_INDEX(p_idx, tabs.size()); - _ensure_no_over_offset(); - - if (p_idx <= offset) { + if (p_idx == offset) { + return; + } + if (p_idx < offset) { offset = p_idx; update(); return; } + int prev_offset = offset; Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); int limit = get_size().width - incr->get_width() - decr->get_width(); - - int x = 0; - for (int i = 0; i < tabs.size(); i++) { - - if (i < offset) - continue; - - int sz = get_tab_width(i); - tabs[i].x_cache = x; - tabs[i].x_size_cache = sz; - x += sz; + for (int i = offset; i <= p_idx; i++) { + if (tabs[i].ofs_cache + tabs[i].size_cache > limit) { + offset++; + } } - while (offset < tabs.size() && ((tabs[p_idx].x_cache + tabs[p_idx].x_size_cache) - tabs[offset].x_cache) > limit) { - offset++; + if (prev_offset != offset) { + update(); } +} - update(); +Rect2 Tabs::get_tab_rect(int p_tab) { + return Rect2(tabs[p_tab].ofs_cache, 0, tabs[p_tab].size_cache, get_size().height); } void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { @@ -642,6 +717,10 @@ void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) { update(); } +void Tabs::set_min_width(int p_width) { + min_width = p_width; +} + void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input); @@ -663,6 +742,7 @@ void Tabs::_bind_methods() { ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("tab_close", PropertyInfo(Variant::INT, "tab"))); + ADD_SIGNAL(MethodInfo("tab_hover", PropertyInfo(Variant::INT, "tab"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); @@ -688,4 +768,6 @@ Tabs::Tabs() { cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER; offset = 0; max_drawn_tab = 0; + + min_width = 0; } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 61b97d2dff..65d409c410 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -59,6 +59,7 @@ private: int ofs_cache; bool disabled; int size_cache; + int size_text; int x_cache; int x_size_cache; @@ -74,7 +75,6 @@ private: bool missing_right; Vector<Tab> tabs; int current; - Control *_get_tab(int idx) const; int _get_top_margin() const; TabAlign tab_align; int rb_hover; @@ -85,9 +85,11 @@ private: CloseButtonDisplayPolicy cb_displaypolicy; int hover; // hovered tab + int min_width; int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); + void _update_cache(); protected: void _gui_input(const Ref<InputEvent> &p_event); @@ -117,13 +119,16 @@ public: int get_tab_count() const; void set_current_tab(int p_current); int get_current_tab() const; + int get_hovered_tab() const; void remove_tab(int p_idx); void clear_tabs(); void ensure_tab_visible(int p_idx); + void set_min_width(int p_width); + Rect2 get_tab_rect(int p_tab); Size2 get_minimum_size() const; Tabs(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 95fad83a28..714327c5b7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1156,6 +1156,7 @@ void Viewport::set_size_override(bool p_enable, const Size2 &p_size, const Vecto size_override_margin = p_margin; _update_rect(); _update_stretch_transform(); + emit_signal("size_changed"); } Size2 Viewport::get_size_override() const { @@ -1232,16 +1233,6 @@ Viewport::UpdateMode Viewport::get_update_mode() const { } //RID get_texture() const; -void Viewport::queue_screen_capture() { - - //VS::get_singleton()->viewport_queue_screen_capture(viewport); -} -Ref<Image> Viewport::get_screen_capture() const { - - //return VS::get_singleton()->viewport_get_screen_capture(viewport); - return Ref<Image>(); -} - Ref<ViewportTexture> Viewport::get_texture() const { return default_texture; @@ -2530,6 +2521,22 @@ Viewport::Usage Viewport::get_usage() const { return usage; } +void Viewport::set_debug_draw(DebugDraw p_debug_draw) { + + debug_draw = p_debug_draw; + VS::get_singleton()->viewport_set_debug_draw(viewport, VS::ViewportDebugDraw(p_debug_draw)); +} + +Viewport::DebugDraw Viewport::get_debug_draw() const { + + return debug_draw; +} + +int Viewport::get_render_info(RenderInfo p_info) { + + return VS::get_singleton()->viewport_get_render_info(viewport, VS::ViewportRenderInfo(p_info)); +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size); @@ -2564,8 +2571,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("is_size_override_enabled"), &Viewport::is_size_override_enabled); ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch); ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled); - ClassDB::bind_method(D_METHOD("queue_screen_capture"), &Viewport::queue_screen_capture); - ClassDB::bind_method(D_METHOD("get_screen_capture"), &Viewport::get_screen_capture); ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip); ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip); @@ -2586,6 +2591,11 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage); ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage); + ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw); + ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw); + + ClassDB::bind_method(D_METHOD("get_render_info", "info"), &Viewport::get_render_info); + ClassDB::bind_method(D_METHOD("get_texture:ViewportTexture"), &Viewport::get_texture); ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking); @@ -2640,6 +2650,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw"); ADD_GROUP("Render Target", "render_target_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame"); @@ -2674,6 +2685,19 @@ void Viewport::_bind_methods() { BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024); BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); + BIND_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_SHADER_CHANGES_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_SURFACE_CHANGES_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_DRAW_CALLS_IN_FRAME); + BIND_CONSTANT(RENDER_INFO_MAX); + + BIND_CONSTANT(DEBUG_DRAW_DISABLED); + BIND_CONSTANT(DEBUG_DRAW_UNSHADED); + BIND_CONSTANT(DEBUG_DRAW_OVERDRAW); + BIND_CONSTANT(DEBUG_DRAW_WIREFRAME); + BIND_CONSTANT(MSAA_DISABLED); BIND_CONSTANT(MSAA_2X); BIND_CONSTANT(MSAA_4X); @@ -2750,6 +2774,7 @@ Viewport::Viewport() { hdr = false; usage = USAGE_3D; + debug_draw = DEBUG_DRAW_DISABLED; } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index e619199424..bd9747d878 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -122,6 +122,24 @@ public: USAGE_3D_NO_EFFECTS, }; + enum RenderInfo { + + RENDER_INFO_OBJECTS_IN_FRAME, + RENDER_INFO_VERTICES_IN_FRAME, + RENDER_INFO_MATERIAL_CHANGES_IN_FRAME, + RENDER_INFO_SHADER_CHANGES_IN_FRAME, + RENDER_INFO_SURFACE_CHANGES_IN_FRAME, + RENDER_INFO_DRAW_CALLS_IN_FRAME, + RENDER_INFO_MAX + }; + + enum DebugDraw { + DEBUG_DRAW_DISABLED, + DEBUG_DRAW_UNSHADED, + DEBUG_DRAW_OVERDRAW, + DEBUG_DRAW_WIREFRAME, + }; + private: friend class ViewportTexture; @@ -204,6 +222,8 @@ private: RID texture_rid; uint32_t texture_flags; + DebugDraw debug_draw; + Usage usage; int shadow_atlas_size; @@ -393,9 +413,6 @@ public: Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; - void queue_screen_capture(); - Ref<Image> get_screen_capture() const; - void set_use_own_world(bool p_world); bool is_using_own_world() const; @@ -430,6 +447,11 @@ public: void set_usage(Usage p_usage); Usage get_usage() const; + void set_debug_draw(DebugDraw p_debug_draw); + DebugDraw get_debug_draw() const; + + int get_render_info(RenderInfo p_info); + Viewport(); ~Viewport(); }; @@ -438,5 +460,7 @@ VARIANT_ENUM_CAST(Viewport::UpdateMode); VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv); VARIANT_ENUM_CAST(Viewport::MSAA); VARIANT_ENUM_CAST(Viewport::Usage); +VARIANT_ENUM_CAST(Viewport::DebugDraw); +VARIANT_ENUM_CAST(Viewport::RenderInfo); #endif diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 9f078072d7..b2737353fb 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -42,7 +42,7 @@ #include "scene/2d/path_2d.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" -#include "scene/gui/button_array.h" + #include "scene/gui/button_group.h" #include "scene/gui/center_container.h" #include "scene/gui/check_box.h" @@ -74,7 +74,6 @@ #include "scene/gui/separator.h" #include "scene/gui/slider.h" #include "scene/gui/spin_box.h" -#include "scene/gui/spin_box.h" #include "scene/gui/split_container.h" #include "scene/gui/tab_container.h" #include "scene/gui/tabs.h" @@ -112,6 +111,7 @@ #include "scene/2d/ray_cast_2d.h" //#include "scene/2d/sound_player_2d.h" //#include "scene/2d/sample_player_2d.h" +#include "scene/2d/audio_stream_player_2d.h" #include "scene/2d/canvas_modulate.h" #include "scene/2d/navigation2d.h" #include "scene/2d/remote_transform_2d.h" @@ -130,7 +130,6 @@ #include "scene/animation/tween.h" #include "scene/main/resource_preloader.h" #include "scene/main/scene_main_loop.h" -#include "scene/main/scene_main_loop.h" #include "scene/resources/packed_scene.h" #include "scene/resources/mesh_data_tool.h" @@ -172,6 +171,8 @@ #include "scene/resources/sky_box.h" #include "scene/resources/texture.h" +#include "scene/resources/primitive_meshes.h" + #include "scene/resources/shader_graph.h" #include "scene/resources/world.h" @@ -206,9 +207,7 @@ #include "scene/3d/physics_body.h" #include "scene/3d/portal.h" #include "scene/3d/position_3d.h" -#include "scene/3d/quad.h" #include "scene/3d/reflection_probe.h" -#include "scene/3d/test_cube.h" #include "scene/resources/environment.h" #include "scene/3d/area.h" @@ -276,7 +275,7 @@ void register_scene_types() { String theme_path = GLOBAL_DEF("gui/theme/custom", ""); GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); String font_path = GLOBAL_DEF("gui/theme/custom_font", ""); - GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.fnt", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); + GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)); if (theme_path != String()) { Ref<Theme> theme = ResourceLoader::load(theme_path); @@ -360,9 +359,6 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init - ClassDB::register_virtual_class<ButtonArray>(); - ClassDB::register_class<HButtonArray>(); - ClassDB::register_class<VButtonArray>(); ClassDB::register_class<TextureProgress>(); ClassDB::register_class<ItemList>(); @@ -410,7 +406,6 @@ void register_scene_types() { ClassDB::register_class<Camera>(); ClassDB::register_class<Listener>(); ClassDB::register_class<InterpolatedCamera>(); - ClassDB::register_class<TestCube>(); ClassDB::register_class<MeshInstance>(); ClassDB::register_class<ImmediateGeometry>(); ClassDB::register_class<Sprite3D>(); @@ -426,7 +421,6 @@ void register_scene_types() { ClassDB::register_class<Portal>(); ClassDB::register_class<Particles>(); ClassDB::register_class<Position3D>(); - ClassDB::register_class<Quad>(); ClassDB::register_class<NavigationMeshInstance>(); ClassDB::register_class<NavigationMesh>(); ClassDB::register_class<Navigation>(); @@ -525,6 +519,14 @@ void register_scene_types() { #ifndef _3D_DISABLED ClassDB::register_virtual_class<Mesh>(); ClassDB::register_class<ArrayMesh>(); + ClassDB::register_virtual_class<PrimitiveMesh>(); + ClassDB::register_class<CapsuleMesh>(); + ClassDB::register_class<CubeMesh>(); + ClassDB::register_class<CylinderMesh>(); + ClassDB::register_class<PlaneMesh>(); + ClassDB::register_class<PrismMesh>(); + ClassDB::register_class<QuadMesh>(); + ClassDB::register_class<SphereMesh>(); ClassDB::register_virtual_class<Material>(); ClassDB::register_class<SpatialMaterial>(); ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial"); @@ -590,7 +592,8 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init - ClassDB::register_class<AudioPlayer>(); + ClassDB::register_class<AudioStreamPlayer>(); + ClassDB::register_class<AudioStreamPlayer2D>(); ClassDB::register_virtual_class<VideoStream>(); ClassDB::register_class<AudioStreamSample>(); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index ef5befac65..b363f2b666 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -37,7 +37,7 @@ class Animation : public Resource { GDCLASS(Animation, Resource); - RES_BASE_EXTENSION("anm"); + RES_BASE_EXTENSION("anim"); public: enum TrackType { diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h index 84d450e3f2..cd02df512f 100644 --- a/scene/resources/audio_stream_sample.h +++ b/scene/resources/audio_stream_sample.h @@ -84,7 +84,7 @@ public: class AudioStreamSample : public AudioStream { GDCLASS(AudioStreamSample, AudioStream) - RES_BASE_EXTENSION("smp") + RES_BASE_EXTENSION("sample") public: enum Format { diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index e40fc0d4be..a435ba06cc 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -315,7 +315,7 @@ void Environment::_validate_property(PropertyInfo &property) const { void Environment::set_ssr_enabled(bool p_enable) { ssr_enabled = p_enable; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); _change_notify(); } @@ -327,57 +327,47 @@ bool Environment::is_ssr_enabled() const { void Environment::set_ssr_max_steps(int p_steps) { ssr_max_steps = p_steps; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); } int Environment::get_ssr_max_steps() const { return ssr_max_steps; } -void Environment::set_ssr_accel(float p_accel) { +void Environment::set_ssr_fade_in(float p_fade_in) { - ssr_accel = p_accel; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + ssr_fade_in = p_fade_in; + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); } -float Environment::get_ssr_accel() const { +float Environment::get_ssr_fade_in() const { - return ssr_accel; + return ssr_fade_in; } -void Environment::set_ssr_fade(float p_fade) { +void Environment::set_ssr_fade_out(float p_fade_out) { - ssr_fade = p_fade; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + ssr_fade_out = p_fade_out; + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); } -float Environment::get_ssr_fade() const { +float Environment::get_ssr_fade_out() const { - return ssr_fade; + return ssr_fade_out; } void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) { ssr_depth_tolerance = p_depth_tolerance; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); } float Environment::get_ssr_depth_tolerance() const { return ssr_depth_tolerance; } -void Environment::set_ssr_smooth(bool p_enable) { - - ssr_smooth = p_enable; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); -} -bool Environment::is_ssr_smooth() const { - - return ssr_smooth; -} - void Environment::set_ssr_rough(bool p_enable) { ssr_roughness = p_enable; - VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness); + VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness); } bool Environment::is_ssr_rough() const { @@ -954,18 +944,15 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ssr_max_steps", "max_steps"), &Environment::set_ssr_max_steps); ClassDB::bind_method(D_METHOD("get_ssr_max_steps"), &Environment::get_ssr_max_steps); - ClassDB::bind_method(D_METHOD("set_ssr_accel", "accel"), &Environment::set_ssr_accel); - ClassDB::bind_method(D_METHOD("get_ssr_accel"), &Environment::get_ssr_accel); + ClassDB::bind_method(D_METHOD("set_ssr_fade_in", "fade_in"), &Environment::set_ssr_fade_in); + ClassDB::bind_method(D_METHOD("get_ssr_fade_in"), &Environment::get_ssr_fade_in); - ClassDB::bind_method(D_METHOD("set_ssr_fade", "fade"), &Environment::set_ssr_fade); - ClassDB::bind_method(D_METHOD("get_ssr_fade"), &Environment::get_ssr_fade); + ClassDB::bind_method(D_METHOD("set_ssr_fade_out", "fade_out"), &Environment::set_ssr_fade_out); + ClassDB::bind_method(D_METHOD("get_ssr_fade_out"), &Environment::get_ssr_fade_out); ClassDB::bind_method(D_METHOD("set_ssr_depth_tolerance", "depth_tolerance"), &Environment::set_ssr_depth_tolerance); ClassDB::bind_method(D_METHOD("get_ssr_depth_tolerance"), &Environment::get_ssr_depth_tolerance); - ClassDB::bind_method(D_METHOD("set_ssr_smooth", "smooth"), &Environment::set_ssr_smooth); - ClassDB::bind_method(D_METHOD("is_ssr_smooth"), &Environment::is_ssr_smooth); - ClassDB::bind_method(D_METHOD("set_ssr_rough", "rough"), &Environment::set_ssr_rough); ClassDB::bind_method(D_METHOD("is_ssr_rough"), &Environment::is_ssr_rough); @@ -973,9 +960,9 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_accel", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_ssr_accel", "get_ssr_accel"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade", PROPERTY_HINT_EXP_EASING), "set_ssr_fade", "get_ssr_fade"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_accel_smooth"), "set_ssr_smooth", "is_ssr_smooth"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_roughness"), "set_ssr_rough", "is_ssr_rough"); ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled); @@ -1179,10 +1166,9 @@ Environment::Environment() { ssr_enabled = false; ssr_max_steps = 64; - ssr_accel = 0.04; - ssr_fade = 2.0; + ssr_fade_in = 0.15; + ssr_fade_out = 2.0; ssr_depth_tolerance = 0.2; - ssr_smooth = true; ssr_roughness = true; ssao_enabled = false; diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 7df3458231..7eda8506b5 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -100,10 +100,9 @@ private: bool ssr_enabled; int ssr_max_steps; - float ssr_accel; - float ssr_fade; + float ssr_fade_in; + float ssr_fade_out; float ssr_depth_tolerance; - bool ssr_smooth; bool ssr_roughness; bool ssao_enabled; @@ -225,18 +224,15 @@ public: void set_ssr_max_steps(int p_steps); int get_ssr_max_steps() const; - void set_ssr_accel(float p_accel); - float get_ssr_accel() const; + void set_ssr_fade_in(float p_transition); + float get_ssr_fade_in() const; - void set_ssr_fade(float p_transition); - float get_ssr_fade() const; + void set_ssr_fade_out(float p_transition); + float get_ssr_fade_out() const; void set_ssr_depth_tolerance(float p_depth_tolerance); float get_ssr_depth_tolerance() const; - void set_ssr_smooth(bool p_enable); - bool is_ssr_smooth() const; - void set_ssr_rough(bool p_enable); bool is_ssr_rough() const; diff --git a/scene/resources/font.h b/scene/resources/font.h index 20978acccd..a04ffbdd4b 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -66,7 +66,7 @@ public: class BitmapFont : public Font { GDCLASS(BitmapFont, Font); - RES_BASE_EXTENSION("fnt"); + RES_BASE_EXTENSION("font"); Vector<Ref<Texture> > textures; diff --git a/scene/resources/material.h b/scene/resources/material.h index b6e85c8332..c043236489 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -43,7 +43,7 @@ class Material : public Resource { GDCLASS(Material, Resource); - RES_BASE_EXTENSION("mtl"); + RES_BASE_EXTENSION("material"); OBJ_SAVE_TYPE(Material); RID material; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 9f55f0c364..a3180ee1df 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1047,72 +1047,3 @@ ArrayMesh::~ArrayMesh() { VisualServer::get_singleton()->free(mesh); } - -//////////////////////// -#if 0 -void QuadMesh::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &QuadMesh::set_material); - ClassDB::bind_method(D_METHOD("get_material:Material"), &QuadMesh::get_material); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); -} - -void QuadMesh::set_material(const Ref<Material> &p_material) { - - surface_set_material(0, p_material); -} - -Ref<Material> QuadMesh::get_material() const { - - return surface_get_material(0); -} - -QuadMesh::QuadMesh() { - - PoolVector<Vector3> faces; - PoolVector<Vector3> normals; - PoolVector<float> tangents; - PoolVector<Vector2> uvs; - - faces.resize(4); - normals.resize(4); - tangents.resize(4 * 4); - uvs.resize(4); - - for (int i = 0; i < 4; i++) { - - static const Vector3 quad_faces[4] = { - Vector3(-1, -1, 0), - Vector3(-1, 1, 0), - Vector3(1, 1, 0), - Vector3(1, -1, 0), - }; - - faces.set(i, quad_faces[i]); - normals.set(i, Vector3(0, 0, 1)); - tangents.set(i * 4 + 0, 1.0); - tangents.set(i * 4 + 1, 0.0); - tangents.set(i * 4 + 2, 0.0); - tangents.set(i * 4 + 3, 1.0); - - static const Vector2 quad_uv[4] = { - Vector2(0, 1), - Vector2(0, 0), - Vector2(1, 0), - Vector2(1, 1), - }; - - uvs.set(i, quad_uv[i]); - } - - Array arr; - arr.resize(ARRAY_MAX); - arr[ARRAY_VERTEX] = faces; - arr[ARRAY_NORMAL] = normals; - arr[ARRAY_TANGENT] = tangents; - arr[ARRAY_TEX_UV] = uvs; - - add_surface_from_arrays(PRIMITIVE_TRIANGLE_FAN, arr); -} -#endif diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 7804a84f81..37fddf3aa6 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -140,7 +140,7 @@ public: class ArrayMesh : public Mesh { GDCLASS(ArrayMesh, Mesh); - RES_BASE_EXTENSION("msh"); + RES_BASE_EXTENSION("mesh"); private: struct Surface { @@ -214,23 +214,6 @@ public: ~ArrayMesh(); }; -#if 0 -class QuadMesh : public Mesh { - - GDCLASS(QuadMesh, Mesh) - -protected: - virtual bool _is_generated() const { return true; } - static void _bind_methods(); - -public: - void set_material(const Ref<Material> &p_material); - Ref<Material> get_material() const; - QuadMesh(); -}; - -#endif - VARIANT_ENUM_CAST(Mesh::ArrayType); VARIANT_ENUM_CAST(Mesh::PrimitiveType); VARIANT_ENUM_CAST(Mesh::BlendShapeMode); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index a381f54a19..cc39110a99 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -39,7 +39,7 @@ class MeshLibrary : public Resource { GDCLASS(MeshLibrary, Resource); - RES_BASE_EXTENSION("gt"); + RES_BASE_EXTENSION("meshlib"); struct Item { String name; diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 4a00685b9f..7d6a0ce44f 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -36,7 +36,7 @@ class MultiMesh : public Resource { GDCLASS(MultiMesh, Resource); - RES_BASE_EXTENSION("mmsh"); + RES_BASE_EXTENSION("multimesh"); public: enum TransformFormat { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp new file mode 100644 index 0000000000..d4221dcb3f --- /dev/null +++ b/scene/resources/primitive_meshes.cpp @@ -0,0 +1,1454 @@ +/*************************************************************************/ +/* primitive_meshes.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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. */ +/*************************************************************************/ + +#include "primitive_meshes.h" +#include "servers/visual_server.h" + +/** + PrimitiveMesh +*/ +void PrimitiveMesh::_update() { + if (!cache_is_dirty) + return; + + Array arr; + arr.resize(VS::ARRAY_MAX); + _create_mesh_array(arr); + + // in with the new + VisualServer::get_singleton()->mesh_clear(mesh); + VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr); + VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); + + cache_is_dirty = false; + + _clear_triangle_mesh(); + emit_changed(); +} + +void PrimitiveMesh::_queue_update() { + if (!cache_is_dirty) { + cache_is_dirty = true; + call_deferred("_update"); + } +} + +void PrimitiveMesh::set_aabb(Rect3 p_aabb) { + aabb = p_aabb; +} + +int PrimitiveMesh::get_surface_count() const { + return 1; +} + +int PrimitiveMesh::surface_get_array_len(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, 1, -1); + return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0); +} + +int PrimitiveMesh::surface_get_array_index_len(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, 1, -1); + return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); +} + +Array PrimitiveMesh::surface_get_arrays(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, 1, Array()); + return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0); +} + +uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, 1, 0); + return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0); +} + +Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { + return primitive_type; +} + +Ref<Material> PrimitiveMesh::surface_get_material(int p_idx) const { + return material; +} + +int PrimitiveMesh::get_blend_shape_count() const { + return 0; +} + +StringName PrimitiveMesh::get_blend_shape_name(int p_index) const { + return StringName(); +} + +Rect3 PrimitiveMesh::get_aabb() const { + return aabb; +} + +RID PrimitiveMesh::get_rid() const { + return mesh; +} + +void PrimitiveMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update"), &PrimitiveMesh::_update); + + ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &PrimitiveMesh::set_material); + ClassDB::bind_method(D_METHOD("get_material:Material"), &PrimitiveMesh::get_material); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); +} + +void PrimitiveMesh::set_material(const Ref<Material> &p_material) { + material = p_material; + if (!cache_is_dirty) { + // just apply it, else it'll happen when _update is called. + VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); + + _change_notify(); + emit_changed(); + }; +} + +Ref<Material> PrimitiveMesh::get_material() const { + return material; +} + +PrimitiveMesh::PrimitiveMesh() { + // defaults + mesh = VisualServer::get_singleton()->mesh_create(); + + // assume primitive triangles as the type, correct for all but one and it will change this :) + primitive_type = Mesh::PRIMITIVE_TRIANGLES; + + // make sure we do an update after we've finished constructing our object + cache_is_dirty = false; + _queue_update(); +} + +PrimitiveMesh::~PrimitiveMesh() { + VisualServer::get_singleton()->free(mesh); +} + +/** + CapsuleMesh +*/ + +void CapsuleMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, y, z, u, v, w; + float onethird = 1.0 / 3.0; + float twothirds = 2.0 / 3.0; + + set_aabb(Rect3(Vector3(-radius, (mid_height * -0.5) - radius, -radius), Vector3(radius * 2.0, mid_height + (2.0 * radius), radius * 2.0))); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + /* top hemisphere */ + thisrow = 0; + prevrow = 0; + for (j = 0; j <= (rings + 1); j++) { + v = j; + w; + + v /= (rings + 1); + w = sin(0.5 * Math_PI * v); + y = radius * cos(0.5 * Math_PI * v); + + for (i = 0; i <= radial_segments; i++) { + u = i; + u /= radial_segments; + + x = sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); + + Vector3 p = Vector3(x * radius * w, y, z * radius * w); + points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0)); + normals.push_back(p.normalized()); + ADD_TANGENT(-z, 0.0, x, -1.0) + uvs.push_back(Vector2(u, v * onethird)); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + }; + + prevrow = thisrow; + thisrow = point; + }; + + /* cylinder */ + thisrow = point; + prevrow = 0; + for (j = 0; j <= (rings + 1); j++) { + v = j; + v /= (rings + 1); + + y = mid_height * v; + y = (mid_height * 0.5) - y; + + for (i = 0; i <= radial_segments; i++) { + u = i; + u /= radial_segments; + + x = sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); + + Vector3 p = Vector3(x * radius, y, z * radius); + points.push_back(p); + normals.push_back(Vector3(x, 0.0, z)); + ADD_TANGENT(-z, 0.0, x, -1.0) + uvs.push_back(Vector2(u, onethird + (v * onethird))); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + }; + + prevrow = thisrow; + thisrow = point; + }; + + /* bottom hemisphere */ + thisrow = point; + prevrow = 0; + for (j = 0; j <= (rings + 1); j++) { + v = j; + w; + + v /= (rings + 1); + v += 1.0; + w = sin(0.5 * Math_PI * v); + y = radius * cos(0.5 * Math_PI * v); + + for (i = 0; i <= radial_segments; i++) { + float u = i; + u /= radial_segments; + + x = sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); + + Vector3 p = Vector3(x * radius * w, y, z * radius * w); + points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0)); + normals.push_back(p.normalized()); + ADD_TANGENT(-z, 0.0, x, -1.0) + uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird))); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + }; + + prevrow = thisrow; + thisrow = point; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void CapsuleMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleMesh::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleMesh::get_radius); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleMesh::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleMesh::get_mid_height); + + ClassDB::bind_method(D_METHOD("set_radial_segments", "segments"), &CapsuleMesh::set_radial_segments); + ClassDB::bind_method(D_METHOD("get_radial_segments"), &CapsuleMesh::get_radial_segments); + ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CapsuleMesh::set_rings); + ClassDB::bind_method(D_METHOD("get_rings"), &CapsuleMesh::get_rings); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_mid_height", "get_mid_height"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings"); +} + +void CapsuleMesh::set_radius(const float p_radius) { + radius = p_radius; + _queue_update(); +} + +float CapsuleMesh::get_radius() const { + return radius; +} + +void CapsuleMesh::set_mid_height(const float p_mid_height) { + mid_height = p_mid_height; + _queue_update(); +} + +float CapsuleMesh::get_mid_height() const { + return mid_height; +} + +void CapsuleMesh::set_radial_segments(const int p_segments) { + radial_segments = p_segments > 4 ? p_segments : 4; + _queue_update(); +} + +int CapsuleMesh::get_radial_segments() const { + return radial_segments; +} + +void CapsuleMesh::set_rings(const int p_rings) { + rings = p_rings > 1 ? p_rings : 1; + _queue_update(); +} + +int CapsuleMesh::get_rings() const { + return rings; +} + +CapsuleMesh::CapsuleMesh() { + // defaults + radius = 0.5; + mid_height = 0.5; + radial_segments = 64; + rings = 8; +} + +/** + CubeMesh +*/ + +void CubeMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, y, z; + float onethird = 1.0 / 3.0; + float twothirds = 2.0 / 3.0; + + Vector3 start_pos = size * -0.5; + + // set our bounding box + set_aabb(Rect3(start_pos, size)); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + // front + back + y = start_pos.y; + thisrow = point; + prevrow = 0; + for (j = 0; j <= subdivide_h + 1; j++) { + x = start_pos.x; + for (i = 0; i <= subdivide_w + 1; i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_w + 1.0)); + v /= (2.0 * (subdivide_h + 1.0)); + + // front + points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z! + normals.push_back(Vector3(0.0, 0.0, 1.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(u, v)); + point++; + + // back + points.push_back(Vector3(-x, -y, start_pos.z)); + normals.push_back(Vector3(0.0, 0.0, -1.0)); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(twothirds + u, v)); + point++; + + if (i > 0 && j > 0) { + int i2 = i * 2; + + // front + indices.push_back(prevrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + // back + indices.push_back(prevrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + }; + + x += size.x / (subdivide_w + 1.0); + }; + + y += size.y / (subdivide_h + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + // left + right + y = start_pos.y; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_h + 1); j++) { + z = start_pos.z; + for (i = 0; i <= (subdivide_d + 1); i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_d + 1.0)); + v /= (2.0 * (subdivide_h + 1.0)); + + // right + points.push_back(Vector3(-start_pos.x, -y, -z)); + normals.push_back(Vector3(1.0, 0.0, 0.0)); + ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + uvs.push_back(Vector2(onethird + u, v)); + point++; + + // left + points.push_back(Vector3(start_pos.x, -y, z)); + normals.push_back(Vector3(-1.0, 0.0, 0.0)); + ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + uvs.push_back(Vector2(u, 0.5 + v)); + point++; + + if (i > 0 && j > 0) { + int i2 = i * 2; + + // right + indices.push_back(prevrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + // left + indices.push_back(prevrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + }; + + z += size.z / (subdivide_d + 1.0); + }; + + y += size.y / (subdivide_h + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + // top + bottom + z = start_pos.z; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_d + 1); j++) { + x = start_pos.x; + for (i = 0; i <= (subdivide_w + 1); i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_w + 1.0)); + v /= (2.0 * (subdivide_d + 1.0)); + + // top + points.push_back(Vector3(-x, -start_pos.y, -z)); + normals.push_back(Vector3(0.0, 1.0, 0.0)); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(onethird + u, 0.5 + v)); + point++; + + // bottom + points.push_back(Vector3(x, start_pos.y, -z)); + normals.push_back(Vector3(0.0, -1.0, 0.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(twothirds + u, 0.5 + v)); + point++; + + if (i > 0 && j > 0) { + int i2 = i * 2; + + // top + indices.push_back(prevrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + // bottom + indices.push_back(prevrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + }; + + x += size.x / (subdivide_w + 1.0); + }; + + z += size.z / (subdivide_d + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void CubeMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &CubeMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &CubeMesh::get_size); + + ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &CubeMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &CubeMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &CubeMesh::set_subdivide_height); + ClassDB::bind_method(D_METHOD("get_subdivide_height"), &CubeMesh::get_subdivide_height); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &CubeMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &CubeMesh::get_subdivide_depth); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_height", "get_subdivide_height"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth"); +} + +void CubeMesh::set_size(const Vector3 &p_size) { + size = p_size; + _queue_update(); +} + +Vector3 CubeMesh::get_size() const { + return size; +} + +void CubeMesh::set_subdivide_width(const int p_subdivide) { + subdivide_w = p_subdivide > 0 ? p_subdivide : 0; + _queue_update(); +} + +int CubeMesh::get_subdivide_width() const { + return subdivide_w; +} + +void CubeMesh::set_subdivide_height(const int p_subdivide) { + subdivide_h = p_subdivide > 0 ? p_subdivide : 0; + _queue_update(); +} + +int CubeMesh::get_subdivide_height() const { + return subdivide_h; +} + +void CubeMesh::set_subdivide_depth(const int p_subdivide) { + subdivide_d = p_subdivide > 0 ? p_subdivide : 0; + _queue_update(); +} + +int CubeMesh::get_subdivide_depth() const { + return subdivide_d; +} + +CubeMesh::CubeMesh() { + // defaults + size = Vector3(1.0, 1.0, 1.0); + subdivide_w = 0; + subdivide_h = 0; + subdivide_d = 0; +} + +/** + CylinderMesh +*/ + +void CylinderMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, y, z, u, v, radius; + + radius = bottom_radius > top_radius ? bottom_radius : top_radius; + + set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + thisrow = 0; + prevrow = 0; + for (j = 0; j <= (rings + 1); j++) { + v = j; + v /= (rings + 1); + + radius = top_radius + ((bottom_radius - top_radius) * v); + + y = height * v; + y = (height * 0.5) - y; + + for (i = 0; i <= radial_segments; i++) { + u = i; + u /= radial_segments; + + x = sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); + + Vector3 p = Vector3(x * radius, y, z * radius); + points.push_back(p); + normals.push_back(Vector3(x, 0.0, z)); + ADD_TANGENT(-z, 0.0, x, -1.0) + uvs.push_back(Vector2(u, v * 0.5)); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + }; + + prevrow = thisrow; + thisrow = point; + }; + + // add top + if (top_radius > 0.0) { + y = height * 0.5; + + thisrow = point; + points.push_back(Vector3(0.0, y, 0.0)); + normals.push_back(Vector3(0.0, 1.0, 0.0)); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0) + uvs.push_back(Vector2(0.25, 0.75)); + point++; + + for (i = 0; i <= radial_segments; i++) { + float r = i; + r /= radial_segments; + + x = sin(r * (Math_PI * 2.0)); + z = cos(r * (Math_PI * 2.0)); + + u = ((x + 1.0) * 0.25); + v = 0.5 + ((z + 1.0) * 0.25); + + Vector3 p = Vector3(x * top_radius, y, z * top_radius); + points.push_back(p); + normals.push_back(Vector3(0.0, 1.0, 0.0)); + ADD_TANGENT(1.0, 0.0, 0.0, 1.0) + uvs.push_back(Vector2(u, v)); + point++; + + if (i > 0) { + indices.push_back(thisrow); + indices.push_back(point - 1); + indices.push_back(point - 2); + }; + }; + }; + + // add bottom + if (bottom_radius > 0.0) { + y = height * -0.5; + + thisrow = point; + points.push_back(Vector3(0.0, y, 0.0)); + normals.push_back(Vector3(0.0, -1.0, 0.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + uvs.push_back(Vector2(0.75, 0.75)); + point++; + + for (i = 0; i <= radial_segments; i++) { + float r = i; + r /= radial_segments; + + x = sin(r * (Math_PI * 2.0)); + z = cos(r * (Math_PI * 2.0)); + + u = 0.5 + ((x + 1.0) * 0.25); + v = 1.0 - ((z + 1.0) * 0.25); + + Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius); + points.push_back(p); + normals.push_back(Vector3(0.0, -1.0, 0.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0) + uvs.push_back(Vector2(u, v)); + point++; + + if (i > 0) { + indices.push_back(thisrow); + indices.push_back(point - 2); + indices.push_back(point - 1); + }; + }; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void CylinderMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_top_radius", "radius"), &CylinderMesh::set_top_radius); + ClassDB::bind_method(D_METHOD("get_top_radius"), &CylinderMesh::get_top_radius); + ClassDB::bind_method(D_METHOD("set_bottom_radius", "radius"), &CylinderMesh::set_bottom_radius); + ClassDB::bind_method(D_METHOD("get_bottom_radius"), &CylinderMesh::get_bottom_radius); + ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderMesh::set_height); + ClassDB::bind_method(D_METHOD("get_height"), &CylinderMesh::get_height); + + ClassDB::bind_method(D_METHOD("set_radial_segments", "segments"), &CylinderMesh::set_radial_segments); + ClassDB::bind_method(D_METHOD("get_radial_segments"), &CylinderMesh::get_radial_segments); + ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CylinderMesh::set_rings); + ClassDB::bind_method(D_METHOD("get_rings"), &CylinderMesh::get_rings); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_top_radius", "get_top_radius"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_bottom_radius", "get_bottom_radius"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings"); +} + +void CylinderMesh::set_top_radius(const float p_radius) { + top_radius = p_radius; + _queue_update(); +} + +float CylinderMesh::get_top_radius() const { + return top_radius; +} + +void CylinderMesh::set_bottom_radius(const float p_radius) { + bottom_radius = p_radius; + _queue_update(); +} + +float CylinderMesh::get_bottom_radius() const { + return bottom_radius; +} + +void CylinderMesh::set_height(const float p_height) { + height = p_height; + _queue_update(); +} + +float CylinderMesh::get_height() const { + return height; +} + +void CylinderMesh::set_radial_segments(const int p_segments) { + radial_segments = p_segments > 4 ? p_segments : 4; + _queue_update(); +} + +int CylinderMesh::get_radial_segments() const { + return radial_segments; +} + +void CylinderMesh::set_rings(const int p_rings) { + rings = p_rings > 0 ? p_rings : 0; + _queue_update(); +} + +int CylinderMesh::get_rings() const { + return rings; +} + +CylinderMesh::CylinderMesh() { + // defaults + top_radius = 0.5; + bottom_radius = 0.5; + height = 1.0; + radial_segments = 64; + rings = 4; +} + +/** + PlaneMesh +*/ + +void PlaneMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, z; + + Size2 start_pos = size * -0.5; + + set_aabb(Rect3(Vector3(start_pos.x, 0.0, start_pos.y), Vector3(size.x, 0.0, size.y))); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + /* top + bottom */ + z = start_pos.y; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_d + 1); j++) { + x = start_pos.x; + for (i = 0; i <= (subdivide_w + 1); i++) { + float u = i; + float v = j; + u /= (subdivide_w + 1.0); + v /= (subdivide_d + 1.0); + + points.push_back(Vector3(-x, 0.0, -z)); + normals.push_back(Vector3(0.0, 1.0, 0.0)); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(u, v)); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + + x += size.x / (subdivide_w + 1.0); + }; + + z += size.y / (subdivide_d + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void PlaneMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &PlaneMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &PlaneMesh::get_size); + + ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &PlaneMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PlaneMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "subdivide"), &PlaneMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PlaneMesh::get_subdivide_depth); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth"); +} + +void PlaneMesh::set_size(const Size2 &p_size) { + size = p_size; + _queue_update(); +} + +Size2 PlaneMesh::get_size() const { + return size; +} + +void PlaneMesh::set_subdivide_width(const int p_subdivide) { + subdivide_w = p_subdivide > 0 ? p_subdivide : 0; + _queue_update(); +} + +int PlaneMesh::get_subdivide_width() const { + return subdivide_w; +} + +void PlaneMesh::set_subdivide_depth(const int p_subdivide) { + subdivide_d = p_subdivide > 0 ? p_subdivide : 0; + _queue_update(); +} + +int PlaneMesh::get_subdivide_depth() const { + return subdivide_d; +} + +PlaneMesh::PlaneMesh() { + // defaults + size = Size2(1.0, 1.0); + subdivide_w = 0; + subdivide_d = 0; +} + +/** + PrismMesh +*/ + +void PrismMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, y, z; + float onethird = 1.0 / 3.0; + float twothirds = 2.0 / 3.0; + + Vector3 start_pos = size * -0.5; + + // set our bounding box + set_aabb(Rect3(start_pos, size)); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + /* front + back */ + y = start_pos.y; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_h + 1); j++) { + float scale = (y - start_pos.y) / size.y; + float scaled_size_x = size.x * scale; + float start_x = start_pos.x; + float offset_front = 0.0; + float offset_back = 0.0; + + start_x += (1.0 - scale) * size.x * left_to_right; + offset_front += (1.0 - scale) * onethird * left_to_right; + offset_back = (1.0 - scale) * onethird * (1.0 - left_to_right); + + x = 0.0; + for (i = 0; i <= (subdivide_w + 1); i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_w + 1.0)); + v /= (2.0 * (subdivide_h + 1.0)); + + u *= scale; + + /* front */ + points.push_back(Vector3(start_x + x, -y, -start_pos.z)); // double negative on the Z! + normals.push_back(Vector3(0.0, 0.0, 1.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(offset_front + u, v)); + point++; + + /* back */ + points.push_back(Vector3(start_x + scaled_size_x - x, -y, start_pos.z)); + normals.push_back(Vector3(0.0, 0.0, -1.0)); + ADD_TANGENT(1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(twothirds + offset_back + u, v)); + point++; + + if (i > 0 && j == 1) { + int i2 = i * 2; + + /* front */ + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + /* back */ + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + } else if (i > 0 && j > 0) { + int i2 = i * 2; + + /* front */ + indices.push_back(prevrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + /* back */ + indices.push_back(prevrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + }; + + x += scale * size.x / (subdivide_w + 1.0); + }; + + y += size.y / (subdivide_h + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + /* left + right */ + Vector3 normal_left, normal_right; + + normal_left = Vector3(-size.y, size.x * left_to_right, 0.0); + normal_right = Vector3(size.y, size.x * left_to_right, 0.0); + normal_left.normalize(); + normal_right.normalize(); + + y = start_pos.y; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_h + 1); j++) { + float left, right; + float scale = (y - start_pos.y) / size.y; + + left = start_pos.x + (size.x * (1.0 - scale) * left_to_right); + right = left + (size.x * scale); + + z = start_pos.z; + for (i = 0; i <= (subdivide_d + 1); i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_d + 1.0)); + v /= (2.0 * (subdivide_h + 1.0)); + + /* right */ + points.push_back(Vector3(right, -y, -z)); + normals.push_back(normal_right); + ADD_TANGENT(0.0, 0.0, 1.0, -1.0); + uvs.push_back(Vector2(onethird + u, v)); + point++; + + /* left */ + points.push_back(Vector3(left, -y, z)); + normals.push_back(normal_left); + ADD_TANGENT(0.0, 0.0, -1.0, -1.0); + uvs.push_back(Vector2(u, 0.5 + v)); + point++; + + if (i > 0 && j > 0) { + int i2 = i * 2; + + /* right */ + indices.push_back(prevrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2 - 2); + indices.push_back(prevrow + i2); + indices.push_back(thisrow + i2); + indices.push_back(thisrow + i2 - 2); + + /* left */ + indices.push_back(prevrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + indices.push_back(prevrow + i2 + 1); + indices.push_back(thisrow + i2 + 1); + indices.push_back(thisrow + i2 - 1); + }; + + z += size.z / (subdivide_d + 1.0); + }; + + y += size.y / (subdivide_h + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + /* bottom */ + z = start_pos.z; + thisrow = point; + prevrow = 0; + for (j = 0; j <= (subdivide_d + 1); j++) { + x = start_pos.x; + for (i = 0; i <= (subdivide_w + 1); i++) { + float u = i; + float v = j; + u /= (3.0 * (subdivide_w + 1.0)); + v /= (2.0 * (subdivide_d + 1.0)); + + /* bottom */ + points.push_back(Vector3(x, start_pos.y, -z)); + normals.push_back(Vector3(0.0, -1.0, 0.0)); + ADD_TANGENT(-1.0, 0.0, 0.0, -1.0); + uvs.push_back(Vector2(twothirds + u, 0.5 + v)); + point++; + + if (i > 0 && j > 0) { + /* bottom */ + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + + x += size.x / (subdivide_w + 1.0); + }; + + z += size.z / (subdivide_d + 1.0); + prevrow = thisrow; + thisrow = point; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void PrismMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_left_to_right", "left_to_right"), &PrismMesh::set_left_to_right); + ClassDB::bind_method(D_METHOD("get_left_to_right"), &PrismMesh::get_left_to_right); + + ClassDB::bind_method(D_METHOD("set_size", "size"), &PrismMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &PrismMesh::get_size); + + ClassDB::bind_method(D_METHOD("set_subdivide_width", "segments"), &PrismMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PrismMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_height", "segments"), &PrismMesh::set_subdivide_height); + ClassDB::bind_method(D_METHOD("get_subdivide_height"), &PrismMesh::get_subdivide_height); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "segments"), &PrismMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_height", "get_subdivide_height"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth"); +} + +void PrismMesh::set_left_to_right(const float p_left_to_right) { + left_to_right = p_left_to_right; + _queue_update(); +} + +float PrismMesh::get_left_to_right() const { + return left_to_right; +} + +void PrismMesh::set_size(const Vector3 &p_size) { + size = p_size; + _queue_update(); +} + +Vector3 PrismMesh::get_size() const { + return size; +} + +void PrismMesh::set_subdivide_width(const int p_divisions) { + subdivide_w = p_divisions > 0 ? p_divisions : 0; + _queue_update(); +} + +int PrismMesh::get_subdivide_width() const { + return subdivide_w; +} + +void PrismMesh::set_subdivide_height(const int p_divisions) { + subdivide_h = p_divisions > 0 ? p_divisions : 0; + _queue_update(); +} + +int PrismMesh::get_subdivide_height() const { + return subdivide_h; +} + +void PrismMesh::set_subdivide_depth(const int p_divisions) { + subdivide_d = p_divisions > 0 ? p_divisions : 0; + _queue_update(); +} + +int PrismMesh::get_subdivide_depth() const { + return subdivide_d; +} + +PrismMesh::PrismMesh() { + // defaults + left_to_right = 0.5; + size = Vector3(1.0, 1.0, 1.0); + subdivide_w = 0; + subdivide_h = 0; + subdivide_d = 0; +} + +/** + QuadMesh +*/ + +void QuadMesh::_create_mesh_array(Array &p_arr) { + PoolVector<Vector3> faces; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + + faces.resize(4); + normals.resize(4); + tangents.resize(4 * 4); + uvs.resize(4); + + for (int i = 0; i < 4; i++) { + + static const Vector3 quad_faces[4] = { + Vector3(-1, -1, 0), + Vector3(-1, 1, 0), + Vector3(1, 1, 0), + Vector3(1, -1, 0), + }; + + faces.set(i, quad_faces[i]); + normals.set(i, Vector3(0, 0, 1)); + tangents.set(i * 4 + 0, 1.0); + tangents.set(i * 4 + 1, 0.0); + tangents.set(i * 4 + 2, 0.0); + tangents.set(i * 4 + 3, 1.0); + + static const Vector2 quad_uv[4] = { + Vector2(0, 1), + Vector2(0, 0), + Vector2(1, 0), + Vector2(1, 1), + }; + + uvs.set(i, quad_uv[i]); + } + + p_arr[ARRAY_VERTEX] = faces; + p_arr[ARRAY_NORMAL] = normals; + p_arr[ARRAY_TANGENT] = tangents; + p_arr[ARRAY_TEX_UV] = uvs; +}; + +void QuadMesh::_bind_methods() { + // nothing here yet... +} + +QuadMesh::QuadMesh() { + primitive_type = PRIMITIVE_TRIANGLE_FAN; +} + +/** + SphereMesh +*/ + +void SphereMesh::_create_mesh_array(Array &p_arr) { + int i, j, prevrow, thisrow, point; + float x, y, z; + + // set our bounding box + set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); + + PoolVector<Vector3> points; + PoolVector<Vector3> normals; + PoolVector<float> tangents; + PoolVector<Vector2> uvs; + PoolVector<int> indices; + point = 0; + +#define ADD_TANGENT(m_x, m_y, m_z, m_d) \ + tangents.push_back(m_x); \ + tangents.push_back(m_y); \ + tangents.push_back(m_z); \ + tangents.push_back(m_d); + + thisrow = 0; + prevrow = 0; + for (j = 0; j <= (rings + 1); j++) { + float v = j; + float w; + + v /= (rings + 1); + w = sin(Math_PI * v); + y = height * (is_hemisphere ? 1.0 : 0.5) * cos(Math_PI * v); + + for (i = 0; i <= radial_segments; i++) { + float u = i; + u /= radial_segments; + + x = sin(u * (Math_PI * 2.0)); + z = cos(u * (Math_PI * 2.0)); + + if (is_hemisphere && y < 0.0) { + points.push_back(Vector3(x * radius * w, 0.0, z * radius * w)); + normals.push_back(Vector3(0.0, -1.0, 0.0)); + } else { + Vector3 p = Vector3(x * radius * w, y, z * radius * w); + points.push_back(p); + normals.push_back(p.normalized()); + }; + ADD_TANGENT(-z, 0.0, x, -1.0) + uvs.push_back(Vector2(u, v)); + point++; + + if (i > 0 && j > 0) { + indices.push_back(prevrow + i - 1); + indices.push_back(prevrow + i); + indices.push_back(thisrow + i - 1); + + indices.push_back(prevrow + i); + indices.push_back(thisrow + i); + indices.push_back(thisrow + i - 1); + }; + }; + + prevrow = thisrow; + thisrow = point; + }; + + p_arr[VS::ARRAY_VERTEX] = points; + p_arr[VS::ARRAY_NORMAL] = normals; + p_arr[VS::ARRAY_TANGENT] = tangents; + p_arr[VS::ARRAY_TEX_UV] = uvs; + p_arr[VS::ARRAY_INDEX] = indices; +} + +void SphereMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereMesh::set_radius); + ClassDB::bind_method(D_METHOD("get_radius"), &SphereMesh::get_radius); + ClassDB::bind_method(D_METHOD("set_height", "height"), &SphereMesh::set_height); + ClassDB::bind_method(D_METHOD("get_height"), &SphereMesh::get_height); + + ClassDB::bind_method(D_METHOD("set_radial_segments", "radial_segments"), &SphereMesh::set_radial_segments); + ClassDB::bind_method(D_METHOD("get_radial_segments"), &SphereMesh::get_radial_segments); + ClassDB::bind_method(D_METHOD("set_rings", "rings"), &SphereMesh::set_rings); + ClassDB::bind_method(D_METHOD("get_rings"), &SphereMesh::get_rings); + + ClassDB::bind_method(D_METHOD("set_is_hemisphere", "is_hemisphere"), &SphereMesh::set_is_hemisphere); + ClassDB::bind_method(D_METHOD("get_is_hemisphere"), &SphereMesh::get_is_hemisphere); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_hemisphere"), "set_is_hemisphere", "get_is_hemisphere"); +} + +void SphereMesh::set_radius(const float p_radius) { + radius = p_radius; + _queue_update(); +} + +float SphereMesh::get_radius() const { + return radius; +} + +void SphereMesh::set_height(const float p_height) { + height = p_height; + _queue_update(); +} + +float SphereMesh::get_height() const { + return height; +} + +void SphereMesh::set_radial_segments(const int p_radial_segments) { + radial_segments = p_radial_segments > 4 ? p_radial_segments : 4; + _queue_update(); +} + +int SphereMesh::get_radial_segments() const { + return radial_segments; +} + +void SphereMesh::set_rings(const int p_rings) { + rings = p_rings > 1 ? p_rings : 1; + _queue_update(); +} + +int SphereMesh::get_rings() const { + return rings; +} + +void SphereMesh::set_is_hemisphere(const bool p_is_hemisphere) { + is_hemisphere = p_is_hemisphere; + _queue_update(); +} + +bool SphereMesh::get_is_hemisphere() const { + return is_hemisphere; +} + +SphereMesh::SphereMesh() { + // defaults + radius = 0.5; + height = 1.0; + radial_segments = 64; + rings = 32; + is_hemisphere = false; +} diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h new file mode 100644 index 0000000000..91d1af2ee1 --- /dev/null +++ b/scene/resources/primitive_meshes.h @@ -0,0 +1,312 @@ +/*************************************************************************/ +/* primitive_meshes.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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. */ +/*************************************************************************/ + +#ifndef PRIMITIVE_MESHES_H +#define PRIMITIVE_MESHES_H + +#include "scene/resources/mesh.h" + +///@TODO probably should change a few integers to unsigned integers... + +/** + @author Bastiaan Olij <mux213@gmail.com> + + Base class for all the classes in this file, handles a number of code functions that are shared among all meshes. + This class is set appart that it assumes a single surface is always generated for our mesh. +*/ +class PrimitiveMesh : public Mesh { + + GDCLASS(PrimitiveMesh, Mesh); + +private: + RID mesh; + Rect3 aabb; + + Ref<Material> material; + + bool cache_is_dirty; + void _update(); + +protected: + Mesh::PrimitiveType primitive_type; + + static void _bind_methods(); + + virtual void _create_mesh_array(Array &p_arr) = 0; + void _queue_update(); + + void set_aabb(Rect3 p_aabb); + +public: + virtual int get_surface_count() const; + virtual int surface_get_array_len(int p_idx) const; + virtual int surface_get_array_index_len(int p_idx) const; + virtual Array surface_get_arrays(int p_surface) const; + virtual uint32_t surface_get_format(int p_idx) const; + virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const; + virtual Ref<Material> surface_get_material(int p_idx) const; + virtual int get_blend_shape_count() const; + virtual StringName get_blend_shape_name(int p_index) const; + virtual Rect3 get_aabb() const; + virtual RID get_rid() const; + + void set_material(const Ref<Material> &p_material); + Ref<Material> get_material() const; + + PrimitiveMesh(); + ~PrimitiveMesh(); +}; + +/** + Mesh for a simple capsule +*/ +class CapsuleMesh : public PrimitiveMesh { + GDCLASS(CapsuleMesh, PrimitiveMesh); + +private: + float radius; + float mid_height; + int radial_segments; + int rings; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_radius(const float p_radius); + float get_radius() const; + + void set_mid_height(const float p_mid_height); + float get_mid_height() const; + + void set_radial_segments(const int p_segments); + int get_radial_segments() const; + + void set_rings(const int p_rings); + int get_rings() const; + + CapsuleMesh(); +}; + +/** + Similar to test cube but with subdivision support and different texture coordinates +*/ +class CubeMesh : public PrimitiveMesh { + + GDCLASS(CubeMesh, PrimitiveMesh); + +private: + Vector3 size; + int subdivide_w; + int subdivide_h; + int subdivide_d; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_size(const Vector3 &p_size); + Vector3 get_size() const; + + void set_subdivide_width(const int p_divisions); + int get_subdivide_width() const; + + void set_subdivide_height(const int p_divisions); + int get_subdivide_height() const; + + void set_subdivide_depth(const int p_divisions); + int get_subdivide_depth() const; + + CubeMesh(); +}; + +/** + A cylinder +*/ + +class CylinderMesh : public PrimitiveMesh { + + GDCLASS(CylinderMesh, PrimitiveMesh); + +private: + float top_radius; + float bottom_radius; + float height; + int radial_segments; + int rings; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_top_radius(const float p_radius); + float get_top_radius() const; + + void set_bottom_radius(const float p_radius); + float get_bottom_radius() const; + + void set_height(const float p_height); + float get_height() const; + + void set_radial_segments(const int p_segments); + int get_radial_segments() const; + + void set_rings(const int p_rings); + int get_rings() const; + + CylinderMesh(); +}; + +/** + Similar to quadmesh but with tesselation support +*/ +class PlaneMesh : public PrimitiveMesh { + + GDCLASS(PlaneMesh, PrimitiveMesh); + +private: + Size2 size; + int subdivide_w; + int subdivide_d; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_size(const Size2 &p_size); + Size2 get_size() const; + + void set_subdivide_width(const int p_divisions); + int get_subdivide_width() const; + + void set_subdivide_depth(const int p_divisions); + int get_subdivide_depth() const; + + PlaneMesh(); +}; + +/** + A prism shapen, handy for ramps, triangles, etc. +*/ +class PrismMesh : public PrimitiveMesh { + + GDCLASS(PrismMesh, PrimitiveMesh); + +private: + float left_to_right; + Vector3 size; + int subdivide_w; + int subdivide_h; + int subdivide_d; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_left_to_right(const float p_left_to_right); + float get_left_to_right() const; + + void set_size(const Vector3 &p_size); + Vector3 get_size() const; + + void set_subdivide_width(const int p_divisions); + int get_subdivide_width() const; + + void set_subdivide_height(const int p_divisions); + int get_subdivide_height() const; + + void set_subdivide_depth(const int p_divisions); + int get_subdivide_depth() const; + + PrismMesh(); +}; + +/** + Our original quadmesh... +*/ + +class QuadMesh : public PrimitiveMesh { + + GDCLASS(QuadMesh, PrimitiveMesh) + +private: + // nothing? really? Maybe add size some day atleast... :) + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + QuadMesh(); +}; + +/** + A sphere.. +*/ +class SphereMesh : public PrimitiveMesh { + + GDCLASS(SphereMesh, PrimitiveMesh); + +private: + float radius; + float height; + int radial_segments; + int rings; + bool is_hemisphere; + +protected: + static void _bind_methods(); + virtual void _create_mesh_array(Array &p_arr); + +public: + void set_radius(const float p_radius); + float get_radius() const; + + void set_height(const float p_height); + float get_height() const; + + void set_radial_segments(const int p_radial_segments); + int get_radial_segments() const; + + void set_rings(const int p_rings); + int get_rings() const; + + void set_is_hemisphere(const bool p_is_hemisphere); + bool get_is_hemisphere() const; + + SphereMesh(); +}; + +#endif diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index b9ec294eb8..36578ce1f7 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -37,7 +37,7 @@ class ShaderGraph : public Shader { GDCLASS( ShaderGraph, Shader ); - RES_BASE_EXTENSION("sgp"); + RES_BASE_EXTENSION("vshader"); public: diff --git a/scene/resources/shape.h b/scene/resources/shape.h index ea3ba9ab0a..c15638aeed 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -37,7 +37,7 @@ class Shape : public Resource { GDCLASS(Shape, Resource); OBJ_SAVE_TYPE(Shape); - RES_BASE_EXTENSION("shp"); + RES_BASE_EXTENSION("shape"); RID shape; Ref<ArrayMesh> debug_mesh_cache; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 8874cbc102..2714ffec10 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -114,6 +114,19 @@ RES StyleBoxTexture::get_texture() const { return texture; } +void StyleBoxTexture::set_normal_map(RES p_normal_map) { + + if (normal_map == p_normal_map) + return; + normal_map = p_normal_map; + emit_changed(); +} + +RES StyleBoxTexture::get_normal_map() const { + + return normal_map; +} + void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) { margin[p_margin] = p_size; @@ -143,7 +156,11 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const { rect.size.x += expand_margin[MARGIN_LEFT] + expand_margin[MARGIN_RIGHT]; rect.size.y += expand_margin[MARGIN_TOP] + expand_margin[MARGIN_BOTTOM]; - VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate); + RID normal_rid; + if (normal_map.is_valid()) + normal_rid = normal_map->get_rid(); + + VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate, normal_rid); } void StyleBoxTexture::set_draw_center(bool p_draw) { @@ -209,6 +226,9 @@ void StyleBoxTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &StyleBoxTexture::set_texture); ClassDB::bind_method(D_METHOD("get_texture:Texture"), &StyleBoxTexture::get_texture); + ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map:Texture"), &StyleBoxTexture::set_normal_map); + ClassDB::bind_method(D_METHOD("get_normal_map:Texture"), &StyleBoxTexture::get_normal_map); + ClassDB::bind_method(D_METHOD("set_margin_size", "margin", "size"), &StyleBoxTexture::set_margin_size); ClassDB::bind_method(D_METHOD("get_margin_size", "margin"), &StyleBoxTexture::get_margin_size); @@ -227,6 +247,7 @@ void StyleBoxTexture::_bind_methods() { ADD_SIGNAL(MethodInfo("texture_changed")); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map"); ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_GROUP("Margin", "margin_"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT); diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index bbb2444bd7..7547c2ea81 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -39,7 +39,7 @@ class StyleBox : public Resource { GDCLASS(StyleBox, Resource); - RES_BASE_EXTENSION("sbx"); + RES_BASE_EXTENSION("stylebox"); OBJ_SAVE_TYPE(StyleBox); float margin[4]; @@ -81,6 +81,7 @@ class StyleBoxTexture : public StyleBox { float margin[4]; Rect2 region_rect; Ref<Texture> texture; + Ref<Texture> normal_map; bool draw_center; Color modulate; @@ -101,6 +102,9 @@ public: void set_texture(RES p_texture); RES get_texture() const; + void set_normal_map(RES p_normal_map); + RES get_normal_map() const; + void set_draw_center(bool p_draw); bool get_draw_center() const; virtual Size2 get_center_size() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 0b8ad5536c..2120b37497 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -28,25 +28,28 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "texture.h" +#include "core/method_bind_ext.inc" #include "core/os/os.h" #include "io/image_loader.h" - Size2 Texture::get_size() const { return Size2(get_width(), get_height()); } -void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid); } -void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid); } -void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const { +void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -65,9 +68,9 @@ void Texture::_bind_methods() { ClassDB::bind_method(D_METHOD("has_alpha"), &Texture::has_alpha); ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags); - ClassDB::bind_method(D_METHOD("draw", "canvas_item", "pos", "modulate", "transpose"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("draw", "canvas_item", "pos", "modulate", "transpose", "normal_map:Texture"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true)); BIND_CONSTANT(FLAG_MIPMAPS); BIND_CONSTANT(FLAG_REPEAT); @@ -265,23 +268,26 @@ bool ImageTexture::has_alpha() const { return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8); } -void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid); } -void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); } -void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const { +void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } void ImageTexture::set_size_override(const Size2 &p_size) { @@ -390,8 +396,17 @@ void StreamTexture::_requested_srgb(void *p_ud) { request_srgb_callback(stex); } +void StreamTexture::_requested_normal(void *p_ud) { + + StreamTexture *st = (StreamTexture *)p_ud; + Ref<StreamTexture> stex(st); + ERR_FAIL_COND(!request_normal_callback); + request_normal_callback(stex); +} + StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL; StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL; +StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL; uint32_t StreamTexture::get_flags() const { @@ -421,12 +436,13 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format - /* +/* print_line("width: " + itos(tw)); print_line("height: " + itos(th)); print_line("flags: " + itos(flags)); print_line("df: " + itos(df)); */ +#ifdef TOOLS_ENABLED if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) { //print_line("request detect 3D at " + p_path); @@ -444,6 +460,14 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL); } + if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) { + //print_line("request detect srgb at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this); + } else { + //print_line("not requesting detect normal at " + p_path); + VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL); + } +#endif if (!(df & FORMAT_BIT_STREAM)) { p_size_limit = 0; } @@ -647,23 +671,26 @@ RID StreamTexture::get_rid() const { return texture; } -void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid); } -void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid); } -void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const { +void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { if ((w | h) == 0) return; - VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool StreamTexture::has_alpha() const { @@ -845,7 +872,7 @@ void AtlasTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin"); } -void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { Rect2 rc = region; @@ -860,10 +887,11 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m rc.size.height = atlas->get_height(); } - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid); } -void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { Rect2 rc = region; @@ -881,9 +909,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Vector2 scale = p_rect.size / (region.size + margin.size); Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid); } -void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const { +void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { //this might not necessarily work well if using a rect, needs to be fixed properly Rect2 rc = region; @@ -911,7 +940,8 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons } Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose); + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, p_clip_uv); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -1076,16 +1106,16 @@ void LargeTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data"); } -void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { for (int i = 0; i < pieces.size(); i++) { // TODO - pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose); + pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map); } } -void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { //tiling not supported for this if (size.x == 0 || size.y == 0) @@ -1093,13 +1123,14 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Size2 scale = p_rect.size / size; + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); for (int i = 0; i < pieces.size(); i++) { // TODO - pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose); + pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map); } } -void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const { +void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { //tiling not supported for this if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0) @@ -1107,6 +1138,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Size2 scale = p_rect.size / p_src_rect.size; + RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); for (int i = 0; i < pieces.size(); i++) { // TODO @@ -1118,7 +1150,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons target.size *= scale; target.position = p_rect.position + (p_src_rect.position + rect.position) * scale; local.position -= rect.position; - pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose); + pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false); } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 9ee9588d2b..2b82dbd21f 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -68,9 +68,9 @@ public: virtual void set_flags(uint32_t p_flags) = 0; virtual uint32_t get_flags() const = 0; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; virtual Ref<Image> get_data() const { return Ref<Image>(); } @@ -131,9 +131,9 @@ public: virtual RID get_rid() const; bool has_alpha() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; void set_storage(Storage p_storage); Storage get_storage() const; @@ -167,6 +167,7 @@ public: FORMAT_BIT_HAS_MIPMAPS = 1 << 23, FORMAT_BIT_DETECT_3D = 1 << 24, FORMAT_BIT_DETECT_SRGB = 1 << 25, + FORMAT_BIT_DETECT_NORMAL = 1 << 26, }; private: @@ -181,6 +182,7 @@ private: static void _requested_3d(void *p_ud); static void _requested_srgb(void *p_ud); + static void _requested_normal(void *p_ud); protected: static void _bind_methods(); @@ -190,6 +192,7 @@ public: static TextureFormatRequestCallback request_3d_callback; static TextureFormatRequestCallback request_srgb_callback; + static TextureFormatRequestCallback request_normal_callback; uint32_t get_flags() const; Image::Format get_format() const; @@ -200,9 +203,9 @@ public: int get_height() const; virtual RID get_rid() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; virtual bool has_alpha() const; virtual void set_flags(uint32_t p_flags); @@ -226,7 +229,7 @@ VARIANT_ENUM_CAST(ImageTexture::Storage); class AtlasTexture : public Texture { GDCLASS(AtlasTexture, Texture); - RES_BASE_EXTENSION("atex"); + RES_BASE_EXTENSION("atlastex"); protected: Ref<Texture> atlas; @@ -254,9 +257,9 @@ public: void set_margin(const Rect2 &p_margin); Rect2 get_margin() const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const; AtlasTexture(); @@ -265,7 +268,7 @@ public: class LargeTexture : public Texture { GDCLASS(LargeTexture, Texture); - RES_BASE_EXTENSION("ltex"); + RES_BASE_EXTENSION("largetex"); protected: struct Piece { @@ -302,9 +305,9 @@ public: Vector2 get_piece_offset(int p_idx) const; Ref<Texture> get_piece_texture(int p_idx) const; - virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; - virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; + virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; LargeTexture(); }; @@ -312,7 +315,7 @@ public: class CubeMap : public Resource { GDCLASS(CubeMap, Resource); - RES_BASE_EXTENSION("cbm"); + RES_BASE_EXTENSION("cubemap"); public: enum Storage { @@ -393,7 +396,7 @@ VARIANT_ENUM_CAST(CubeMap::Storage); class CurveTexture : public Texture { GDCLASS(CurveTexture, Texture); - RES_BASE_EXTENSION("cvtex"); + RES_BASE_EXTENSION("curvetex"); private: RID texture; diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 1a5cfcf4b2..1dfea7f421 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -43,7 +43,7 @@ class Theme : public Resource { GDCLASS(Theme, Resource); - RES_BASE_EXTENSION("thm"); + RES_BASE_EXTENSION("theme"); static Ref<Theme> default_theme; diff --git a/scene/resources/world.h b/scene/resources/world.h index 96857a577a..5291b3974b 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -41,7 +41,7 @@ class VisibilityNotifier; class World : public Resource { GDCLASS(World, Resource); - RES_BASE_EXTENSION("wrd"); + RES_BASE_EXTENSION("world"); private: RID space; diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index ec9ec96e50..36d2a38b3d 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -360,16 +360,17 @@ RID World2D::get_space() { return space; } -RID World2D::get_sound_space() { +void World2D::get_viewport_list(List<Viewport *> *r_viewports) { - return sound_space; + for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) { + r_viewports->push_back(E->key()); + } } void World2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas); ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space); - ClassDB::bind_method(D_METHOD("get_sound_space"), &World2D::get_sound_space); ClassDB::bind_method(D_METHOD("get_direct_space_state:Physics2DDirectSpaceState"), &World2D::get_direct_space_state); } diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 2b6e7e7383..35c8ce390f 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -44,7 +44,6 @@ class World2D : public Resource { RID canvas; RID space; - RID sound_space; SpatialIndexer2D *indexer; @@ -66,10 +65,11 @@ protected: public: RID get_canvas(); RID get_space(); - RID get_sound_space(); Physics2DDirectSpaceState *get_direct_space_state(); + void get_viewport_list(List<Viewport *> *r_viewports); + World2D(); ~World2D(); }; |