Graphics.EDGE3dTVTutorial - lordmundi/wikidoctest GitHub Wiki

EDGE 3D TV Tutorial

« Render A Poster From EDGE | EDGE User’s Guide | Example Driving of Planets with Recorded Data »

This is a page that will attempt to explain how to get stereo EDGE graphics on a 3D TV set. This can be done with most 3D TVs (passive or active) as long as they support a mode which will take a split-screen signal and combine it into a stereo pair (which most should). Most 3D TVs should have a 3D button or something similar on the remote which should let you pick from multiple split screen setups. In this tutorial, we will use a vertical orientation with a top and bottom view that the TV will combine into stereo.

The first thing to do is define a DISPLAY context in your userdata which has a viewport for the top and bottom views. We want to get a view setup that looks like the following:

EDGE Splitscreen

To do this, let's first make a new userdata directory from the template delivered with EDGE and call it "userdata.3dtv_test":

> cp -a userdata userdata.3dtv_test

Now that we have a userdata directory to mess around in, let's edit the user.cfg and make our display context. The easiest way to do this is to copy the ENG_GRAPHICS context that we default to in cev.cfg. Here is my full display context after redefining the viewports to give me the split screen above. I defined this right after the ENG_GRAPHICS context in user.cfg:

3DTV
        {
            DOUG
            {
                 TCL
                 {
                     cev_plume_init  "${GUI_HOME}/cev_plume_init.tcl"
                     cev_plume_drive "${GUI_HOME}/cev_plume_drive.tcl"
                 }

                 GUI
                 {
                     lightsoff       "${GUI_HOME}/lightsoff.tcl"
                     #disp            "${GUI_HOME}/multidisp.tcl"
                     #camtargets      "${GUI_HOME}/cam_targets_rel.tcl"
                     animate         "${GUI_HOME}/animate.tcl"
                     #simdata         "${GUI_HOME}/simdatadlg.tcl"
                     keycuecard      "${GUI_HOME}/keycuecard_cev.tcl"
                     #dyn_ov          "${GUI_HOME}/dynamic_overlays.tcl"
                     #cev_ovl         "${GUI_HOME}/cev_overlay_comm.tcl"
                     #cev_ovl_menu    "${GUI_HOME}/cev_overlay_menu.tcl"
                     #trails          "${GUI_HOME}/trails.tcl"
                     speedfly        "${GUI_HOME}/speedfly.tcl"
                     fix_ideal_light "${GUI_HOME}/fix_ideal_light.tcl"
                     camdata         "${GUI_HOME}/camera_data_overlay.tcl"
                     #doug_config     "${GUI_HOME}/doug_config.tcl"
                     eyesep          "${USERDATA}/gui/change_eye_seperation.tcl"
                     blipper         ""
                     camdata_toggle  "${USERDATA}/gui/camera_overlay_toggle.tcl"
                }
            }

            command_line
            {
                -plugin cctv        '-nofocusdraw -nofocus'
                -plugin canvas      '-dir "${DOUG_HOME}/fonts" -default arial'
                -plugin dcanvas     '-image_objs 1'
                -plugin ideal       '-node IDEAL_LIGHTING'
                -plugin script      '-input "${RECONFIG_FILE}"'
            }

            plugins
            {
                #flycam          dsp_flycam
                cctv            dsp_cctv
                ideal           dsp_ideal
                canvas          dsp_canvas
                dcanvas         dsp_drawcanvas
                simdata         dsp_simdata
                jpeg            dsp_jpegsave
                #timer           dsp_timeit
                record          dsp_record
                trail           dsp_trail
                #noise           dsp_noise
            }

            channel1
            {
                view.TOP  LeftEye    perspective( 40.9, 1.333, 4.0, 1000000000000.0 ); xywh( 0, 240, 640, 240 ); attribs(CAMINFO);
                view.BOTTOM    RightEye    perspective( 40.9, 1.333, 4.0, 1000000000000.0 ); xywh( 0, 0, 640, 240 ); attribs(CAMINFO);
            }
        }

Now, obviously the important part here is the two view lines in the channel specification. This makes two views - one on top and one on bottom. Notice that the aspect ratio defined (1.333) isn't what you would calculate if you divide the width by the height, because in this case, the 3D TV will be stretching both images to be fullscreen on the TV, so we want the aspect ratio to use double the height of the view (480). Not that this width and height is just important to set the initial window size and also figure out the aspect of the images - if we run fullscreen, the window will take the shape of the display and the views will adjust accordingly.

You'll notice that the views default to two cameras called "LeftEye" and "RightEye". Let's go ahead and make those cameras. Edit your configs/user_models.cfg and add in the following to the top CAMERAS block (i.e., "DSP_CONFIG→DATA→SCENE_LOAD→CAMERAS"):

...
                node(LeftEye); xyz(-2613.4251 -997.3266 -11.3556); pyr(2.0899 -2.4377 -0.1274); parent( JimboCam );
                node(RightEye); xyz(0, 20, 0); parent( LeftEye );
...

This positions the LeftEye camera in some random position, and then puts the RightEye camera 20 inches to the right of it. Note that this 20 inches in the eye separation, so this means we are exaggerating the eye separation considerably so as to exaggerate the 3D effect of the station. Otherwise, you would have to be extremely close to the model to see a difference in the left and right views. With an exaggerated eye separation, we are aiming to produce a 3D effect at a distance, as if it were a small toy being rotated in the TV. Feel free to adjust this eye separation to suit your needs. We will add a script later to make it configurable at runtime.

Now that we have a display context and cameras for the viewports, let's make a script to run it. I like to put my userdata specific scripts in the userdata itself so I know where to look for them. Inside the userdata.3dtv_test directory, make the following startup script called "run_3dtv.csh":

#!/bin/csh -f
setenv USERDATA ${PWD}

cd ${EDGE_HOME}
./run_graphics -mode standalone -display 3DTV $*

Running that script, you should see a display similar to the image above (although you may need to run "chmod +x run_3dtv.csh" first to make it executable).

Now that we can run with a split screen, we now need to get rid of the border so that the views take up the entire TV. We will also want to run fullscreen.

Starting with EDGE v2.4, you can use the new method for running fullscreen described here: Graphics.RunningFullscreen

If you don't mind right-clicking and toggling on fullscreen manually, you can simply use the right click menu to do it. If you want the settings correct at init, then you can add the small scripts in that article to a tcl script in your context and it will make the view fullscreen with no window border and hide the menu.

Optional updates

One thing you may want to add is the ability to dynamically adjust the eye separation. Since the cameras are just positioned as nodes in the scene, this script just needs to bump the right eye over in reaction to a keypress. To do this, create a script called "change_eye_separation.tcl" in userdata.3dtv_test/gui with the following contents:

global dougmain

bind $dougmain <KeyRelease-bracketleft> {
        set sep [doug.node RightEye get -y]
        doug.node RightEye set -y [expr $sep - 1]
        puts "Eye Sep is now [expr $sep - 1]"
}

bind $dougmain <KeyRelease-bracketright> {
        set sep [doug.node RightEye get -y]
        doug.node RightEye set -y [expr $sep + 1]
        puts "Eye Sep is now [expr $sep + 1]"
}

set my_fullscr_win [doug.display get -main_window]
focus -force $my_fullscr_win
update

That will let the bracket keys ("[" and "]") adjust the eye seperation in one inch increments. To use it, add it to the GUI block of the 3DTV_NOVISUAL display context as you did with the other scripts.

Another optional update is to create a script which will spin the station around and enhance the 3d effect so that your viewers can see a spinning ISS in front of them. To do this, create a script called "spinstation.tcl" in the userdata.3dtv_test directory as follows:

proc spinstation { } {

        set node "SSREF"
        #set pitch [expr [doug.node $node get -pitch] + 0.05]
        set yaw   [expr [doug.node $node get -yaw]   - 0.24]
        #set roll  [expr [doug.node $node get -roll]  - 0.12]

        #doug.node $node set -pitch $pitch -roll $roll -yaw $yaw
        doug.node $node set -yaw $yaw
}


proc setup_spinstation { } {
    doug.node LeftEye set -parent "NULL"
    update
    doug.callback add redraw "spinstation"

    doug.plugin dsp_speedtest3.environment set -enabled 1
    doug.plugin dsp_speedtest3.shadow set -enabled 1
    doug.plugin dsp_speedtest3.bloom set -enabled 1
    doug.plugin dsp_speedtest3.ambocc set -enabled 0
}

doug.callback add timer -delay 0.5 -autoreset 0 setup_spinstation

Similarly to others, add it to the GUI block in the user.cfg.

« Render A Poster From EDGE | EDGE User’s Guide | Example Driving of Planets with Recorded Data »