1 | /**************************************************************************/ |
2 | /* camera_server.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "camera_server.h" |
32 | #include "core/variant/typed_array.h" |
33 | #include "rendering_server.h" |
34 | #include "servers/camera/camera_feed.h" |
35 | |
36 | //////////////////////////////////////////////////////// |
37 | // CameraServer |
38 | |
39 | CameraServer::CreateFunc CameraServer::create_func = nullptr; |
40 | |
41 | void CameraServer::_bind_methods() { |
42 | ClassDB::bind_method(D_METHOD("get_feed" , "index" ), &CameraServer::get_feed); |
43 | ClassDB::bind_method(D_METHOD("get_feed_count" ), &CameraServer::get_feed_count); |
44 | ClassDB::bind_method(D_METHOD("feeds" ), &CameraServer::get_feeds); |
45 | |
46 | ClassDB::bind_method(D_METHOD("add_feed" , "feed" ), &CameraServer::add_feed); |
47 | ClassDB::bind_method(D_METHOD("remove_feed" , "feed" ), &CameraServer::remove_feed); |
48 | |
49 | ADD_SIGNAL(MethodInfo("camera_feed_added" , PropertyInfo(Variant::INT, "id" ))); |
50 | ADD_SIGNAL(MethodInfo("camera_feed_removed" , PropertyInfo(Variant::INT, "id" ))); |
51 | |
52 | BIND_ENUM_CONSTANT(FEED_RGBA_IMAGE); |
53 | BIND_ENUM_CONSTANT(FEED_YCBCR_IMAGE); |
54 | BIND_ENUM_CONSTANT(FEED_Y_IMAGE); |
55 | BIND_ENUM_CONSTANT(FEED_CBCR_IMAGE); |
56 | }; |
57 | |
58 | CameraServer *CameraServer::singleton = nullptr; |
59 | |
60 | CameraServer *CameraServer::get_singleton() { |
61 | return singleton; |
62 | }; |
63 | |
64 | int CameraServer::get_free_id() { |
65 | bool id_exists = true; |
66 | int newid = 0; |
67 | |
68 | // find a free id |
69 | while (id_exists) { |
70 | newid++; |
71 | id_exists = false; |
72 | for (int i = 0; i < feeds.size() && !id_exists; i++) { |
73 | if (feeds[i]->get_id() == newid) { |
74 | id_exists = true; |
75 | }; |
76 | }; |
77 | }; |
78 | |
79 | return newid; |
80 | }; |
81 | |
82 | int CameraServer::get_feed_index(int p_id) { |
83 | for (int i = 0; i < feeds.size(); i++) { |
84 | if (feeds[i]->get_id() == p_id) { |
85 | return i; |
86 | }; |
87 | }; |
88 | |
89 | return -1; |
90 | }; |
91 | |
92 | Ref<CameraFeed> CameraServer::get_feed_by_id(int p_id) { |
93 | int index = get_feed_index(p_id); |
94 | |
95 | if (index == -1) { |
96 | return nullptr; |
97 | } else { |
98 | return feeds[index]; |
99 | } |
100 | }; |
101 | |
102 | void CameraServer::add_feed(const Ref<CameraFeed> &p_feed) { |
103 | ERR_FAIL_COND(p_feed.is_null()); |
104 | |
105 | // add our feed |
106 | feeds.push_back(p_feed); |
107 | |
108 | print_verbose("CameraServer: Registered camera " + p_feed->get_name() + " with ID " + itos(p_feed->get_id()) + " and position " + itos(p_feed->get_position()) + " at index " + itos(feeds.size() - 1)); |
109 | |
110 | // let whomever is interested know |
111 | emit_signal(SNAME("camera_feed_added" ), p_feed->get_id()); |
112 | }; |
113 | |
114 | void CameraServer::remove_feed(const Ref<CameraFeed> &p_feed) { |
115 | for (int i = 0; i < feeds.size(); i++) { |
116 | if (feeds[i] == p_feed) { |
117 | int feed_id = p_feed->get_id(); |
118 | |
119 | print_verbose("CameraServer: Removed camera " + p_feed->get_name() + " with ID " + itos(feed_id) + " and position " + itos(p_feed->get_position())); |
120 | |
121 | // remove it from our array, if this results in our feed being unreferenced it will be destroyed |
122 | feeds.remove_at(i); |
123 | |
124 | // let whomever is interested know |
125 | emit_signal(SNAME("camera_feed_removed" ), feed_id); |
126 | return; |
127 | }; |
128 | }; |
129 | }; |
130 | |
131 | Ref<CameraFeed> CameraServer::get_feed(int p_index) { |
132 | ERR_FAIL_INDEX_V(p_index, feeds.size(), nullptr); |
133 | |
134 | return feeds[p_index]; |
135 | }; |
136 | |
137 | int CameraServer::get_feed_count() { |
138 | return feeds.size(); |
139 | }; |
140 | |
141 | TypedArray<CameraFeed> CameraServer::get_feeds() { |
142 | TypedArray<CameraFeed> return_feeds; |
143 | int cc = get_feed_count(); |
144 | return_feeds.resize(cc); |
145 | |
146 | for (int i = 0; i < feeds.size(); i++) { |
147 | return_feeds[i] = get_feed(i); |
148 | }; |
149 | |
150 | return return_feeds; |
151 | }; |
152 | |
153 | RID CameraServer::feed_texture(int p_id, CameraServer::FeedImage p_texture) { |
154 | int index = get_feed_index(p_id); |
155 | ERR_FAIL_COND_V(index == -1, RID()); |
156 | |
157 | Ref<CameraFeed> feed = get_feed(index); |
158 | |
159 | return feed->get_texture(p_texture); |
160 | }; |
161 | |
162 | CameraServer::CameraServer() { |
163 | singleton = this; |
164 | }; |
165 | |
166 | CameraServer::~CameraServer() { |
167 | singleton = nullptr; |
168 | }; |
169 | |