operator.py 21.4 KB
Newer Older
Dalai Felinto's avatar
Dalai Felinto committed
1
2
3
4
import bpy

from bpy.app.handlers import persistent

Dalai Felinto's avatar
Dalai Felinto committed
5
from .hmd import HMD
Dalai Felinto's avatar
Dalai Felinto committed
6
7
8

from .preview import Preview

9
10
from .lib import (
        getDisplayBackend,
11
        isMac,
12
        )
Dalai Felinto's avatar
Dalai Felinto committed
13

Dalai Felinto's avatar
Dalai Felinto committed
14

15
TODO = False
Dalai Felinto's avatar
Dalai Felinto committed
16

17
18
19
20
21
22
23

# ############################################################
# Commands
# ############################################################

class Commands:
    recenter = 'RECENTER'
Dalai Felinto's avatar
Dalai Felinto committed
24
    fullscreen = 'FULLSCREEN'
Dalai Felinto's avatar
Dalai Felinto committed
25
26
    play = 'PLAY'
    pause = 'PAUSE'
27
28
29
    test = 'TEST'


Dalai Felinto's avatar
Dalai Felinto committed
30
class SlaveStatus:
Dalai Felinto's avatar
Dalai Felinto committed
31
32
33
34
35
    non_setup    = 0   # initial
    dupli        = 1   # view3d duplicated
    uiless       = 2   # view3d without UI
    waituser     = 3   # waiting for user to move window to HMD
    usermoved    = 4   # user moved window
36
37
38
39
40
    ready        = 5   # all went well
    play         = 6   # play
    pause        = 7   # pause
    paused       = 8   # paused
    error        = 9   # something didn't work
Dalai Felinto's avatar
Dalai Felinto committed
41
42


Dalai Felinto's avatar
Dalai Felinto committed
43
44
45
46
47
48
49
50
51
52
# ############################################################
# Main Operator
# ############################################################

class VirtualRealityDisplayOperator(bpy.types.Operator):
    """"""
    bl_idname = "view3d.virtual_reality_display"
    bl_label = "Toggle Virtual Reality Display"
    bl_description = ""

53
    # update the values in def _init_static
Dalai Felinto's avatar
Dalai Felinto committed
54
    _hmd = None
Dalai Felinto's avatar
Dalai Felinto committed
55
    _timer = None
56
57
58
    _handle_pre = None
    _handle_post = None
    _handle_pixel = None
59
60
    _hash_slave = -1
    _hash_master = -1
Dalai Felinto's avatar
Dalai Felinto committed
61
    _slave_status = 0
Dalai Felinto's avatar
Dalai Felinto committed
62
    _slave_window = None
63
64
    _slave_area = None
    _is_mac = False
65
66
67
    _visible_master = None
    _visible_slave = None
    _is_rendering = False
Dalai Felinto's avatar
Dalai Felinto committed
68
69
70
71
72

    action = bpy.props.EnumProperty(
        description="",
        items=(("ENABLE", "Enable", "Enable"),
               ("DISABLE", "Disable", "Disable"),
Dalai Felinto's avatar
Dalai Felinto committed
73
               ("TOGGLE", "Toggle", "Toggle"),
74
               ("RECENTER", "Re-Center", "Re-Center tracking data"),
Dalai Felinto's avatar
Dalai Felinto committed
75
               ("FULLSCREEN", "Fullscreen", "Make slave fullscreen"),
Dalai Felinto's avatar
Dalai Felinto committed
76
77
               ("PLAY", "Play", ""),
               ("PAUSE", "Pause", ""),
Dalai Felinto's avatar
Dalai Felinto committed
78
               ),
Dalai Felinto's avatar
Dalai Felinto committed
79
        default="TOGGLE",
Dalai Felinto's avatar
Dalai Felinto committed
80
81
82
83
84
85
86
87
88
89
        options={'SKIP_SAVE'},
        )

    @classmethod
    def poll(cls, context):
        return context.area.type == 'VIEW_3D'

    def modal(self, context, event):
        wm = context.window_manager
        vr = wm.virtual_reality
90
91
92
93
94
95
        area = context.area

        if not area:
            self.quit(context)
            self._quit(context)
            return {'FINISHED'}
Dalai Felinto's avatar
Dalai Felinto committed
96
97
98

        if not vr.is_enabled:
            self._quit(context)
99
            area.tag_redraw()
Dalai Felinto's avatar
Dalai Felinto committed
100
101
            return {'FINISHED'}

102
103
104
105
106
107
        if event.type == 'TIMER' and \
           not vr.is_paused:
            if self._slave_area:
                self._slave_area.tag_redraw()

            if vr.use_preview:
108
                area.tag_redraw()
Dalai Felinto's avatar
Dalai Felinto committed
109
110
111
112
113
114
115
116
117

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        wm = context.window_manager
        vr = wm.virtual_reality

        is_enabled = vr.is_enabled

Dalai Felinto's avatar
Dalai Felinto committed
118
119
120
        if self.action == 'TOGGLE':
            self.action = 'DISABLE' if is_enabled else 'ENABLE'

Dalai Felinto's avatar
Dalai Felinto committed
121
        if self.action == 'DISABLE':
122
            if is_enabled:
Dalai Felinto's avatar
Dalai Felinto committed
123
124
125
126
127
128
                self.quit(context)
                return {'FINISHED'}
            else:
                self.report({'ERROR'}, "Virtual Reality Display is not enabled")
                return {'CANCELLED'}

129
130
        elif self.action == 'ENABLE':
            if is_enabled:
Dalai Felinto's avatar
Dalai Felinto committed
131
132
133
134
135
136
137
                self.report({'ERROR'}, "Virtual Reality Display is already enabled")
                return {'CANCELLED'}

            if self.init(context):
                return {'RUNNING_MODAL'}
            else:
                # quit right away
138
                vr.is_enabled = False
Dalai Felinto's avatar
Dalai Felinto committed
139
140
                self._quit(context)

141
142
143
144
        elif self.action == 'RECENTER':
            vr.command_push(Commands.recenter)
            return {'FINISHED'}

Dalai Felinto's avatar
Dalai Felinto committed
145
146
147
148
        elif self.action == 'FULLSCREEN':
            vr.command_push(Commands.fullscreen)
            return {'FINISHED'}

Dalai Felinto's avatar
Dalai Felinto committed
149
150
        elif self.action == 'PLAY':
            vr.command_push(Commands.play)
151
152
153
            # we define is_paused right away, so
            # the next MODAL loop already tag_redraw
            vr.is_paused = False
Dalai Felinto's avatar
Dalai Felinto committed
154
155
156
157
            return {'FINISHED'}

        elif self.action == 'PAUSE':
            vr.command_push(Commands.pause)
158
            self._redraw(context)
Dalai Felinto's avatar
Dalai Felinto committed
159
160
            return {'FINISHED'}

161
162
163
        else:
            assert False, "action \"{0}\" not implemented".format(self.action)

Dalai Felinto's avatar
Dalai Felinto committed
164
165
        return {'CANCELLED'}

166
167
168
169
170
171
172
    def _redraw(self, context, redraw_master=True, redraw_slave=True):
        if redraw_slave and self._slave_area:
            self._slave_area.tag_redraw()

        if redraw_master:
            context.area.tag_redraw()

Dalai Felinto's avatar
Dalai Felinto committed
173
174
175
176
    def quit(self, context):
        """garbage collect"""
        # change it so the original modal operator will clean things up
        wm = context.window_manager
177
        wm.virtual_reality.reset()
Dalai Felinto's avatar
Dalai Felinto committed
178
179
180
181

    def _quit(self, context):
        """actual quit"""

Dalai Felinto's avatar
Dalai Felinto committed
182
183
184
185
186
        if self._timer:
            wm = context.window_manager
            wm.event_timer_remove(self._timer)
            self._timer = None

187
188
189
190
191
192
193
194
195
196
197
        if self._handle_pre:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle_pre, 'WINDOW')
            self._handle_pre = None

        if self._handle_post:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle_post, 'WINDOW')
            self._handle_post = None

        if self._handle_pixel:
            bpy.types.SpaceView3D.draw_handler_remove(self._handle_pixel, 'WINDOW')
            self._handle_pixel = None
Dalai Felinto's avatar
Dalai Felinto committed
198
199
200

        self._preview.quit()

Dalai Felinto's avatar
Dalai Felinto committed
201
202
203
        if self._hmd:
            self._hmd.quit()

Dalai Felinto's avatar
Dalai Felinto committed
204
        if self._slave_window:
Dalai Felinto's avatar
Dalai Felinto committed
205
            self._slave_window.close()
Dalai Felinto's avatar
Dalai Felinto committed
206

Dalai Felinto's avatar
Dalai Felinto committed
207
        # cleanup viewport
208
209
        if context.area:
            context.area.tag_redraw()
Dalai Felinto's avatar
Dalai Felinto committed
210

211
212
213
    def _init_static(self):
        self._hmd = None
        self._timer = None
214
215
216
        self._handle_pre = None
        self._handle_post = None
        self._handle_pixel = None
217
218
219
220
221
222
        self._hash_slave = -1
        self._hash_master = -1
        self._slave_status = 0
        self._slave_window = None
        self._slave_area = None
        self._is_mac = isMac()
223
224
225
        self._visible_master = None
        self._visible_slave = None
        self._is_rendering = False
226

Dalai Felinto's avatar
Dalai Felinto committed
227
228
229
230
231
    def init(self, context):
        """
        Initialize the callbacks and the external devices
        """
        wm = context.window_manager
Dalai Felinto's avatar
Dalai Felinto committed
232
233
        vr = wm.virtual_reality

234
        vr.reset()
Dalai Felinto's avatar
Dalai Felinto committed
235
        vr.is_enabled = True
236
237

        self._init_static()
Dalai Felinto's avatar
Dalai Felinto committed
238
239

        display_backend = getDisplayBackend(context)
240
        self._hmd = HMD(display_backend, context, self._error_callback)
Dalai Felinto's avatar
Dalai Felinto committed
241
242
        self._preview = Preview()

243
244
245
        self._hash_master = hash(context.area)

        # setup modal
Dalai Felinto's avatar
Dalai Felinto committed
246
        self._timer = wm.event_timer_add(1.0 / 75.0, context.window) # 75 Hz
247
248
249
        self._handle_pre = bpy.types.SpaceView3D.draw_handler_add(self._draw_callback_pre, (context,), 'WINDOW', 'PRE_VIEW')
        self._handle_post = bpy.types.SpaceView3D.draw_handler_add(self._draw_callback_post, (context,), 'WINDOW', 'POST_VIEW')
        self._handle_pixel = bpy.types.SpaceView3D.draw_handler_add(self._draw_callback_pixel, (context,), 'WINDOW', 'POST_PIXEL')
250
251
252
        wm.modal_handler_add(self)

        if self._hmd.is_direct_mode:
Dalai Felinto's avatar
Dalai Felinto committed
253
            self._init(context)
254
        else:
Dalai Felinto's avatar
Dalai Felinto committed
255
256
            vr.is_slave_setup = True
            return self._slaveSetup(context)
257
258
259
260

        return True

    def _init(self, context):
Dalai Felinto's avatar
Dalai Felinto committed
261
        if not self._hmd.init(context):
Dalai Felinto's avatar
Dalai Felinto committed
262
            self.report({'ERROR'}, "Error initializing device")
263
            return False
Dalai Felinto's avatar
Dalai Felinto committed
264

265
        # get the data from device
266
        color_texture = [0, 0]
Dalai Felinto's avatar
Dalai Felinto committed
267
268
        for i in range(2):
            self._hmd.setEye(i)
269
            color_texture[i] = self._hmd.color_texture
Dalai Felinto's avatar
Dalai Felinto committed
270

271
        self._preview.init(color_texture[0], color_texture[1])
272
        return True
273

Dalai Felinto's avatar
Dalai Felinto committed
274
275
    def _slaveSetup(self, context):
        ok = True
Dalai Felinto's avatar
Dalai Felinto committed
276

Dalai Felinto's avatar
Dalai Felinto committed
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
        if self._slave_status == SlaveStatus.error:
            return False

        elif self._slave_status == SlaveStatus.non_setup:
            ok = self._slaveHook(context, SlaveStatus.dupli)
            self._slave_status = SlaveStatus.dupli

        elif self._slave_status == SlaveStatus.dupli:
            ok = self._slaveHook(context, SlaveStatus.uiless)
            self._slave_status = SlaveStatus.waituser

        elif self._slave_status == SlaveStatus.waituser:
            # waiting for the user input
            return True

        elif self._slave_status == SlaveStatus.usermoved:
293
            if not self._is_mac and not getDisplayBackend(context) == 'DEBUG':
294
                bpy.ops.wm.window_fullscreen_toggle()
Dalai Felinto's avatar
Dalai Felinto committed
295

296
297
298
299
300
            space = context.space_data
            if space.camera:
                region = context.region_data
                region.view_perspective = 'CAMERA'

301
            context.window_manager.virtual_reality.is_slave_setup = False
Dalai Felinto's avatar
Dalai Felinto committed
302
            ok = self._init(context)
Dalai Felinto's avatar
Dalai Felinto committed
303
            self._slave_status = SlaveStatus.ready
Dalai Felinto's avatar
Dalai Felinto committed
304
305

        elif self._slave_status == SlaveStatus.play:
306
            context.window_manager.virtual_reality.is_paused = False
Dalai Felinto's avatar
Dalai Felinto committed
307
308
            self._slave_status = SlaveStatus.ready

Dalai Felinto's avatar
Dalai Felinto committed
309
        elif self._slave_status == SlaveStatus.pause:
310
311
            context.window_manager.virtual_reality.is_paused = True
            context.area.tag_redraw()
Dalai Felinto's avatar
Dalai Felinto committed
312
313
            self._slave_status = SlaveStatus.paused

Dalai Felinto's avatar
Dalai Felinto committed
314
315
        else:
            assert False, "_slaveSetup: Slave status \"{0}\" not defined".format(self._slave_status)
316

Dalai Felinto's avatar
Dalai Felinto committed
317
318
        if not ok:
            self._slave_status = SlaveStatus.error
319
320
            self.quit(context)

Dalai Felinto's avatar
Dalai Felinto committed
321
        self._slave_window = context.window
Dalai Felinto's avatar
Dalai Felinto committed
322
323
324
        return ok

    def _slaveHook(self, context, mode=''):
325
        self._hash_slave = -1
326
        self._slave_area = None
Dalai Felinto's avatar
Dalai Felinto committed
327
        self._slave_status = SlaveStatus.non_setup
328
329
330
331
332
333
334
335

        hashes = []

        for screen in bpy.data.screens:
            for area in screen.areas:
                if area.type == 'VIEW_3D':
                    hashes.append(hash(area))

Dalai Felinto's avatar
Dalai Felinto committed
336
337
338
339
340
341
342
343
        if mode == SlaveStatus.dupli:
            bpy.ops.screen.area_dupli('INVOKE_DEFAULT')

        elif mode == SlaveStatus.uiless:
            bpy.ops.screen.screen_full_area(use_hide_panels=True)

        else:
            assert False, "_slaveHook: Slave status \"{0}\" not defined".format(self._slave_status)
344
345
346
347
348
349
350
351
352
353
354
355
356

        for screen in bpy.data.screens:
            for area in screen.areas:
                if area.type != 'VIEW_3D':
                    continue

                _hash = hash(area)

                try:
                    hashes.remove(_hash)

                except ValueError:
                    self._hash_slave = _hash
357
                    self._slave_area = area
358
359
360
361
                    print('Success finding slave')
                    return True

        return False
Dalai Felinto's avatar
Dalai Felinto committed
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
    def _commands(self, context):
        """
        Process any pending command from the main window
        """
        wm = context.window_manager
        vr = wm.virtual_reality

        while vr.commands:
            command = vr.command_pop()

            if command == Commands.recenter:
                if self._hmd:
                    self._hmd.reCenter()

Dalai Felinto's avatar
Dalai Felinto committed
377
378
379
380
            elif command == Commands.fullscreen:
                self._slave_status = SlaveStatus.usermoved
                self._slaveSetup(context)

Dalai Felinto's avatar
Dalai Felinto committed
381
382
383
384
385
386
387
388
            elif command == Commands.play:
                self._slave_status = SlaveStatus.play
                self._slaveSetup(context)

            elif command == Commands.pause:
                self._slave_status = SlaveStatus.pause
                self._slaveSetup(context)

389
390
391
            elif command == Commands.test:
                print("Testing !!!")

Dalai Felinto's avatar
Dalai Felinto committed
392
393
394
            else:
                assert False, "_commands: command \"{0}\" not implemented"

395
    def _loop(self, context):
Dalai Felinto's avatar
Dalai Felinto committed
396
397
398
        """
        Get fresh tracking data and render into the FBO
        """
399
        self._is_rendering = True
Dalai Felinto's avatar
Dalai Felinto committed
400
        self._hmd.loop(context)
Dalai Felinto's avatar
Dalai Felinto committed
401

Dalai Felinto's avatar
Dalai Felinto committed
402
403
404
405
        scene = context.scene
        view3d = context.space_data
        region = context.region

Dalai Felinto's avatar
Dalai Felinto committed
406
407
        for i in range(2):
            self._hmd.setEye(i)
408

409
            offscreen = self._hmd.offscreen
Dalai Felinto's avatar
Dalai Felinto committed
410
            projection_matrix = self._hmd.projection_matrix
411
            modelview_matrix = self._hmd.modelview_matrix
412

Dalai Felinto's avatar
Dalai Felinto committed
413
            # drawing
Dalai Felinto's avatar
Dalai Felinto committed
414
            offscreen.draw_view3d(scene, view3d, region, projection_matrix, modelview_matrix)
Dalai Felinto's avatar
Dalai Felinto committed
415
416

        self._hmd.frameReady()
417
        self._is_rendering = False
Dalai Felinto's avatar
Dalai Felinto committed
418

419
420
421
    def _drawMaster(self, context):
        wm = context.window_manager
        vr = wm.virtual_reality
Dalai Felinto's avatar
Dalai Felinto committed
422

423
        if self._hmd.is_direct_mode:
Dalai Felinto's avatar
Dalai Felinto committed
424
            self._commands(context)
425
426
427
428
429

        if vr.is_paused:
            return

        if self._hmd.is_direct_mode:
430
431
432
433
434
435
            self._loop(context)

        if vr.use_preview:
            self._preview.loop(vr.preview_scale)

    def _drawSlave(self, context):
436
437
438
        wm = context.window_manager
        vr = wm.virtual_reality

439
        if self._hmd.is_direct_mode:
440
441
            return

Dalai Felinto's avatar
Dalai Felinto committed
442
        self._commands(context)
443

444
445
446
        if vr.is_paused:
            return

Dalai Felinto's avatar
Dalai Felinto committed
447
448
449
        if self._slave_status == SlaveStatus.ready:
            self._loop(context)

Dalai Felinto's avatar
Dalai Felinto committed
450
451
452
        elif self._slave_status == SlaveStatus.paused:
            return

Dalai Felinto's avatar
Dalai Felinto committed
453
        elif self._slave_status == SlaveStatus.waituser:
454
            self._drawDisplayMessage(context)
Dalai Felinto's avatar
Dalai Felinto committed
455
456
457
458

        else:
            self._slaveSetup(context)

459
460
461
462
    def _drawDisplayMessage(self, context):
        """
        Message telling user to move the window the HMD display
        """
Dalai Felinto's avatar
Dalai Felinto committed
463
464
        from bgl import glColor4f

465
466
467
468
        window = context.window
        width = window.width
        height = window.height

Dalai Felinto's avatar
Dalai Felinto committed
469
        glColor4f(1.0, 1.0, 1.0, 1.0)
470
471
472
473
474
475
        font_id = 0

        # draw some text
        x = int(0.1 * width)
        y = int(0.5 * height)
        font_size = int(width * 0.035)
476
        line_gap = int(font_size * 1.5)
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492

        from blf import (
                SHADOW,
                enable,
                shadow,
                shadow_offset,
                position,
                size,
                draw,
                disable,
                )

        enable(font_id, SHADOW)
        shadow(font_id, 5, 0.0, 0.0, 0.0, 1.0)
        shadow_offset(font_id, -2, -2)
        size(font_id, font_size, 72)
493
494
495
496
497
498
499
500
501
502
503
504
505
506

        if self._is_mac:
            position(font_id, x, y + line_gap, 0)
            draw(font_id, "1. Move this window to the external HMD display")
            position(font_id, x, y, 0)
            draw(font_id, "2. Set this window to fullscreen (Alt + F11)")
            position(font_id, x, y - line_gap, 0)
            draw(font_id, "3. Select \"Start\" in the main window")
        else:
            position(font_id, x, y, 0)
            draw(font_id, "1. Move this window to the external HMD display")
            position(font_id, x, y - line_gap, 0)
            draw(font_id, "2. Select \"Start\" in the main window")

507
        disable(font_id, SHADOW)
508

509
510
    def _pre_draw_hide(self, context, visible):
        scene = context.scene
Dalai Felinto's avatar
Dalai Felinto committed
511
512
513
514
515
        space = context.space_data

        visible['objects'] = []
        objects = visible['objects']

516
517
        for ob in scene.objects:
            if not ob.hide:
Dalai Felinto's avatar
Dalai Felinto committed
518
                objects.append(ob)
519
520
                ob.hide = True

Dalai Felinto's avatar
Dalai Felinto committed
521
522
523
        visible['show_grease_pencil'] = space.show_grease_pencil
        space.show_grease_pencil = False

524
    def _post_draw_show(self, context, visible):
Dalai Felinto's avatar
Dalai Felinto committed
525
526
527
528
529
        space = context.space_data

        objects = visible['objects']

        for ob in objects:
530
531
            ob.hide = False

Dalai Felinto's avatar
Dalai Felinto committed
532
533
534
535
        visible['objects'] = []

        space.show_grease_pencil = visible['show_grease_pencil']

536
537
538
539
540
    def _hide_master(self, context):
        """
        whether to hide the main 3d viewport
        """
        vr = context.window_manager.virtual_reality
541
542
543
        if vr.is_paused:
            return False

544
545
546
547
548
549
550
551
552
553
        if vr.use_hmd_only:
            return True

        if vr.use_preview and vr.preview_scale == 100:
            return True

    def _draw_callback_pre(self, context):
        """
        hide all the scene objects to speed up rendering
        """
554
555
        if self._is_rendering or \
           context.window_manager.virtual_reality.is_debug:
556
557
558
559
560
561
            return

        area = context.area
        hash_area = hash(area)

        if hash_area == self._hash_slave:
Dalai Felinto's avatar
Dalai Felinto committed
562
            self._visible_slave = {}
563
564
565
            self._pre_draw_hide(context, self._visible_slave)

        elif hash_area == self._hash_master and self._hide_master(context):
Dalai Felinto's avatar
Dalai Felinto committed
566
            self._visible_master = {}
567
568
569
570
571
572
            self._pre_draw_hide(context, self._visible_master)

    def _draw_callback_post(self, context):
        """
        show all the hidden objects
        """
573
574
        if self._is_rendering or \
           context.window_manager.virtual_reality.is_debug:
575
576
577
578
579
580
581
582
583
584
585
586
            return

        area = context.area
        hash_area = hash(area)

        if hash_area == self._hash_slave:
            self._post_draw_show(context, self._visible_slave)

        elif hash_area == self._hash_master and self._hide_master(context):
            self._post_draw_show(context, self._visible_master)

    def _draw_callback_pixel(self, context):
587
        """
588
        callback function, run every time the viewport is refreshed
589
        """
590
591
592
        if self._is_rendering:
            return

593
594
595
        area = context.area
        hash_area = hash(area)

596
        if hash_area == self._hash_slave:
597
598
599
600
            self._drawSlave(context)

        elif hash_area == self._hash_master:
            self._drawMaster(context)
Dalai Felinto's avatar
Dalai Felinto committed
601

Dalai Felinto's avatar
Dalai Felinto committed
602
603
604
605
606
607
608
609
610
611
612
613
614
615
    def _error_callback(self, message, is_fatal):
        """
        Error handler, called from HMD class
        """
        context = bpy.context
        wm = context.window_manager
        vr = wm.virtual_reality

        if is_fatal:
            self.report({'ERROR'}, message)
            self.quit(context)

        vr.error_message = message

Dalai Felinto's avatar
Dalai Felinto committed
616
617
618
619
620

# ############################################################
# Global Properties
# ############################################################

621
622
623
624
625
626
627
628
from bpy.props import (
        BoolProperty,
        CollectionProperty,
        EnumProperty,
        StringProperty,
        IntProperty,
        )

Dalai Felinto's avatar
Dalai Felinto committed
629

630
631
632
633
634
class VirtualRealityCommandInfo(bpy.types.PropertyGroup):
    action = EnumProperty(
        name="Action",
        items=(("NONE", "None", ""),
               (Commands.recenter, "Re-Center", ""),
Dalai Felinto's avatar
Dalai Felinto committed
635
               (Commands.fullscreen, "Fullscreen", ""),
Dalai Felinto's avatar
Dalai Felinto committed
636
637
               (Commands.play, "Play", ""),
               (Commands.pause, "Pause", ""),
638
639
640
641
642
643
               (Commands.test, "Test", ""),
               ),
        default="NONE",
        )


Dalai Felinto's avatar
Dalai Felinto committed
644
class VirtualRealityInfo(bpy.types.PropertyGroup):
645
    is_enabled = BoolProperty(
Dalai Felinto's avatar
Dalai Felinto committed
646
647
648
649
            name="Enabled",
            default=False,
            )

650
651
652
653
654
    is_paused = BoolProperty(
            name="Paused",
            default=False,
            )

655
656
657
658
659
    use_preview = BoolProperty(
        name="Preview",
        default=False,
        )

660
661
662
663
664
    use_hmd_only = BoolProperty(
        name="HMD Only",
        default=False,
        )

665
    preview_scale = IntProperty(
666
667
668
            name="Preview Scale",
            min=0,
            max=100,
669
            default=20,
670
            subtype='PERCENTAGE',
Dalai Felinto's avatar
Dalai Felinto committed
671
672
            )

673
    error_message = StringProperty(
Dalai Felinto's avatar
Dalai Felinto committed
674
675
676
            name="Error Message",
            )

677
678
679
680
681
682
683
684
685
686
    tracking_mode = EnumProperty(
        name="Tracking Mode",
        description="",
        items=(("ALL", "All", ""),
               ("ROTATION", "Rotation Only", "Ignore positional tracking data"),
               ("NONE", "None", "No tracking"),
               ),
        default="ALL",
        )

Dalai Felinto's avatar
Dalai Felinto committed
687
688
689
690
    is_slave_setup = BoolProperty(
        default = False,
        )

691
692
693
694
695
696
    is_debug = BoolProperty(
        name = "Debug",
        default = False,
        description = "Skip the optimization to prevent extra drawing",
        )

697
698
699
700
701
702
703
704
705
706
707
708
709
    commands = CollectionProperty(type=VirtualRealityCommandInfo)


    def command_push(self, action):
        command = self.commands.add()
        command.action = action

    def command_pop(self):
        command = self.commands[0]
        action = command.action
        self.commands.remove(0)
        return action

710
    def reset(self):
711
712
713
        while self.commands:
            self.commands.remove(0)

714
        self.use_preview = False
715
        self.use_hmd_only = False
716
717
        self.error_message = ""
        self.is_enabled = False
Dalai Felinto's avatar
Dalai Felinto committed
718
        self.is_slave_setup = False
719
        self.is_paused = False
720
        self.is_debug = False
721

722

Dalai Felinto's avatar
Dalai Felinto committed
723
724
725
726
727
728
729
# ############################################################
# Callbacks
# ############################################################

@persistent
def virtual_reality_load_pre(dummy):
    wm = bpy.context.window_manager
730
    wm.virtual_reality.reset()
Dalai Felinto's avatar
Dalai Felinto committed
731
732
733
734
735


@persistent
def virtual_reality_load_post(dummy):
    wm = bpy.context.window_manager
736
    wm.virtual_reality.reset()
Dalai Felinto's avatar
Dalai Felinto committed
737
738
739
740
741
742
743
744
745
746
747


# ############################################################
# Un/Registration
# ############################################################

def register():
    bpy.app.handlers.load_pre.append(virtual_reality_load_pre)
    bpy.app.handlers.load_pre.append(virtual_reality_load_post)

    bpy.utils.register_class(VirtualRealityDisplayOperator)
748
    bpy.utils.register_class(VirtualRealityCommandInfo)
Dalai Felinto's avatar
Dalai Felinto committed
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    bpy.utils.register_class(VirtualRealityInfo)
    bpy.types.WindowManager.virtual_reality = bpy.props.PointerProperty(
            name="virtual_reality",
            type=VirtualRealityInfo,
            options={'HIDDEN'},
            )


def unregister():
    bpy.app.handlers.load_pre.remove(virtual_reality_load_pre)
    bpy.app.handlers.load_pre.remove(virtual_reality_load_post)

    bpy.utils.unregister_class(VirtualRealityDisplayOperator)
    del bpy.types.WindowManager.virtual_reality
    bpy.utils.unregister_class(VirtualRealityInfo)
764
    bpy.utils.unregister_class(VirtualRealityCommandInfo)
Dalai Felinto's avatar
Dalai Felinto committed
765