-
Notifications
You must be signed in to change notification settings - Fork 0
/
documentation.html
2366 lines (1798 loc) · 205 KB
/
documentation.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>Virtual World Framework</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/syntax.css" rel="stylesheet">
<!-- Custom styles -->
<link href="/css/vwf.css" rel="stylesheet">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<img src="/images/vwf-logo-100x100.png" class="pull-left" alt="VWF Duck Logo">
<span class="pull-right">Virtual<br>World<br>Framework</span>
</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/demos.html">Demos</a></li>
<li><a href="/getting_started.html">Tutorial</a></li>
<li><a href="/documentation.html">Documentation</a></li>
<li><a href="/releases.html">Downloads</a></li>
</ul>
<a href="http://github.com/virtual-world-framework/vwf" class="btn btn-info navbar-btn pull-right hidden-sm" role="button">View on GitHub</a>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container" id="docs">
<div class="row">
<div id="nav" class="col-md-2 hidden-sm hidden-xs">
<div class="nav-wrap" data-spy="affix" data-offset-top="0">
<ul class="navmenu list-unstyled">
<li>
<a href='#install' class='header' title='Introduction'>Installation</a>
</li>
<li>
<a href='#devguide' class='header' title='Dev Guide'>VWF Concepts</a>
<ul class="list-unstyled">
<li><a href='#partsofvwf' title='Architecture'>Parts of VWF</a></li>
<li><a href='#architecture' title='Architecture'>Architecture</a></li>
<li><a href='#components' title='Components'>Components</a></li>
<li><a href='#cameras' title='Cameras'>Cameras</a></li>
<li><a href='#lights' title='Lights'>Lights</a></li>
<li><a href='#prototypes' title='Prototypes'>Prototypes</a></li>
<li><a href='#behaviors' title='Behaviors'>Behaviors</a></li>
<li><a href='#animations' title='Animations'>Animations</a></li>
<li><a href='#html' title='HTML'>HTML</a></li>
<li><a href='#drivers' title='Drivers'>Drivers</a></li>
<li><a href='#editor' title='Editor'>Editor</a></li>
<li><a href='#querying' title='Querying'>Querying</a></li>
</ul>
</li>
<li>
<a href='#cookbook' class='header' title='Cookbook'>Cookbook</a>
<ul class="list-unstyled">
<li><a href='#multiuser' title='Multiuser'>Multiuser</a></li>
<li><a href='#simulation' title='Simulation'>Simulation</a></li>
<li><a href='#2d-interface' title='2D-Interface'>2D Interface</a></li>
<li><a href='#materials' title='Materials'>Materials</a></li>
<li><a href='#chat' title='Chat'>Chat</a></li>
<li><a href='#sound' title='Sound'>Sound</a></li>
<li><a href='#transforms' title='Transforms'>Transforms</a></li>
<li><a href='#lesson' title='Lesson'>Lesson</a></li>
<li><a href='#logging' title='Logging'>Logging</a></li>
<li><a href='#persistence' title='Persistence'>Persistence</a></li>
<li><a href='#testing' title='Testing'>Testing</a></li>
<li><a href='#pitfalls' title='Pitfalls'>Pitfalls</a></li>
</ul>
</li>
<li>
<a href='#application-api' class='header' title='APIs'>APIs</a>
<ul class="list-unstyled">
<li><a href='#application-api' title='Application API'>Application API</a></li>
<li><a href='#system-api' title='System API'>System API</a></li>
</ul>
</li>
<li>
<a href='#corecontributors' class='header' title='Core Contributors'>Core Contributors</a>
</li>
</ul>
</div>
<!-- End documentation specific layout -->
</div>
<div id="docs-content" class="col-md-9">
<h1><a name="install">Installation</a></h1>
<hr>
<h2>Windows</h2>
<!--
Download and run the VWF Windows Installer.
Launch a command prompt window and create a new VWF application:
c:\> vwf create MyApp
Change into your new application folder and start the server.
c:\> cd MyApp
c:\MyApp> vwf
-->
<p>Download and extract the latest Windows build from the <a href="https://virtual.wf/releases.html">Downloads</a> page.</p>
<p>Install <a href="http://nodejs.org/">Node.js</a>.</p>
<p>Launch a command prompt and navigate to your <em>vwf</em> folder. </p>
<p>Edit npm configuration settings:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">npm config set registry http://registry.npmjs.org/
</code></pre></div>
<p>Note: You may also need to set a proxy if required by your network:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">npm config set strict-ssl false
npm config set proxy http://yourproxy.com:80
npm config set https-proxy http://yourproxy.com:80
</code></pre></div>
<p>Install all the prerequisites for the VWF server:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">npm install
</code></pre></div>
<p>Start the server:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">npm start
</code></pre></div>
<p>Navigate to "localhost:3000" to see the sample duck application from your local machine.</p>
<h2>Mac OS X / Linux</h2>
<p>NOTE: On Mac OS X, please make sure you have <a href="https://developer.apple.com/xcode/">Xcode Command Line Tools</a> installed prior to executing the script.</p>
<p>Execute the following command at your terminal/shell prompt:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">$ curl -L http://get.virtual.wf | sh
</code></pre></div>
<p>Launch a command prompt window and create a new VWF application:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">$ vwf create MyApp
</code></pre></div>
<p>Change into your new folder application, and start the server.</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">$ cd MyApp
MyApp$ vwf
</code></pre></div>
<h2>Demo Apps</h2>
<p>For additional VWF app examples, download the <a href="https://github.com/virtual-world-framework/vwf-apps/archive/master.zip">vwf-apps repo</a>, and unzip to your <em>public</em> directory. </p>
<hr>
<h2><a name="troubleshooting">Troubleshooting</a></h2>
<p>The following resources may be helpful for troubleshooting any issues that arise.</p>
<ul>
<li><p>Verify <a href="#install">installation instructions</a> were followed.</p></li>
<li><p>Load an application, and verify all the requirements are met on the loading screen. </p></li>
<li><p>Open the developer console to check for any error messages. </p>
<ul>
<li><p>In Google Chrome, press Ctrl+Shift+J or select the tools menu -> Tools -> Developer Tools -> JavaScript Console. </p>
<p><img src='images/chrome.png' alt='chrome' style='width:500px' /></p></li>
<li><p>In Mozilla Firefox, download and install <a href="https://addons.mozilla.org/en-us/firefox/addon/firebug">Firebug</a>. Select the bug icon in the upper right of the browser to run, and then select the Console window. </p>
<p><img src='images/firebug.png' alt='firebug' style='width:500px' /></p></li>
</ul></li>
</ul>
<h1><a name="devguide">VWF Concepts</a></h1>
<p>If you haven't already built your first VWF app by following our <a href="getting_started.html">tutorial</a>, we highly recommend it!</p>
<p>This section will expand upon what you learned in the tutorial and run through some VWF concepts that will help you create your VWF apps.</p>
<h2><a name="partsofvwf">Parts of VWF</a></h2>
<div style='width:100%;text-align:center'><img src='images/vwf-onion.png' alt='arch' width='512' /></div>
<p>VWF consists of two pieces:</p>
<ol>
<li>Core: Consists of the server and part of the client and ensures synchronization between the model state on every client.</li>
<li>Drivers: Add functionality to VWF by providing access to 3rd party libraries (like three.js for graphics)</li>
</ol>
<p>VWF enables one to create:</p>
<ol>
<li>Components: A meaningful unit of functionality. Components are the building blocks of VWF applications. A component might contain a 3D model and/or it might contain some functionality.</li>
<li>Applications: This is a full VWF ... well ... application. It's something that a user can sit down and use.</li>
</ol>
<p>The VWF ecosystem is everything that exists to help developers create components and applications. Many of the items listed in the <em>Ecosystem</em> circle are works in progress.</p>
<hr>
<h2><a name="architecture">Anatomy of a VWF App</a></h2>
<p>VWF allows you to ignore the complexity of sharing state between multiple users. You focus on the logic of your app, and as long as you follow VWF conventions, nothing else must be done to achieve a synchronized state across multiple users. </p>
<p>Let's look at the anatomy of a VWF app to understand a little of how it works under the hood.</p>
<h3>Model-view architecture</h3>
<p>VWF has a model-view based architecture. Views exist for each client joined in the app. Each view provides input into a model that keeps track of the state of the simulation. </p>
<div style='width:100%;text-align:center'><img src='images/arch1.png' alt='arch' width='512' /></div>
<p>The single model, or shared state, of the application has multiple copies that represent the shared simulation. </p>
<div style='width:100%;text-align:center'><img src='images/arch2.png' alt='arch' width='512' /></div>
<p>Each client then has their own replicated model that they take with them. The model, however, remains the same as the one that every other user is viewing. All clients show the same state with each having an identical copy of the app. The app are separately but simultaneously updated to retain identical states. </p>
<p>The app then is a state machine. The same state machine is in different locations (different clients). If the state machines all have the same properties and children, they will all move to the same successive state.</p>
<p>A client's browser may have multiple views. For example, a user may see a renderer view and an editor view in their browser window. The renderer view shows a 3D visualization of the model state, and the editor view shows the hierachy of the scene and the pieces that make it up such as it's properties and children.</p>
<div style='width:100%;text-align:center'><img src='images/arch3.png' alt='arch' width='512' /></div>
<p>External inputs from one user get thrown "across the moat" into the shared simulation (model) [1]. The model deflects incoming input from a view, and sends it directly to the reflector [2]. The reflector can then send out the information to all of the replicated models [3]. Thus all inputs to a model happen identically on the timeline to all clients within the application. </p>
<div style='width:100%;text-align:center'><img src='images/arch4.png' alt='arch' width='512' /></div>
<p>The architecture separates external input from internal input. All external input (ie. user input from a view), once received by the model is deferred to the reflector, which then sends it out to everyone. However, the model is free to make any additional state changes (ie. internal input) provided that it was caused by something internal to the model. This would include things such as setter methods that can manipulate other internal properties. </p>
<h3>The Model side</h3>
<p>The application's main model file is usually named <code>index.vwf.yaml</code>. The <code>index</code> part can actually be replaced with any name, but if it is named <code>index.vwf.yaml</code>, the filename is not necessary in the browser url (only the path leading to it). It can actually also be a .json file instead (<code>index.vwf.json</code>). We use .yaml because of its human-readableness.</p>
<p>Everything in the <em>model</em> is automatically syncrhonized across all users. Let's take a look at how the model is composed.</p>
<h4>Nodes</h4>
<p>A <em>node</em> is the atomic unit of state in the VWF model. The application's entire model state is comprised of a tree of nodes.</p>
<h4>Components</h4>
<p>A tree of nodes that forms a functional unit (for example, a tree composed of a car node that has four children tire nodes) is called a <em>component</em>.</p>
<p>Since a component can actually be made from a single node (since that is technically a tree ... just a very simple one), you will sometimes catch us calling individual nodes components.</p>
<p>To summarize: the model side of a VWF application is made up of one or more components, which are in-turn made up of one or more components. Like this:</p>
<div style='width:100%;text-align:center'><img src='images/arch5.png' alt='arch' width='600' /></div>
<p>Additionally, components may extend prototype components, and will inherit their properties, methods, and events. A prototype may have multiple components that extend it in an application. Like this:</p>
<div style='width:100%;text-align:center'><img src='images/arch6.png' alt='arch' width='600' /></div>
<p>Since components are such a big deal in VWF, we'll come back to them in more detail in the <a href="#components">components</a> section where we show you the structure of a component definition. And if you want to see what components already exist inside VWF that you can use as prototypes in your applications, check out the <a href="#prototypes">prototypes</a> section. </p>
<p>But for now, let's move onto talking about the other half of a VWF application ... the <em>view</em>.</p>
<h3>The View side</h3>
<p>The application's main model file is usually named <code>index.vwf.html</code>. Again, just like the model file, it can actually be named anything, but the part before the <code>vwf.html</code> needs to match that part of the model files name.</p>
<p>The view side is what the user interacts with. It contains the logic for anything that is user-specific (like the logic for a user controlling their personal avatar, etc). Therefore, the view is not synchronized across every user.</p>
<p>The main file is an html file, and it is the primary means for creating 2D elements in your application (3D elements are handled by the three.js driver, but that is a topic for later). From this file you may also include untold numbers of <code>.js</code> files to implement view-side logic (like the aformentioned user controlling their avatar).</p>
<p>In a VWF application, the model does not know that the view exists. The view knows that the model exists and can listen for changes to it (and perform some view-side logic as a result). It can also take user input and create its own changes to the model by setting properties and calling methods (etc) on those components we mentioned in the last section.</p>
<hr>
<h2><a name="components">Components</a></h2>
<p>Components define the behavior, state and visual representation of an object and are the basic building blocks of VWF. Components make up a hierarchical structure, with each component acting as the parent or child to another component. At the root of the structure is the application, which is also a component, and is created automatically when the application loads.</p>
<hr>
<h3>Component Contents</h3>
<p>There are eight parts that make up a component, seen here as a skeleton in YAML.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">source</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">type</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">children</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
</code></pre></div>
<p>Each part is optional and only needs to be included in the component definition if that part needs to be customized in the component. All relative paths are resolved using the current component as the base.</p>
<h4>extends</h4>
<p>This specifies the URI or descriptor of the prototype component that is extended to make the new component. All behaviors, properties, methods, events, children and scripts are inherited by the component. The default prototype is <code>http://vwf.example.com/node.vwf</code>.</p>
<p>To specify a prototype using a URI, simply provide the URI.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/prototype.vwf</span>
</code></pre></div>
<p>Since a prototype is also a component, it can be specified using the same format.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">source</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">type</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">children</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
</code></pre></div>
<p>See <a href="#prototypes">prototypes</a> for more information.</p>
<h4>implements</h4>
<p>This specifies the URIs of components that will be used as behaviors. All behaviors, properties, methods, events, children and scripts are inherited by the component, allowing functionality to be added from a separate file.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/behavior.vwf</span>
</code></pre></div>
<p>See <a href="#behaviors">behaviors</a> for more information.</p>
<h4>source/type</h4>
<p>The source and type allow the component to load a seperate data blob, usually in the form of a 3D model or image. Source is the URI of the data, and type is the MIME type. If type is not specified, it will default to the MIME type taken from the server's response.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">source</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">model.dae</span>
<span class="l-Scalar-Plain">type</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">model/vnd.collada+xml</span>
</code></pre></div>
<h4>properties</h4>
<p>Properties are the public variables of the component. The component inherits properties from its prototype and any behaviors. Initializing a property will override any default values from the prototype or behavior.</p>
<p>The declaration for a property provides only a name, and an optional value.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">aProperty</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">value</span>
</code></pre></div>
<p>Properties can also be declared with accessor functions that allow the component to detect changes, allow only acceptable values, or serve as a proxy for another property. </p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">aProperty</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">set</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span> <span class="c1"># calculate and set the value</span>
<span class="no">this.aProperty = value</span>
<span class="l-Scalar-Plain">get</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span> <span class="c1"># calculate and return the value</span>
<span class="no">return this.aProperty</span>
<span class="l-Scalar-Plain">value</span><span class="p-Indicator">:</span> <span class="c1"># the value is available to the accessor functions</span>
<span class="l-Scalar-Plain">value</span>
</code></pre></div>
<h4>methods</h4>
<p>Methods are the public functions of the component. The component inherits methods from its prototype and behaviors. Redefining those methods here will override the inherited ones.</p>
<p>The method declaration only provides the body of the method.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">aMethod</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
<span class="no">// method body</span>
</code></pre></div>
<p>The extended method specifier allows named parameters. Additional parameters can still be parsed out of the arguments object when needed.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">anotherMethod</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">parameters</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">one</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">two</span>
<span class="l-Scalar-Plain">body</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
<span class="no">var three = arguments[2];</span>
<span class="no">this.something(one, two, three);</span>
</code></pre></div>
<p>Methods can also be declared empty, and intialized in a script later.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">aMethod</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">this.aMethod = function(one, two, three) {</span>
<span class="no">}</span>
</code></pre></div>
<h4>events</h4>
<p>Events define the outgoing messages a node can trigger. The component inherits events from its prototype and behaviors. </p>
<p>The event specifier only provides the name of the event.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">anEvent</span><span class="p-Indicator">:</span>
</code></pre></div>
<p>The extended event specifier describes the arguments passed to the event. As with methods, additional parameters can still be parsed out of the arguments object in the event handler.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">anotherEvent</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">parameters</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">one</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">two</span>
</code></pre></div>
<p>To listen for events, a javascript function that matches the event name is added to the Scripts section of the component.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">anEvent</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">this.anEvent = function() {</span>
<span class="no">}</span>
</code></pre></div>
<p>VWF also defines several dispatched events. These are triggered when outside actions, such as a key press or mouse click occur. When one of these events occurs, the system automatically finds any nodes that have been definined as triggering the event, and dispatches the event from those nodes. Currently, the dispatched events defined by VWF are:</p>
<ul>
<li><code>keyDown</code></li>
<li><code>keyUp</code></li>
<li><code>pointerClick</code></li>
<li><code>pointerDown</code></li>
<li><code>pointerOver</code></li>
<li><code>pointerHover</code></li>
<li><code>pointerOut</code></li>
<li><code>pointerMove</code></li>
<li><code>pointerUp</code></li>
<li><code>pointerWheel</code></li>
</ul>
<h4>children</h4>
<p>Children are instances of other components that are attached to this component. A child can be a simple reference to a separate component, or the reference can include a configuration. The format for a child specification is the same as for a component.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">children</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">childFromURI</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/component.vwf</span>
<span class="l-Scalar-Plain">childFromDescriptor</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/component.vwf</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">something</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">value</span>
<span class="l-Scalar-Plain">childFromDescriptorDetailed</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/prototype.vwf</span>
<span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/behavior.vwf</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http://vwf.example.com/a/different/behavior.vwf</span>
<span class="l-Scalar-Plain">source</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">asset.dat</span>
<span class="l-Scalar-Plain">type</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">mime/type</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">another</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">another</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">events</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">another</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">descriptor</span>
<span class="l-Scalar-Plain">children</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">component</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">another</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">component</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">specifier</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">specifier</span>
</code></pre></div>
<h4>scripts</h4>
<p>Scripts define the component's internal behavior and can be used to create and use private variables and methods, and event handlers. Currently the only language supported for scripts is JavaScript.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">var aVariable;</span>
<span class="no">this.aFunction = function() {</span>
<span class="no">...</span>
<span class="no">}</span>
</code></pre></div>
<p>Inside a script <code>this</code> always refers to the component that owns the script. Other components can be accessed by navigating up or down the component hierarchy using <code>this.parent</code> and <code>this.children.childName</code>. VWF also defines an <code>initialize</code> function that is automatically executed when a component is initialized. In order to use this function, define it like any other function.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">this.initialize = function() {</span>
<span class="no">...</span>
<span class="no">}</span>
</code></pre></div>
<hr>
<h3>Manipulating Components With JavaScript</h3>
<p>The various parts of a component can also be modified from JavaScript after the component has been initialized as a node. VWF defines several functions to make these changes.</p>
<h4>properties</h4>
<p>New properties can be added using the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"propertyName"</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
</code></pre></div>
<p>The first parameter is the name of the new property, and the second is its initial value. There are also two optional parameters that customize the getter and setter of the parameter. These are passed in as strings.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"propertyName"</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="s2">"return this.propertyName;"</span><span class="p">,</span> <span class="s2">"this.propertyName = value;"</span><span class="p">);</span>
</code></pre></div>
<h4>methods</h4>
<p>New methods can be added using the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">methods</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"methodName"</span><span class="p">,</span> <span class="p">[</span><span class="nx">methodParameters</span><span class="p">,...],</span> <span class="nx">methodBody</span><span class="p">);</span>
</code></pre></div>
<p>The first parameter is the name of the new method, the second is an array of any parameters the method will take, and the third is the body of the method, as a string.</p>
<h4>events</h4>
<p>Creating a new event uses the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"eventName"</span><span class="p">,</span> <span class="p">[</span><span class="nx">eventParameters</span><span class="p">]);</span>
</code></pre></div>
<p>The first parameter is the name of the new event and the second is an array of any parameters the event will take.</p>
<p>New event listeners can also be added.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">eventName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">},</span> <span class="nx">phases</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">listeningNode</span><span class="p">,</span> <span class="nx">callback</span> <span class="cm">/* listenerID */</span><span class="p">);</span>
</code></pre></div>
<p>The first parameter is the function that will be executed when the event occurs.</p>
<p>The second parameter is optional and defaults to <code>"bubble"</code>. Setting phases to <code>"capture"</code> will prevent the event from propagating to other nodes.</p>
<p>The third parameter will be used as the <code>this</code> value for the event and defaults to the node firing the event. Setting the parameter to the node listening for the event allows the listener function to find its node more easily. This parameter is also optional.</p>
<p>The final parameter is an optional callback function to receive the ID assigned to the listener. The listener ID is used to remove the listener from the event.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">eventName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">remove</span><span class="p">(</span><span class="nx">listenerID</span><span class="p">);</span>
</code></pre></div>
<h4>children</h4>
<p>A component can be written as a JavaScript object in the following format.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">component</span> <span class="o">=</span> <span class="p">{</span>
<span class="kr">extends</span><span class="o">:</span> <span class="s2">"http://vwf.example.com/path/to/prototype.vwf"</span><span class="p">,</span>
<span class="kr">implements</span><span class="o">:</span> <span class="p">[</span><span class="s2">"http://vwf.example.com/path/to/behavior.vwf"</span><span class="p">],</span>
<span class="nx">properties</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">aProperty</span><span class="o">:</span> <span class="nx">value</span>
<span class="p">},</span>
<span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">aMethod</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">parameter</span><span class="p">,</span> <span class="p">...</span> <span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">},</span>
<span class="nx">anotherMethod</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">parameter</span><span class="p">,</span> <span class="p">...</span> <span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="p">},</span>
<span class="nx">events</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">anEvent</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">},</span>
<span class="nx">anotherEvent</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="p">},</span>
<span class="nx">children</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">childFromURI</span><span class="o">:</span> <span class="s2">"http://vwf.example.com/path/to/component.vwf"</span><span class="p">,</span>
<span class="nx">childFromDescriptor</span><span class="o">:</span> <span class="p">{</span>
<span class="kr">extends</span><span class="o">:</span> <span class="s2">"http://vwf.example.com/path/to/component.vwf"</span><span class="p">,</span>
<span class="nx">properties</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">something</span><span class="o">:</span> <span class="s2">"value"</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="nx">scripts</span><span class="o">:</span> <span class="p">[</span> <span class="s2">"this.aFunction = function() { ... }"</span><span class="p">]</span>
<span class="p">};</span>
</code></pre></div>
<p>From inside an existing node, the new component can be created using the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"componentName"</span><span class="p">,</span> <span class="nx">component</span><span class="p">);</span>
</code></pre></div>
<p>The first argument is the name of the new component to be created, and the second is the JavaScript object for the component itself. The new component will be created as a child of <code>this</code>, and will be treated the same as any other children that were already present.</p>
<p>Children can also be deleted. The delete function takes the JavaScript object of the child that will be deleted.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">component</span><span class="p">);</span>
</code></pre></div>
<h2><a name="cameras">Cameras</a></h2>
<p>The camera capability provides the users a viewpoint into the app. Every app automatically creates a camera as part of the scene. This camera can be accessed in javascript through the <code>camera</code> property of the scene node, or through the editor. </p>
<hr>
<h3>Creating New Cameras</h3>
<p>New cameras can be created by creating a node that extends <code>http://vwf.example.com/camera.vwf</code>. </p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">newCamera</span> <span class="o">=</span> <span class="p">{</span>
<span class="kr">extends</span><span class="o">:</span> <span class="s2">"http://vwf.example.com/camera.vwf"</span>
<span class="p">};</span>
<span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="s2">"newCamera"</span><span class="p">,</span> <span class="nx">newCamera</span><span class="p">);</span>
</code></pre></div>
<p>See <a href="#components">components</a> for more information about creating new nodes.</p>
<hr>
<h3>Camera Type</h3>
<p>The <code>cameraType</code> property controls whether the camera is a <em>persepective</em> or <em>orthographic</em> camera. With a perspective camera, the further away an object is, the smaller it will appear. Orthographic cameras always display objects as their actual size. <code>cameraType</code> defaults to <em>perspective</em> and can be set using the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">cameraType</span> <span class="o">=</span> <span class="s2">"orthographic"</span><span class="p">;</span>
</code></pre></div>
<hr>
<h3>Transform Properties</h3>
<p>The camera component extends from node3, and inherits the transform properties, such as translation and rotation. </p>
<p>The <code>translation</code> property controls the position of the camera. Changing this property will move the camera to the new coordinates, and the view will automatically update with it. <code>translation</code> defaults to [ 0, 0, 0 ] and can be set using the following syntax. The coordinate system defaults to +x to the right, +y forward, and +z up, if no rotation has been applied.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="c1">// Moves the camera to 100 on the x-axis, -20 on the y-axis, and 30 on the z-axis</span>
<span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">translation</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">100</span><span class="p">,</span> <span class="o">-</span><span class="mi">20</span><span class="p">,</span> <span class="mi">30</span> <span class="p">];</span>
</code></pre></div>
<p>The <code>rotation</code> property controls the direction the camera is pointing, as an offset from the default orientation. Changing this property will rotate the camera and automatically update the view. The value takes the from of [ x, y, z, angle ] where the amount rotation around an axis is axis * angle. </p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">rotation</span> <span class="o">=</span> <span class="p">[</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">,</span> <span class="mi">90</span> <span class="p">];</span>
<span class="c1">// From looking down the positive y-axis, rotate 90 degrees </span>
<span class="c1">// around the x-axis, rotation 180 degrees around the y-axis </span>
<span class="c1">// and 45 degrees around the z-axis.</span>
</code></pre></div>
<p>Note that the x, y and z values in the rotation array are automatically normalized to a unit vector. So after the above example, reading the value of <code>rotation</code> would return [ 0.4364357888698578, 0.8728715777397156, 0.21821792423725128, 90 ].</p>
<hr>
<h3>Clipping Plane</h3>
<p>The <code>near</code> and <code>far</code> properties are used to control the clipping plane. <code>far</code> controls how far away from the camera another node can get before it is no longer displayed and <code>near</code> property controls how close to the camera another node can get before it is no longer displayed. The values of <code>near</code> and <code>far</code> are restricted so that 0 < <code>near</code> < <code>far</code>. They can be set with the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">far</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">near</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">;</span>
</code></pre></div>
<p><code>near</code> and <code>far</code> also control the view buffer. The ratio of <code>far / near</code> should roughly match the size of the world, in order to have accurate depth calculations and avoid overlapping models.</p>
<hr>
<h3>Lookat</h3>
<p>The <code>lookAt</code> property affects how the camera moves. If it is set to the id of another node, that node will always be at the center of the cameras view. If the position of the camera changes, the camera will automatically stay pointed at the other node. <code>lookAt</code> can only be set to a valid id, and defaults to "". It can be set using the following syntax.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">lookAt</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'interestingNode'</span><span class="p">].</span><span class="nx">id</span><span class="p">;</span>
</code></pre></div>
<hr>
<h3>Using Multiple Cameras</h3>
<p>The application uses the <code>activeCamera</code> property of the scene to determine which camera to use as the main viewpoint. Other cameras can be created, but they will not affect what is displayed in the browser unless they have been set as the active camera. Cameras in the model are shared by all clients, and <code>activeCamera</code> will be seen by all clients, unless they switch to a different one in their private view. Setting <code>activeCamera</code> to the id of a camera will automatically switch the view that is displayed in the browser to the view of that camera.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="c1">// this is the scene</span>
<span class="k">this</span><span class="p">.</span><span class="nx">activeCamera</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">children</span><span class="p">[</span><span class="s1">'newCamera'</span><span class="p">].</span><span class="nx">id</span><span class="p">;</span>
</code></pre></div>
<h2><a name="lights">Lights</a></h2>
<p>VWF provides control of lighting within an app or default lighting if none is specified. There are three basic light types that can be created within the framework. Each light has properties associated with it that can be manipulated, including attenuation, effects, and shadows. A complete list of light properties can be found under <a href="https://demo.virtual.wf/web/docs/jsdoc_cmp/symbols/light.vwf.html">light</a> in the <a href="#application-api">Application API</a>.</p>
<hr>
<h3>Light Types</h3>
<h4>Point</h4>
<p>A point light is represented by a point source in 3D space, and emits light in all directions. The closer an object is to the light source, the more illuminated it becomes.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">Omni1</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/light.vwf</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">lightType</span><span class="p-Indicator">:</span> <span class="s">"point"</span>
<span class="l-Scalar-Plain">translation</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span> <span class="nv">-150</span><span class="p-Indicator">,</span> <span class="nv">150</span><span class="p-Indicator">,</span> <span class="nv">150</span> <span class="p-Indicator">]</span>
</code></pre></div>
<h4>Directional</h4>
<p>Directional lights equally illuminate all objects from a given direction. An application should only have a small number of directional lights if needed, as computations for directional lights need to be done on all pixels on the screen. </p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">Dir1</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/light.vwf</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">lightType</span><span class="p-Indicator">:</span> <span class="s">"directional"</span>
<span class="l-Scalar-Plain">rotation</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span> <span class="nv">1</span><span class="p-Indicator">,</span> <span class="nv">0</span><span class="p-Indicator">,</span> <span class="nv">0</span><span class="p-Indicator">,</span> <span class="nv">-10</span> <span class="p-Indicator">]</span>
</code></pre></div>
<h4>Spot</h4>
<p>Spot lights emit light in a cone shape instead of a sphere. Other than that, spot lights and point lights share the similar properties. Spot lights also have the additional properties of <code>spotCosCutOff</code> and <code>spotExponent</code>, as described in the light API.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">Spot1</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">extends</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">http://vwf.example.com/light.vwf</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">lightType</span><span class="p-Indicator">:</span> <span class="s">"spot"</span>
<span class="l-Scalar-Plain">spotCosCutOff</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">0.95</span>
<span class="l-Scalar-Plain">spotExponent</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">10</span>
<span class="l-Scalar-Plain">translation</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span> <span class="nv">-150</span><span class="p-Indicator">,</span> <span class="nv">150</span><span class="p-Indicator">,</span> <span class="nv">150</span> <span class="p-Indicator">]</span>
</code></pre></div>
<hr>
<h3>Lighting Effects</h3>
<h4>Specular</h4>
<p>Specular reflection is the reflection of light from a surface where the ray is reflected in a single direction.</p>
<h4>Diffuse</h4>
<p>Diffuse reflection is the reflection of light from a surface where the ray is reflected at many angles.</p>
<h2><a name="prototypes">Prototypes</a></h2>
<p>Prototypes are the base component types for inheritance in the Virtual World Framework. A prototype has the same structure as a VWF <a href="#components">component</a>, and contains common properties, methods, and events. </p>
<p>A component can inherit from a prototype by using the <code>extends</code> keyword and specifying the URI of the prototype component. All behaviors, properties, methods, events, children and scripts are inherited by the component. </p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">extends: http://vwf.example.com/path/to/prototype.vwf
</code></pre></div>
<p>The default values for properties are defined in the prototype file. These properties can be overridden in the component definition file, or left alone to keep the default value. The same is true for methods and events, which can be extended in the component definition. </p>
<p>The default prototype for all components is <code>http://vwf.example.com/node.vwf</code>.</p>
<p>Prototypes can be housed on any server, and any URI passed to the extends keyword. Common VWF prototypes use a URI of <code>vwf.example.com</code>.</p>
<h4>Common Prototypes</h4>
<ul>
<li><code>node2.vwf</code> - base type for 2D components</li>
<li><code>node3.vwf</code> - base type for 3D components</li>
<li><code>camera.vwf</code> - base type for cameras</li>
<li><code>light.vwf</code> - base type for lights</li>
<li><code>material.vwf</code> - base type for materials</li>
<li><code>scene.vwf</code> - base type for a scene</li>
</ul>
<p>The <a href="#application-api">Application API</a> covers the complete list of VWF prototypes and their property, method, and event definitions.</p>
<h2><a name="behaviors">Behaviors</a></h2>
<p>A behavior is a component that is used to add functionality to another component. It is referenced from a seperate file, allowing multiple components to reuse the same behavior. To use a behavior, add an <code>implements</code> section to the component with the URI to the behavior.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/behavior.vwf</span>
</code></pre></div>
<p>When a behavior is loaded, all behaviors, properties, methods, events, children and scripts are inherited by the new component. All the inherited functionality can be used as part of the component. Behaviors can also use properties from the component that implement the behavior. For example, in this behavior, <code>someMethod</code> will perform an action based on the value of <code>behavior-someProperty</code>, which defaults to true. The convention for properties from the behavior is to prefix the property name with the name of the behavior, to avoid accidently overriding the value with a property from the implementing component.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">behavior-someProperty</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
<span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">someMethod</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
<span class="no">if(this.behavior-someProperty && this.anotherProperty) {</span>
<span class="no">// Do something</span>
<span class="no">}</span>
<span class="no">else {</span>
<span class="no">// Do something else</span>
<span class="no">}</span>
</code></pre></div>
<p><code>anotherProperty</code> is defined in the implementing component, but is still usable in the behavior. If the component that is implementing the behavior needs <code>behavior-someProperty</code> to be false, it simply overrides the value in its own properties. </p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">implements</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">http://vwf.example.com/path/to/behavior.vwf</span>
<span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">behavior-someProperty</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">false</span>
<span class="l-Scalar-Plain">anotherProperty</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
<span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">this.doSomething = function() {</span>
<span class="no">this.someMethod();</span>
<span class="no">}</span>
</code></pre></div>
<p>When <code>someMethod</code> executes, it will read the overridden value of <code>behavior-someProperty</code>, and go into the else statement.</p>
<h2><a name="animations">Animations</a></h2>
<h3>Animation Behavior</h3>
<p>The primary way to accomplish animations in VWF is the animation behavior. All components that extend node3 automatically implement the animation behavior, which provides standardized methods and properties for creating and executing an animation. </p>
<p>In order to create an animation on a node, the <code>animationUpdate</code> method needs to be implemented. This method is called each time the animation time changes, and is used to update the node to the correct state for that time.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">scripts</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="p-Indicator">|</span>
<span class="no">this.animationUpdate = function(time, duration) {</span>
<span class="no">// Animate the node. For example, update the translation based on the time</span>
<span class="no">this.translateBy([0, 0, 1 * time], 0);</span>
<span class="no">}</span>
</code></pre></div>
<p>The animation can then be started by calling the <code>animationPlay</code> method and stopped by calling <code>animationStop</code>.</p>
<p>Common properties used to customize the animation include:</p>
<ul>
<li><code>animationDuration</code> - The length of the animation</li>
<li><code>animationRate</code> - The animation playback rate</li>
<li><code>animationLoop</code> - Whether or not the animation should replay after reaching the end</li>
</ul>
<p>A full list of methods and properties can be found under <a href="https://demo.virtual.wf/web/docs/jsdoc_cmp/symbols/animation.vwf.html">animation</a> in the <a href="#application-api">Application API</a>.</p>
<hr>
<h3>Collada Animations</h3>
<p>Animations defined in the collada document will also be loaded and available to the framework. They are controlled the same way as animations created in a component, except there is no need to implement an <code>animationUpdate</code> method, since the animation information is pulled from the collada file.</p>
<p>Common properties used to customize collada animations include:</p>
<ul>
<li><code>animationStartTime</code> - The time the animation should start at. Used to play a subsection of the animation.</li>
<li><code>animationStopTime</code> - The time the animation should stop at. Used to play a subsection of the animation.</li>
<li><code>animationStartFrame</code> - Equivalent to animationStartTime, but in frames, instead of seconds.</li>
<li><code>animationStopFrame</code> - Equivalent to animationStopTime, but in frames, instead of seconds.</li>
<li><code>fps</code> - The frames per second the animation should play at.</li>
</ul>
<hr>
<h3>Future Call</h3>
<p>Animations can also be created using the future call. The VWF future call can be used to run a method at a specified time in the future. This call can be inserted into the method call chain, and a parameter passed with an amount of time from the current point for when the method should be called. An example of the future call is shown below. </p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="l-Scalar-Plain">methods</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">methodName</span><span class="p-Indicator">:</span> <span class="p-Indicator">|</span>
<span class="no">if( criteriaMet )</span>
<span class="no">{</span>
<span class="no">doSomething();</span>
<span class="no">this.future( 0.05 ).methodName();</span>
<span class="no">}</span>
</code></pre></div>
<p>The future call schedules the next step. The parameter passed to the function call can be raised or lowered to smooth or optimize the animation, respectively.</p>
<p>Future calls may also be used for property assignment or to fire an event at a given time in the future.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="k">this</span><span class="p">.</span><span class="nx">future</span><span class="p">.</span><span class="nx">eventName</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">future</span><span class="p">.</span><span class="nx">propertyName</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
</code></pre></div>
<h2><a name="html">HTML Overlays</a></h2>
<p>Two dimensional components may be added to any application via HTML. When an application loads, the framework automatically looks for an HTML file of the same name. For instance, if your application is entitled <code><i>application</i>.vwf.yaml</code>, VWF will look for a file in the same directory called <code><i>application</i>.vwf.html</code>. This HTML is of a standard format, and can, in fact, be loaded standalone in a browser. </p>
<p>A few additions to the file can attach the 2D content as an overlay directly over the VWF view, and scripts can be added to attach the HTML content to the application pieces itself. </p>
<hr>
<h3>Overlay HTML Content</h3>
<p>The first step is to create the HTML content as you'd like it to appear on the screen. In the example below, everything contained within the first div can stand alone as it's own HTML file, with standard css rules applied.</p>
<div class="highlight"><pre><code class="html language-html" data-lang="html"><span class="nt"><body></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"wrapper"</span> <span class="na">class=</span><span class="s">"wrapper"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"toolstyle"</span> <span class="na">id=</span><span class="s">"toolbar"</span><span class="nt">></span>
<span class="nt"><img</span> <span class="na">id=</span><span class="s">"icon1"</span> <span class="na">src=</span><span class="s">"images/icon1.png"</span> <span class="na">style=</span><span class="s">"border:3px solid red"</span> <span class="na">alt=</span><span class="s">"icon1"</span>
<span class="na">onclick=</span><span class="s">"setMode('mode1')"</span><span class="nt">/></span>
<span class="nt"><img</span> <span class="na">id=</span><span class="s">"icon2"</span> <span class="na">src=</span><span class="s">"images/icon2.png"</span> <span class="na">style=</span><span class="s">"border:2px solid black"</span> <span class="na">alt=</span><span class="s">"icon2"</span>
<span class="na">onclick=</span><span class="s">"setMode('mode2')"</span><span class="nt">/></span>
<span class="nt"></div></span>
<span class="nt"></div></span>
<span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">></span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'#wrapper'</span><span class="p">).</span><span class="nx">appendTo</span><span class="p">(</span><span class="s1">'#vwf-root'</span><span class="p">);</span>
<span class="nt"></script></span>
<span class="nt"></body></span>
</code></pre></div>
<p>In order to attach the content as an overlay to the application, we've added an additonal script tag, that appends the <code>wrapper</code> div to <code>vwf-root</code>, or the main application view. </p>
<p><strong>Note</strong>: The loader strips out header and body tags and inserts content directly into index.html. HTML5 formatting is helpful for testing as a standalone webpage, but not required for VWF. </p>
<hr>
<h3>Allow HTML to Monitor and Change the Simulation State</h3>
<p>The HTML has access to the VWF application models through <code>vwf_view</code>. Thus, the HTML can watch what happens within the simulation and make changes to it such as setting properties, calling methods, and firing events. </p>
<p>The <code>vwf.api.kernel</code> in the <a href="#system-api">system API</a> contains a full list of possible kernel calls that can be made from the view (.html).</p>
<p>The following sections show examples of how to do just that. Refer to <a href="#querying">querying</a> for more information about obtaining node IDs to pass to the following functions.</p>
<hr>
<h3>Allow HTML to Set Application Properties</h3>
<p>Properties of the application or of specific nodes may be set directly in the javascript of an HTML file. In order to set a property, the following syntax should be used. </p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">setProperty</span><span class="p">(</span><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">application</span><span class="p">(),</span> <span class="s2">"property1"</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
</code></pre></div>
<p>The first argument is the ID of the node containing the given property. In this case, the property is on the application itself, and uses the function call for the root node of the application. The second parameter is the name of the property to set, and the third argument is the value to be passed to the specified property. </p>
<hr>
<h3>Allow HTML to Call Application Methods</h3>
<p>Application methods can be called directly from the HTML, with or without parameters. In order to call a method, the following syntax should be used.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">callMethod</span><span class="p">(</span><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="kc">undefined</span><span class="p">,</span> <span class="s2">"/nodeName"</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">"method1"</span><span class="p">);</span>
</code></pre></div>
<p>The first argument is the ID of the node where the method resides. In this case, the ID is found using the <a href="#querying">find</a> function call passing in the name of the node. The second parameter is the name of the method as defined in the main application file. In order to pass parameters directly to the method call, a third parameter may be passed as an array of values. </p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">callMethod</span><span class="p">(</span><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="kc">undefined</span><span class="p">,</span> <span class="s2">"/nodeName"</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">"method1"</span><span class="p">,</span> <span class="p">[</span> <span class="nx">parameter1</span><span class="p">,</span> <span class="nx">parameter2</span><span class="p">,</span> <span class="nx">etc</span> <span class="p">]);</span>
</code></pre></div>
<hr>
<h3>Allow HTML to Create Components</h3>
<p>New components can also be created from the HTML. In order to create a node, the following syntax should be used.</p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">createChild</span><span class="p">(</span><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">application</span><span class="p">(),</span> <span class="s2">"componentName"</span><span class="p">,</span> <span class="nx">component</span><span class="p">,</span> <span class="kc">undefined</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span>
</code></pre></div>
<p>The first argument is the ID of the node that will be the parent of the new component. The second argument is the name of the new component, and the third is the JavaScript object defining the new component. The final argument is optional, and is a function that will be called after the new component has been created. Note the callback is not
currently functional.</p>
<hr>
<h3>Monitor the Simulation to Manipulate HTML</h3>
<p>HTML can reflect changes to the simulation as they occur. These changes can include property updates, method calls, or event fires. The following example allows the HTML to be notified of property changes in the simulation. </p>
<div class="highlight"><pre><code class="javascript language-javascript" data-lang="javascript"><span class="nx">vwf_view</span><span class="p">.</span><span class="nx">satProperty</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">nodeId</span><span class="p">,</span> <span class="nx">propertyName</span><span class="p">,</span> <span class="nx">propertyValue</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">nodeId</span> <span class="o">==</span> <span class="nx">vwf_view</span><span class="p">.</span><span class="nx">kernel</span><span class="p">.</span><span class="nx">application</span><span class="p">()</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nx">propertyName</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="s2">"mouseMode"</span><span class="o">:</span>
<span class="nx">doSomething</span><span class="p">(</span> <span class="nx">propertyValue</span> <span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>In this case, any time a property has been set, this function will check to see if the property was changed on a specific node, and if so, will check the name of the property. If found, javascript can then be performed to update the HTML state.</p>
<p>Similarly, the HTML can monitor other types of application updates as well. A few common ones are listed below.</p>
<ul>
<li>Node created - <code>vwf_view.createdNode = function ...</code></li>
<li>Node deleted - <code>vwf_view.deletedNode = function ...</code></li>
<li>Method called - <code>vwf_view.calledMethod = function ...</code></li>
<li>Event fired - <code>vwf_view.firedEvent = function ...</code></li>
</ul>
<p>The <code>vwf.api.view</code> in the <a href="#system-api">system API</a> contains a full list of view driver calls.</p>
<h2><a name="drivers">Drivers</a></h2>
<p>We've discussed how to write an application using the framework. The next section describes how the system works, and how to reconfigure the system to accomplish more complex tasks. The drivers of the system are the things that connect components to the 3D visualization and the user interaction that you see. </p>
<p>The drivers define the autonomic actions that happen within a system, dividing responsibility and delegating work for each action of the system. These actions include things such as creating or deleting a node, getting or setting a property, calling methods, and firing events. The drivers stand side by side without direct interaction between them. Rather, they interact by autonomic actions that the kernel manages. </p>
<p>For example, the three.js driver is responsible for any manipulation on the node that's part of the scene, like setting the translation of a node. This information may be ignored by the rest of the drivers if it is not needed. </p>
<p>Model and view drivers have the same structure; however, the model driver doesn't reach out, and a view driver does not have direct control. </p>
<h3>Configuring Drivers for an Application</h3>
<p>An application allows for both its model and view drivers to be selected and activated via a configuration file. This system will look for a config file with the same base name as the application being loaded. For instance, <code>application.vwf</code> will search for and attempt to load a config file entitled <code>application.vwf.config.yaml</code>.</p>
<p>Within the configuration, both model and view drivers may be defined within the <code>model:</code> or <code>view:</code> tag, using the path to the driver file, as shown below. </p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">model</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">vwf/model/threejs</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">view</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">vwf/view/threejs</span><span class="p-Indicator">:</span> <span class="s">"#vwf-root"</span>
<span class="l-Scalar-Plain">vwf/view/lesson</span><span class="p-Indicator">:</span>
</code></pre></div>
<p>For drivers that require parameters, such as the renderer view driver that requires the correct HTML element ID, these can be passed in one of two ways. If there is only one parameter, it can be passed in as shown above to the right of the colon: <code>"#vwf-root"</code>. Alternatively, the parameter name may also be explicitly listed as defined below.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">view</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">vwf/view/glge</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">application-root</span><span class="p-Indicator">:</span> <span class="s">"#vwf-root"</span>
</code></pre></div>
<hr>
<h3>Default Drivers</h3>
<p>By default, the following drivers are active:</p>
<ul>
<li>Threejs (vwf/model/threejs, vwf/view/threejs)</li>
<li>Javascript (vwf/model/javscript)</li>
<li>Object (vwf/model/object)</li>
<li>Document (vwf/view/document)</li>
</ul>
<p>Alternative driver options also include:</p>
<ul>
<li>Editor (vwf/view/editor)</li>
<li>GLGE (vwf/model/glge, vwf/view/glge)</li>
<li>JigLib (vwf/model/jiblib)</li>
<li>Cesium (vwf/model/cesium, vwf/view/cesium)</li>
<li>Google Earth (vwf/view/google-earth)</li>
<li>Lesson (vwf/view/lesson)</li>
<li>WebRTC (vwf/view/webrtc)</li>
</ul>
<p>For 2D applications, or any application where the default drivers are not necessary, the keyword <code>nodriver</code> may be used. For example, in <em>tile-puzzle-2D</em>, a WebGL renderer is not required, and thus uses the following configuration:</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">model</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">nodriver</span><span class="p-Indicator">:</span>
</code></pre></div>
<hr>
<h3>Additional Information</h3>
<p>In addition to defining the driver configuration for your application, the <code>config.yaml</code> file also allows you to set some additional information: an HTML title for the page. The following example configuration will set the title to the specified value, rather than the default <em>Virtual World Framework.</em></p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>
<span class="l-Scalar-Plain">info</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">title</span><span class="p-Indicator">:</span> <span class="s">"My</span><span class="nv"> </span><span class="s">New</span><span class="nv"> </span><span class="s">VWF</span><span class="nv"> </span><span class="s">Application"</span>
</code></pre></div>
<hr>
<h3>Passing Configuration Parameters in URL</h3>
<p>An alternative option to using the <code>config.yaml</code> file is to pass in driver parameters via the URL. </p>
<p>For instance, the Google Earth view driver may be loaded in an application without a configuration file:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">https://demo.virtual.wf/earth/#!google-earth
</code></pre></div>
<p>Both a model and a view driver may be loaded in an application with the following URL:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">https://demo.virtual.wf/humvee/?threejs#!threejs
</code></pre></div>
<p>Parameters may also be passed in via the URL. The following example passes in parameters for the application root and setting the pick interval:</p>
<div class="highlight"><pre><code class="text language-text" data-lang="text">https://demo.virtual.wf/sandtable/?threejs#!threejs={"application-root":"#vwf-root","experimental-pick-interval":50}
</code></pre></div>
<p><strong>Note</strong>: The URL takes precedence and will override anything defined via the configuration file.</p>
<h2><a name="editor">Editor</a></h2>
<p>The editor capability of VWF allows for the app to be edited in a live environment. It provides full control to the user and has the ability to navigate through the current state of the app, consisting of its various nodes and properties. The editor allows changes to be made to the shared simulation by setting properties, calling methods, and firing events. </p>
<hr>
<h3>Opening the Editor</h3>
<p>The editor is not enabled by default. The app's config file can be updated to include the editor interface under the <code>view:</code> tag. Additionally, the threejs model and view drivers must be added, as adding just the editor will override the default drivers. An example configuration is below.</p>
<div class="highlight"><pre><code class="yaml language-yaml" data-lang="yaml"><span class="nn">---</span>