BGE: stereoscopic settings changes: (1) eye separation is the UI (2) focallength...
authorDalai Felinto <dfelinto@gmail.com>
Tue, 29 Dec 2009 15:47:20 +0000 (15:47 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Tue, 29 Dec 2009 15:47:20 +0000 (15:47 +0000)
Now the default eye separation value is 0.10 (reasonable for games with 1 meter == 1 B.U.
The focallength used is the camera focal length (DOF settings). It allow you to even use different focal lengths for different scenes (good for UI)

In order to change it you can change the camera focal length or use Rasterizer.setFocalLength.
If you use the Rasterizer method it will use this value for all the cameras.

ToDo:
- Blenderplayer settings
- Update wiki documentation (any volunteer)?

* Note to stereo fans:
I don't have a real stereo environment to test it (other than cheap cyan-red glasses). If you can give it a try in a more robust system and report bugs or problems with BGE current system please let me know. I would be glad to help to make it work 100% by the time Blender 2.5 is out.

For the record, BGE is using the method known as 'parallel axis asymmetric frustum perspective projection'. This method is well documented here:
http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/stereographics/stereorender/

release/scripts/ui/properties_game.py
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_scene.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Rasterizer/RAS_CameraData.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h

index 293c4786c7fb4fbdd991302dbf892fcf09d62705..e0b8e5a20a4bc2e953f2dad504a446cc60900cb6 100644 (file)
@@ -274,8 +274,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel):
         # stereo:
         if stereo_mode == 'STEREO':
             layout.prop(gs, "stereo_mode")
-            # layout.label(text="To do: Focal Length") # to be done after 2.5alpha0 is out
-            # layout.label(text="To do: Eye Separation") # to be done after 2.5alpha0 is out
+            layout.prop(gs, "eye_separation")
 
         # dome:
         elif stereo_mode == 'DOME':
index eadeac585b2917b7ad8ef1bf7b1d2e482a29c6ed..f17d11c40cec3ff9eb8e2ddd2d2d23565d252eeb 100644 (file)
@@ -450,6 +450,8 @@ Scene *add_scene(char *name)
        /* game data */
        sce->gm.stereoflag = STEREO_NOSTEREO;
        sce->gm.stereomode = STEREO_ANAGLYPH;
+       sce->gm.eyeseparation = 0.10;
+
        sce->gm.dome.angle = 180;
        sce->gm.dome.mode = DOME_FISHEYE;
        sce->gm.dome.res = 4;
index d6858f664a30484520f35de38b61bd30000798b7..b99efc5be889cc15369f946e8604418a80dae991 100644 (file)
@@ -10304,6 +10304,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        /* put 2.50 compatibility code here until next subversion bump */
 
+       if (1) {
+               Scene *sce;
+               
+               for(sce = main->scene.first; sce; sce = sce->id.next) {
+                       sce->gm.eyeseparation = 0.10;
+               }
+       }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
index 536d9ba2bc3094f5af170339767212533b924399..6d6e668e2270cca81e7e1d72a6e8a7ac2c9b066a 100644 (file)
@@ -444,6 +444,7 @@ typedef struct GameData {
        /* stereo/dome mode */
        struct GameDome dome;
        short stereoflag, stereomode, xsch, ysch; //xsch and ysch can be deleted !!!
+       float eyeseparation, pad1;
 } GameData;
 
 #define STEREO_NOSTEREO                1
index ba389f66438ef758197fcb37bbefb7bc6e523e8e..e824a72c7911a0471807a61c90feabe05edad0a1 100644 (file)
@@ -1215,6 +1215,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Stereo Mode", "Stereographic techniques");
        RNA_def_property_update(prop, NC_SCENE, NULL);
 
+       prop= RNA_def_property(srna, "eye_separation", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "eyeseparation");
+       RNA_def_property_range(prop, 0.01, 5.0);
+       RNA_def_property_ui_text(prop, "Eye Separation", "Set the distance between the eyes");
+       RNA_def_property_update(prop, NC_SCENE, NULL);
+       
        /* Dome */
        prop= RNA_def_property(srna, "dome_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "dome.mode");
index cb1c05414d157664133fd9bf04b60603068a1ac7..83a6bbb2fe1fbd860d08976dc8ba6f86ffde40f3 100644 (file)
@@ -342,6 +342,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
                        if(blscene->gm.stereoflag == STEREO_ENABLED){
                                if (blscene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
                                        rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->gm.stereomode);
+
+                               rasterizer->SetEyeSeparation(blscene->gm.eyeseparation);
                        }
 
                        rasterizer->SetBackColor(blscene->gm.framing.col[0], blscene->gm.framing.col[1], blscene->gm.framing.col[2], 0.0f);
index 4c5960554950edb0f5b95b449780ed5c251709f3..a7f8b5c5fdf2c542c9c29cfdbc9c45186181156e 100644 (file)
@@ -1658,7 +1658,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
 
 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
        Camera* ca = static_cast<Camera*>(ob->data);
-       RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
+       RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist);
        KX_Camera *gamecamera;
        
        gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
index c8f4d9a0a17c5a1713d7f56bf99f352bc54c5e09..81dcc839ecb69e0bd103957f9c867e20bc7f4452 100644 (file)
@@ -44,19 +44,19 @@ struct RAS_CameraData
        float m_focallength;
 
        RAS_CameraData(float lens = 35.0, float scale = 6.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
-       float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, 
+       float focallength = 3.0, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, 
        int viewportright = 0, int viewporttop = 0) :
                m_lens(lens),
                m_scale(scale),
                m_clipstart(clipstart),
                m_clipend(clipend),
                m_perspective(perspective),
+               m_focallength(focallength),
                m_viewport(viewport),
                m_viewportleft(viewportleft),
                m_viewportbottom(viewportbottom),
                m_viewportright(viewportright),
-               m_viewporttop(viewporttop),
-               m_focallength(focallength)
+               m_viewporttop(viewporttop)
        {
        }
 };
index 336d80507e4e7049027c8da86b8f68a2311581aa..bbccb51124929fd8240e9b6fe86624c1f5cbc6b2 100644 (file)
@@ -73,7 +73,6 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        m_stereomode(RAS_STEREO_NOSTEREO),
        m_curreye(RAS_STEREO_LEFTEYE),
        m_eyeseparation(0.0),
-       m_seteyesep(false),
        m_focallength(0.0),
        m_setfocallength(false),
        m_noOfScanlines(32),
@@ -518,7 +517,6 @@ RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
 void RAS_OpenGLRasterizer::SetEyeSeparation(const float eyeseparation)
 {
        m_eyeseparation = eyeseparation;
-       m_seteyesep = true;
 }
 
 float RAS_OpenGLRasterizer::GetEyeSeparation()
@@ -902,26 +900,26 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
        if(Stereo())
        {
                        float near_div_focallength;
-                       // next 2 params should be specified on command line and in Blender publisher
+                       float offset;
+
+                       // if Rasterizer.setFocalLength is not called we use the camera focallength
                        if (!m_setfocallength)
-                               m_focallength = (focallength == 0.f) ? 1.5 * right  // derived from example
-                                       : focallength; 
-                       if (!m_seteyesep)
-                               m_eyeseparation = m_focallength/30;  // reasonable value...
+                               m_focallength = focallength;
 
                        near_div_focallength = frustnear / m_focallength;
+                       offset = 0.5 * m_eyeseparation * near_div_focallength;
                        switch(m_curreye)
                        {
                                case RAS_STEREO_LEFTEYE:
-                                               left += 0.5 * m_eyeseparation * near_div_focallength;
-                                               right += 0.5 * m_eyeseparation * near_div_focallength;
+                                               left += offset;
+                                               right += offset;
                                                break;
                                case RAS_STEREO_RIGHTEYE:
-                                               left -= 0.5 * m_eyeseparation * near_div_focallength;
-                                               right -= 0.5 * m_eyeseparation * near_div_focallength;
+                                               left -= offset;
+                                               right -= offset;
                                                break;
                        }
-                       // leave bottom, top, bottom and top untouched
+                       // leave bottom and top untouched
        }
        
        glMatrixMode(GL_PROJECTION);
index db0f97bf46f886f0e759b887b8aa5bcbbae6eda8..8d6bab7109767af80c9fed414cd3329597358334 100644 (file)
@@ -85,7 +85,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
        StereoMode              m_stereomode;
        StereoEye               m_curreye;
        float                   m_eyeseparation;
-       bool                    m_seteyesep;
        float                   m_focallength;
        bool                    m_setfocallength;
        int                             m_noOfScanlines;