comparison Samples/WebAssembly/BasicScene.cpp @ 826:2de01660debe

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 29 May 2019 16:48:56 +0200
parents 270c31978df1
children 0aff28f15ea2 6073c980323a
comparison
equal deleted inserted replaced
825:9a6c7a5dcb76 826:2de01660debe
17 * You should have received a copy of the GNU Affero General Public License 17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/ 19 **/
20 20
21 21
22 #include "dev.h"
22 23
23 #include <emscripten.h> 24 #include <emscripten.h>
24 #include <emscripten/html5.h> 25 #include <emscripten/html5.h>
25 26
26 // From Stone 27 // From Stone
27 #include "../../Applications/Sdl/SdlOpenGLWindow.h"
28 #include "../../Framework/Scene2D/CairoCompositor.h"
29 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h" 28 #include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
30 #include "../../Framework/Scene2D/OpenGLCompositor.h"
31 #include "../../Framework/Scene2D/PanSceneTracker.h"
32 #include "../../Framework/Scene2D/RotateSceneTracker.h"
33 #include "../../Framework/Scene2D/Scene2D.h"
34 #include "../../Framework/Scene2D/ZoomSceneTracker.h"
35 #include "../../Framework/Scene2DViewport/ViewportController.h"
36 #include "../../Framework/StoneInitialization.h" 29 #include "../../Framework/StoneInitialization.h"
37 #include "../../Framework/OpenGL/WebAssemblyOpenGLContext.h"
38 30
39 // From Orthanc framework 31 // From Orthanc framework
40 #include <Core/Images/Image.h> 32 #include <Core/Images/Image.h>
41 #include <Core/Logging.h> 33 #include <Core/Logging.h>
42 #include <Core/OrthancException.h> 34 #include <Core/OrthancException.h>
43 35
44 #include <boost/make_shared.hpp> 36 void PrepareScene(OrthancStone::Scene2D& scene)
45
46 #include <stdio.h>
47
48 static const unsigned int FONT_SIZE = 32;
49
50 using boost::shared_ptr;
51 using boost::make_shared;
52
53 void PrepareScene(OrthancStone::Scene2DPtr scene)
54 { 37 {
55 using namespace OrthancStone; 38 using namespace OrthancStone;
56 39
57 // Texture of 2x2 size 40 // Texture of 2x2 size
58 if (1) 41 if (1)
75 58
76 p[3] = 255; 59 p[3] = 255;
77 p[4] = 0; 60 p[4] = 0;
78 p[5] = 0; 61 p[5] = 0;
79 62
80 scene->SetLayer(12, new ColorTextureSceneLayer(i)); 63 scene.SetLayer(12, new ColorTextureSceneLayer(i));
81 64
82 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); 65 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
83 l->SetOrigin(-3, 2); 66 l->SetOrigin(-3, 2);
84 l->SetPixelSpacing(1.5, 1); 67 l->SetPixelSpacing(1.5, 1);
85 l->SetAngle(20.0 / 180.0 * M_PI); 68 l->SetAngle(20.0 / 180.0 * M_PI);
86 scene->SetLayer(14, l.release()); 69 scene.SetLayer(14, l.release());
87 } 70 }
88 71
89 // Texture of 1x1 size 72 // Texture of 1x1 size
90 if (1) 73 if (1)
91 { 74 {
97 p[2] = 0; 80 p[2] = 0;
98 81
99 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i)); 82 std::auto_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
100 l->SetOrigin(-2, 1); 83 l->SetOrigin(-2, 1);
101 l->SetAngle(20.0 / 180.0 * M_PI); 84 l->SetAngle(20.0 / 180.0 * M_PI);
102 scene->SetLayer(13, l.release()); 85 scene.SetLayer(13, l.release());
103 } 86 }
104 87
105 // Some lines 88 // Some lines
106 { 89 {
107 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer); 90 std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
128 chain.push_back(ScenePoint2D(4, -4 + dy)); 111 chain.push_back(ScenePoint2D(4, -4 + dy));
129 chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy)); 112 chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
130 chain.push_back(ScenePoint2D(4, 2)); 113 chain.push_back(ScenePoint2D(4, 2));
131 layer->AddChain(chain, false, 0, 0, 255); 114 layer->AddChain(chain, false, 0, 0, 255);
132 115
133 scene->SetLayer(50, layer.release()); 116 scene.SetLayer(50, layer.release());
134 } 117 }
135 118
136 // Some text 119 // Some text
137 if (1) 120 if (1)
138 { 121 {
139 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer); 122 std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer);
140 layer->SetText("Hello"); 123 layer->SetText("Hello");
141 scene->SetLayer(100, layer.release()); 124 scene.SetLayer(100, layer.release());
142 } 125 }
143 } 126 }
144 127
145 namespace OrthancStone
146 {
147 class WebAssemblyViewport : public boost::noncopyable
148 {
149 private:
150 // the construction order is important because compositor_
151 // will hold a reference to the scene that belong to the
152 // controller_ object
153 OpenGL::WebAssemblyOpenGLContext context_;
154 ViewportControllerPtr controller_;
155 OpenGLCompositor compositor_;
156
157 void SetupEvents(const std::string& canvas);
158
159 public:
160 WebAssemblyViewport(MessageBroker& broker, const std::string& canvas) :
161 context_(canvas),
162 controller_(make_shared<ViewportController>(broker)),
163 compositor_(context_, *controller_->GetScene())
164 {
165 compositor_.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
166 FONT_SIZE, Orthanc::Encoding_Latin1);
167 SetupEvents(canvas);
168 }
169
170 Scene2DPtr GetScene()
171 {
172 return controller_->GetScene();
173 }
174
175 ViewportControllerPtr GetController()
176 {
177 return controller_;
178 }
179
180 void UpdateSize()
181 {
182 context_.UpdateSize();
183 compositor_.UpdateSize();
184 Refresh();
185 }
186
187 void Refresh()
188 {
189 compositor_.Refresh();
190 }
191
192 const std::string& GetCanvasIdentifier() const
193 {
194 return context_.GetCanvasIdentifier();
195 }
196
197 ScenePoint2D GetPixelCenterCoordinates(int x, int y) const
198 {
199 return compositor_.GetPixelCenterCoordinates(x, y);
200 }
201
202 unsigned int GetCanvasWidth() const
203 {
204 return context_.GetCanvasWidth();
205 }
206
207 unsigned int GetCanvasHeight() const
208 {
209 return context_.GetCanvasHeight();
210 }
211 };
212
213 class ActiveTracker : public boost::noncopyable
214 {
215 private:
216 OrthancStone::FlexiblePointerTrackerPtr tracker_;
217 std::string canvasIdentifier_;
218 bool insideCanvas_;
219
220 public:
221 ActiveTracker(FlexiblePointerTrackerPtr tracker,
222 const WebAssemblyViewport& viewport) :
223 tracker_(tracker),
224 canvasIdentifier_(viewport.GetCanvasIdentifier()),
225 insideCanvas_(true)
226 {
227 if (tracker_.get() == NULL)
228 {
229 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
230 }
231 }
232
233 bool IsAlive() const
234 {
235 return tracker_->IsAlive();
236 }
237
238 void PointerMove(const PointerEvent& event)
239 {
240 tracker_->PointerMove(event);
241 }
242
243 void PointerUp(const PointerEvent& event)
244 {
245 tracker_->PointerUp(event);
246 }
247 };
248 }
249
250 static OrthancStone::PointerEvent* ConvertMouseEvent(
251 const EmscriptenMouseEvent& source,
252 OrthancStone::WebAssemblyViewport& viewport)
253 {
254 std::auto_ptr<OrthancStone::PointerEvent> target(
255 new OrthancStone::PointerEvent);
256
257 target->AddPosition(viewport.GetPixelCenterCoordinates(
258 source.targetX, source.targetY));
259 target->SetAltModifier(source.altKey);
260 target->SetControlModifier(source.ctrlKey);
261 target->SetShiftModifier(source.shiftKey);
262
263 return target.release();
264 }
265
266 std::auto_ptr<OrthancStone::ActiveTracker> tracker_;
267
268 EM_BOOL OnMouseEvent(int eventType,
269 const EmscriptenMouseEvent *mouseEvent,
270 void *userData)
271 {
272 if (mouseEvent != NULL &&
273 userData != NULL)
274 {
275 OrthancStone::WebAssemblyViewport& viewport =
276 *reinterpret_cast<OrthancStone::WebAssemblyViewport*>(userData);
277
278 switch (eventType)
279 {
280 case EMSCRIPTEN_EVENT_CLICK:
281 {
282 static unsigned int count = 0;
283 char buf[64];
284 sprintf(buf, "click %d", count++);
285
286 std::auto_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
287 layer->SetText(buf);
288 viewport.GetScene()->SetLayer(100, layer.release());
289 viewport.Refresh();
290 break;
291 }
292
293 case EMSCRIPTEN_EVENT_MOUSEDOWN:
294 {
295 OrthancStone::FlexiblePointerTrackerPtr t;
296
297 {
298 std::auto_ptr<OrthancStone::PointerEvent> event(
299 ConvertMouseEvent(*mouseEvent, viewport));
300
301 switch (mouseEvent->button)
302 {
303 case 0: // Left button
304 emscripten_console_log("Creating RotateSceneTracker");
305 t.reset(new OrthancStone::RotateSceneTracker(
306 viewport.GetController(), *event));
307 break;
308
309 case 1: // Middle button
310 emscripten_console_log("Creating PanSceneTracker");
311 LOG(INFO) << "Creating PanSceneTracker" ;
312 t.reset(new OrthancStone::PanSceneTracker(
313 viewport.GetController(), *event));
314 break;
315
316 case 2: // Right button
317 emscripten_console_log("Creating ZoomSceneTracker");
318 t.reset(new OrthancStone::ZoomSceneTracker(
319 viewport.GetController(), *event, viewport.GetCanvasWidth()));
320 break;
321
322 default:
323 break;
324 }
325 }
326
327 if (t.get() != NULL)
328 {
329 tracker_.reset(
330 new OrthancStone::ActiveTracker(t, viewport));
331 viewport.Refresh();
332 }
333
334 break;
335 }
336
337 case EMSCRIPTEN_EVENT_MOUSEMOVE:
338 if (tracker_.get() != NULL)
339 {
340 std::auto_ptr<OrthancStone::PointerEvent> event(
341 ConvertMouseEvent(*mouseEvent, viewport));
342 tracker_->PointerMove(*event);
343 viewport.Refresh();
344 }
345 break;
346
347 case EMSCRIPTEN_EVENT_MOUSEUP:
348 if (tracker_.get() != NULL)
349 {
350 std::auto_ptr<OrthancStone::PointerEvent> event(
351 ConvertMouseEvent(*mouseEvent, viewport));
352 tracker_->PointerUp(*event);
353 viewport.Refresh();
354 if (!tracker_->IsAlive())
355 tracker_.reset();
356 }
357 break;
358
359 default:
360 break;
361 }
362 }
363
364 return true;
365 }
366
367
368 void OrthancStone::WebAssemblyViewport::SetupEvents(const std::string& canvas)
369 {
370 #if 0
371 emscripten_set_click_callback(canvas.c_str(), this, false, OnMouseEvent);
372 #else
373 emscripten_set_mousedown_callback(canvas.c_str(), this, false, OnMouseEvent);
374 emscripten_set_mousemove_callback(canvas.c_str(), this, false, OnMouseEvent);
375 emscripten_set_mouseup_callback(canvas.c_str(), this, false, OnMouseEvent);
376 #endif
377 }
378 128
379 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport1_; 129 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport1_;
380 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport2_; 130 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport2_;
381 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport3_; 131 std::auto_ptr<OrthancStone::WebAssemblyViewport> viewport3_;
382 OrthancStone::MessageBroker broker_; 132 OrthancStone::MessageBroker broker_;