fix BGE bug #8646: unusable anaglyph settings

The best rules for stereo rendering are now applied to Blender. Here is the new situation:
1) The focal distance is now settable through the GUI: select the camera (each camera can have a different setting) and go to the camera data (F9): the "Dof Dist" and "Dof Ob" can be used to set the focal distance for that camera. The "Dof Ob" is interesting because it sets the focal distance so that the center this object will appear at the surface of the screen when running the game.
2) The eye separation is automatically set to focal_distance/30, which is considered to be a reasonable value. If you need a different value, you can always use Python scripting. 

Notes: 
- If you switch camera during the game, the focal distance will also change unless you have set the focal distance by scripting, in which case it overwrites the focal distance setting of all cameras.
- If you don't set the focal distance in the camera data or by scripting, the default value will be used. The default value corresponds more of less to the near clipping plane which means that all the objects will be very far with little 3D effect.
- If you don't set the eye separation by scripting, it is automatically computed as focal_distance/30, regardless on how the focal distance was set.
This commit is contained in:
Benoit Bolsee 2008-05-24 08:34:04 +00:00
parent 5f70682f6a
commit 7f10f5f66f
8 changed files with 26 additions and 9 deletions

@ -87,6 +87,7 @@
#include "DNA_action_types.h" #include "DNA_action_types.h"
#include "BKE_main.h" #include "BKE_main.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_object.h"
#include "BL_SkinMeshObject.h" #include "BL_SkinMeshObject.h"
#include "BL_SkinDeformer.h" #include "BL_SkinDeformer.h"
#include "BL_MeshDeformer.h" #include "BL_MeshDeformer.h"
@ -1571,8 +1572,9 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
return gamelight; return gamelight;
} }
static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP); Camera* ca = static_cast<Camera*>(ob->data);
RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
KX_Camera *gamecamera; KX_Camera *gamecamera;
gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
@ -1607,7 +1609,7 @@ static KX_GameObject *gameobject_from_blenderobject(
case OB_CAMERA: case OB_CAMERA:
{ {
KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter); KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter);
gameobj = gamecamera; gameobj = gamecamera;
//don't add a reference: the camera list in kxscene->m_cameras is not released at the end //don't add a reference: the camera list in kxscene->m_cameras is not released at the end

@ -204,6 +204,11 @@ float KX_Camera::GetCameraFar() const
return m_camdata.m_clipend; return m_camdata.m_clipend;
} }
float KX_Camera::GetFocalLength() const
{
return m_camdata.m_focallength;
}
RAS_CameraData* KX_Camera::GetCameraData() RAS_CameraData* KX_Camera::GetCameraData()

@ -184,12 +184,14 @@ public:
*/ */
const MT_Matrix4x4& GetModelviewMatrix() const; const MT_Matrix4x4& GetModelviewMatrix() const;
/** Gets the focal length. */ /** Gets the aperture. */
float GetLens() const; float GetLens() const;
/** Gets the near clip distance. */ /** Gets the near clip distance. */
float GetCameraNear() const; float GetCameraNear() const;
/** Gets the far clip distance. */ /** Gets the far clip distance. */
float GetCameraFar() const; float GetCameraFar() const;
/** Gets the focal length (only used for stereo rendering) */
float GetFocalLength() const;
/** Gets all camera data. */ /** Gets all camera data. */
RAS_CameraData* GetCameraData(); RAS_CameraData* GetCameraData();

@ -890,7 +890,7 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
// update graphics // update graphics
void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
{ {
float left, right, bottom, top, nearfrust, farfrust; float left, right, bottom, top, nearfrust, farfrust, focallength;
const float ortho = 100.0; const float ortho = 100.0;
// KX_Camera* cam = scene->GetActiveCamera(); // KX_Camera* cam = scene->GetActiveCamera();
@ -913,6 +913,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
float lens = cam->GetLens(); float lens = cam->GetLens();
nearfrust = cam->GetCameraNear(); nearfrust = cam->GetCameraNear();
farfrust = cam->GetCameraFar(); farfrust = cam->GetCameraFar();
focallength = cam->GetFocalLength();
if (!cam->GetCameraData()->m_perspective) if (!cam->GetCameraData()->m_perspective)
{ {
@ -939,7 +940,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
farfrust = frustum.camfar; farfrust = frustum.camfar;
MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
left, right, bottom, top, nearfrust, farfrust); left, right, bottom, top, nearfrust, farfrust, focallength);
cam->SetProjectionMatrix(projmat); cam->SetProjectionMatrix(projmat);

@ -40,13 +40,16 @@ struct RAS_CameraData
int m_viewportbottom; int m_viewportbottom;
int m_viewportright; int m_viewportright;
int m_viewporttop; int m_viewporttop;
float m_focallength;
RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true, RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true,
bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0,
int viewportright = 0, int viewporttop = 0) :
m_lens(lens), m_lens(lens),
m_clipstart(clipstart), m_clipstart(clipstart),
m_clipend(clipend), m_clipend(clipend),
m_perspective(perspective), m_perspective(perspective),
m_focallength(focallength),
m_viewport(viewport), m_viewport(viewport),
m_viewportleft(viewportleft), m_viewportleft(viewportleft),
m_viewportbottom(viewportbottom), m_viewportbottom(viewportbottom),

@ -344,6 +344,7 @@ public:
float top, float top,
float frustnear, float frustnear,
float frustfar, float frustfar,
float focallength = 0.0f,
bool perspective = true bool perspective = true
)=0; )=0;
/** /**

@ -1802,6 +1802,7 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
float top, float top,
float frustnear, float frustnear,
float frustfar, float frustfar,
float focallength,
bool bool
){ ){
MT_Matrix4x4 result; MT_Matrix4x4 result;
@ -1813,9 +1814,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
float near_div_focallength; float near_div_focallength;
// next 2 params should be specified on command line and in Blender publisher // next 2 params should be specified on command line and in Blender publisher
if (!m_setfocallength) if (!m_setfocallength)
m_focallength = 1.5 * right; // derived from example m_focallength = (focallength == 0.f) ? 1.5 * right // derived from example
: focallength;
if (!m_seteyesep) if (!m_seteyesep)
m_eyeseparation = 0.18 * right; // just a guess... m_eyeseparation = m_focallength/30; // reasonable value...
near_div_focallength = frustnear / m_focallength; near_div_focallength = frustnear / m_focallength;
switch(m_curreye) switch(m_curreye)

@ -246,6 +246,7 @@ public:
float top, float top,
float frustnear, float frustnear,
float frustfar, float frustfar,
float focallength,
bool perspective bool perspective
); );