#include "clue_finder.h" #include "core/config/engine.h" #include "core/math/math_defs.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/xr/xr_nodes.h" #include "scene/main/node.h" #include "scene/resources/material.h" #include "scene/resources/texture.h" #include "you_done_it/clue_db.h" ClueFinder *ClueFinder::singleton_instance{ nullptr }; String const ClueFinder::sig_found_marker_changed{ "found_marker_changed" }; void ClueFinder::_bind_methods() { ClassDB::bind_method(D_METHOD("take_photo"), &ClueFinder::take_photo); ADD_SIGNAL(MethodInfo(sig_found_marker_changed, PropertyInfo(Variant::BOOL, "has_marker"))); BIND_HPROPERTY(Variant::OBJECT, empty_texture, PROPERTY_HINT_RESOURCE_TYPE, "Texture"); BIND_HPROPERTY(Variant::OBJECT, photo_material, PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D"); } void ClueFinder::enter_tree() { if (singleton_instance == nullptr) { singleton_instance = this; } else { queue_free(); } if (XRController3D * controller{ cast_to(get_parent()) }) { controller->connect("button_pressed", callable_mp(this, &self_type::on_button_pressed)); } } void ClueFinder::exit_tree() { if (singleton_instance == this) { singleton_instance = nullptr; } } void ClueFinder::on_button_pressed(String button) { if (button == "trigger_click") { take_photo(); } if (button == "ax_button") { send_photo(); } if (button == "by_button") { delete_photo(); } } void ClueFinder::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { case NOTIFICATION_ENTER_TREE: enter_tree(); return; case NOTIFICATION_EXIT_TREE: exit_tree(); return; default: return; } } ClueFinder *ClueFinder::get_singleton() { return singleton_instance; } ClueMarker *ClueFinder::find_current_clue() { float best_score{ Math::INF }; ClueMarker *best_marker{ nullptr }; for (ClueMarker *marker : this->clue_markers) { float score{ marker->score_in_view() }; if (!Math::is_nan(score) && score < best_score) { best_marker = marker; best_score = score; } } return best_marker; } void ClueFinder::register_clue_marker(ClueMarker *marker) { this->clue_markers.insert(marker); } void ClueFinder::remove_clue_marker(ClueMarker *marker) { this->clue_markers.erase(marker); } void ClueFinder::take_photo() { this->found_marker = find_current_clue(); if (this->found_marker) { Ref clue{ ClueDB::get_singleton()->get_clue(this->found_marker->get_clue_id()) }; print_line("Found clue: ", this->found_marker->get_clue_id(), " ", clue, " ", clue->get_image()); photo_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, clue->get_image()); } else { photo_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, this->empty_texture); } emit_signal(sig_found_marker_changed, bool(this->found_marker)); } void ClueFinder::send_photo() { if (this->found_marker) { this->found_marker->reveal(); this->found_marker = nullptr; emit_signal(sig_found_marker_changed, false); photo_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, this->empty_texture); } } void ClueFinder::delete_photo() { if (this->found_marker) { this->found_marker = nullptr; emit_signal(sig_found_marker_changed, false); photo_material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, this->empty_texture); } } void ClueFinder::set_empty_texture(Ref texture) { this->empty_texture = texture; } Ref ClueFinder::get_empty_texture() const { return this->empty_texture; } void ClueFinder::set_photo_material(Ref material) { this->photo_material = material; } Ref ClueFinder::get_photo_material() const { return this->photo_material; }