[sci.virtual-worlds] 5D Design: Part 4 of 4

thinman@netcom.com (Lance Norskog) (04/22/91)

                                  - 50 -

































































                                  - 51 -



       9.  _5_D__L_i_b_r_a_r_y

       Every deck includes a large library of pre-defined trees
       which do a variety of basic operations:  2D bitmaps, text,
       sample objects, colors, & textures, etc.  The library trees
       are assigned a pre-defined block of IDs.  5D program and
       tree authors may always assume these classes are available,
       as well as the primitive class library.  The following trees
       are from the core tree library, and are a sample of simple
       5D tree composition.

       9.0.1  _F_l_o_a_t_i_n_g__P_i_x_m_a_p_
       The Floating Pixmap is a 2D pixmap which should not be sub-
       or super-sampled, and instead should only be seen at a fixed
       size and place.  It sets its 2D bounding box to force this
       to occur.  This might be used for system status messages.


       ( class
           ID='Floating Pixmap'
           super=Painted
           ( method
               name=Float
               ( template
                   (ID=Pix type=Pixmap)
                   (ID=Frame type=Drawable)
                   (ID=Place type=Box)
               )
               ( rewrite
                   type=Void
                   / Set screen box to force placement on screen
                   ( property
                       name=screenbox
                       value=Place
                   )
                   / If the sizes of the pixmap and the frame are
                   / mis-matched, an exception will be raised,
                   / so don't bother checking them here.
                   Apply(Pix, Frame)
               )
           )
       )

       Notes:

          +o Obviously, the Floating Pixmap would only be invoked
            during a screen refresh.  As a defined tree, the
            Floating Pixmap inherits the evaluation frequency
            property at invocation time.  Setting the evaluation
            frequency would make no sense.












                                  - 52 -



          +o The core library is assumed to be pre-loaded in the
            deck, and its members are referred to by standardized
            code numbers.  However, since Floating Pixmaps can be
            described in 5D, they belong in the core library, not
            the language specification.

          +o A fixed-size pixmap will be legible anywhere on the
            screen.  Since its placement is a 2D graphics decision,
            that is left up to the invoker.

       9.0.2  _S_t_e_r_e_o__F_l_o_a_t_i_n_g__P_i_x_m_a_p
       The Stereo Floating Pixmap object uses two instances of the
       Floating Pixmap object to create a stereo image in a fixed
       size and place on the screen.  Random sub- or super-sampling
       the left and right frames of a stereo image would give your
       visual system severe grief, so the Floating Pixmap library
       routine is the appropriate choice.  The stereo input pixmaps
       may be produced with a ray-tracer or stereo video pairs.


       ( class
           ID='Stereo Floating Pixmap'
           super='Floating Pixmap'

           ( method
               name=Float
               ( template
               (ID=PixLeft type=Pixmap)
               (ID=PixRight type=Pixmap)
               (ID=Frame type=Drawable)
               (ID=Place type=Box)
               )
               ( rewrite
                   type=Void
               / Set screen box, which forces placement on screen
               ( property
                   name=screenbox
                   value=Place
               )
               / Type of cond is VOID, so can't do cond(left, pix, pix)
               cond(LeftEye,
                   Apply(PixLeft, Frame),
                   Apply(PixRight, Frame))
               )
           )
       )

       Notes:

          +o The Stereo Floating Pixmap needs two input bitmaps, and
            the size and placement to use for the maps.  It uses











                                  - 53 -



            the intrinsic boolean variable left_eye to decide
            whether to invoke the Floating Pixmap object on the
            left or right eye image.  Again, the object should only
            be invoked during a retrace event.

          +o With video-in-a-window, you could do this with live
            stereo pairs.

       9.0.3  _S_o_u_n_d__s_a_m_p_l_e__a_t_t_a_c_h_e_d__t_o__o_b_j_e_c_t
       This class definition plays a continuously cycled sound
       sample or synthesizer patch.  It adjusts the volume to your
       distance from it.  This is usually part of a larger object.


       ( class
           ID='Positioned Sound'
           super=SoundChannel

           ( property
               name=Volume
               (
                   type=Number
                   distance((property name=Position type=Point),
                       EyePoint type=Point)
               )
           )

           ( property
               name=execute
               value=True
           )

       )

       Notes:

          +o The actual format of sound samples and instrument
            definitions is very deck-dependent.  Low-end PC sound
            boards have a bunch of oscillators.  They allow you to
            set a bunch of registers for instrument X out of 10,
            and then leave it alone.  Higher-end gear requires
            generating sound samples on the fly and feeding them to
            DMA channels.  The very desirable ability to have
            high-level definitions of several simultaneous sound
            channels making iconic sounds (a FWOOOSH when you grab
            something, a TINK when you hit something metal) is thus
            much easier on PC's than workstations.  On the other
            hand, we need to go to more sophisticated hardware to
            get stereo or 3D sound placement.  There has been work
            on doing 2D placement with Midi.  [Computer Music
            Journal, Feb. 1991, pp. 59] Midi I/O is available for











                                  - 54 -



            all desktop PC's; this is an obvious direction for
            research.

       9.0.4  _F_l_i_p_-_F_l_o_p
       The flip-flop uses feedback to create a simple 1-bit memory
       of past inputs.

       9.0.5  _S_o_f_t_w_a_r_e__P_h_a_s_e_-_L_o_c_k_e_d__L_o_o_p
       The phase-locked loop is a key circuit used in interfacing
       analog and digital circuitry.  The Synthesis operating
       system [ref: Columbia University Technical Report] uses a
       software implementation of a PLL as its scheduler.  Software
       PLLs provide a simple, fast system that responds to external
       rhythms.  A software PLL can interface real-time output to a
       user's work rhythm, and gives a powerful tool for making the
       user interface controlled by the user's time sense.

       It should be possible to interface the MIDI ports with the
       software PLL to do interesting drum machine stuff.

       9.0.6  _S_a_m_p_l_e__&__H_o_l_d
       Sample and hold an input value.  Whenever the input switch
       is true, sample the value.  Whenever the input value
       changes, sample the value.  Output the held value on demand.


                 ( class
                     ID='Sample and Hold'
                     super=Number
                     super=Boolean
                     ( data
                         / secret data sampled & held
                         ID=$Sample
                         type=Number
                     )



























                                  - 55 -



                     ( method
                         / grab data when boolean is true,
                         / and when number changes while boolean is true
                         ( template
                             name=Sample
                             type=Number
                             ( name=switch type=Boolean )
                             ( name=input type=Number)
                         )
                         ( rewrite
                             (cond
                                 (and
                                     (switch)
                                     (or
                                         (inputChange(switch))
                                         (inputChange(value))
                                     )
                                 )
                                 (set($Sample, input))
                                 ()  / else do nothing
                             )
                         )
                     )
                     ( method
                         ( template
                             name=Value
                         )
                         ( rewrite
                             type=Number
                             set(output, $Sample)
                         )
                     )
                 )

       The inputChange boolean operation is extremely useful for
       asynchronous operations such as Sample&Hold.  This class
       does not operate continuously, of course, but instead is
       driven by its inherited clock.
























                                  - 56 -



       10.  _5_D__S_a_m_p_l_e__P_r_o_g_r_a_m_s

       The following program is in severely abridged pidgin 5D for
       clarity.  It dates back to before the addition of objects to
       5D, but does give the flavor of 5D programming.

       10.1  _S_o_u_n_d__m_i_x_e_r

       This is a sample 5D program which implements a simple
       digital sound mixer.  It allows the user to record and play
       back 2 sound samples.

       top of world            / visible universe
       (
           / built-in boolean switch1          record channel 1
           / built-in boolean switch2          record channel 2
           / built-in boolean switch3          playback channel 1
           / built-in boolean switch4          playback channel 2
           / built-in boolean switch5          playback both channels
           call [
               property: evaluate when input changes
               evaluate [
                   property: evaluate never
                   dataset sample1 [
                       property: sound sample, 10 seconds long.
                   ]
                   dataset sample2 [
                       property: sound sample, 10 seconds long.
                   ]
               ]
               evalute [
                   property: evaluate in order         / concurrency control
                   conditional [
                       switch1
                       assign [                        / record sample 1
                           sample1
                           microphone
                       ]
                       null
                   ]
                   conditional [
                       switch2
                       assign [                        / play sample 1
                           sound channel 1
                           sample1
                       ]
                       null
                   ]
                   conditional [
                        switch3
                        assign [                       / record sample 2











                                  - 57 -



                            sample2
                            microphone
                        ]
                       null
                   ]
                   conditional [
                   switch4
                   assign [                            / play sample 2
                               sound channel 2
                               sample2
                           ]
                       null
                   ]
                   conditional [
                       switch5
                       evaluate [                      / mix both samples
                           property: evaluate simultaneously
                           assign [
                               sound channel 1
                               sample1
                           ]
                           assign [
                               sound channel 2
                               sample2
                           ]
                       ]
                       null                            / empty function
                   ]
               ]
           ]
       ]

       This example world has no graphics.  Five switches are used,
       one for each possible operation.  The property of sequenced
       evaluation of sub-trees is used to provide concurrency
       control; only one operation at a time may be used.  A tree
       which is never evaluated is used as a data holder for the
       two sound samples.  The following version uses nested
       conditionals:























                                  - 58 -



       top of world
       [
           / built-in boolean switch1;         record channel 1
           / built-in boolean switch2;         record channel 2
           / built-in boolean switch3;         playback channel 1
           / built-in boolean switch4;         playback channel 2
           / built-in boolean switch5;         playback both channels
           evaluate all [
           property: evaluate when input changes
               evaluate [
                   property: evaluate never
                   dataset sample1 [
                       property: sound sample, 10 seconds long.
                   ]
                   dataset sample2 [
                       property: sound sample, 10 seconds long.
                   ]
               ]
               conditional [
                   property: evaluate in order/ concurrency control
                   switch1
                   assign [                            / record sample 1
                       sample1
                       microphone
                   ]
                   conditional [
                       switch2
                       assign [                        / play sample 1
                           sound channel 1
                           sample1
                       ]
                       conditional [
                           switch3
                           assign [                    / record sample 2
                               sample2
                               microphone
                           ]
                           conditional [
                               switch4
                               assign [                / play sample 2
                                   sound channel 2
                                   sample2
                               ]
                               conditional [
                                   switch5
                                   evaluate [          / mix both samples
                                       property: evaluate simultaneously
                                       assign [
                                           sound channel 1
                                           sample1
                                       ]











                                  - 59 -



                                       assign [
                                           sound channel 2
                                           sample2
                                       ]
                                   ]
                                   null / empty tree
                               ]
                           ]
                       ]
                   ]
               ]
           ]
       ]

       Note that the version with nested conditionals still uses
       the sequential evaluation property.  Multi-processor systems
       can evaluate all 3 branches of a conditional expression
       concurrently, being careful that the false leg of the then-
       else pair leaves no permanent side effects.