BGE: scene.pre_draw_setup[] callback

This callback allows the user to change the camera data right before the
rendering calculations.

scene.pre_draw[] is not enough here, because if you want to change the
camera matrices (projection/modelview) the culling test is done before
that (after pre_draw_setup[] though).

Reviewers: moguri, campbellbarton

Differential Revision: https://developer.blender.org/D1251

Python sample code using this. The sample scene would need a default
camera (not used for rendering), a dummy camera ('Camera.VR'), and two
cameras ('Camera.Left', 'Camera.Right') that will be used for the actual
rendering.

```
import bge

def callback():
    scene = bge.logic.getCurrentScene()
    objects = scene.objects

    vr_camera = objects.get('Camera.VR')

    if bge.render.getStereoEye() ==  bge.render.LEFT_EYE:
        camera = objects.get('Camera.Left')
    else:
        camera = objects.get('Camera.Right')

    vr_camera.worldOrientation = camera.worldOrientation
    vr_camera.worldPosition =  camera.worldPosition

def init():
    scene = bge.logic.getCurrentScene()
    main_camera = scene.active_camera
    main_camera.useViewport = True

   scene.pre_draw_setup.append(callback)

    objects = scene.objects
    vr_camera = objects.get('Camera.VR')
    vr_camera.useViewport = True
    vr_camera.setViewport(
            0,
            0,
            bge.render.getWindowWidth(),
            bge.render.getWindowHeight() )
```
This commit is contained in:
Dalai Felinto 2015-04-21 17:36:18 -03:00
parent f2956d5fc7
commit 9425a8ff38
4 changed files with 43 additions and 0 deletions

View File

@ -125,6 +125,12 @@ base class --- :class:`PyObjectPlus`
:type: list
.. attribute:: pre_draw_setup
A list of callables to be run before the drawing setup (i.e., before the model view and projection matrices are computed).
:type: list
.. attribute:: gravity
The scene gravity using the world x, y and z axis.

View File

@ -1108,6 +1108,10 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
KX_SetActiveScene(scene);
#ifdef WITH_PYTHON
scene->RunDrawingCallbacks(scene->GetPreDrawSetupCB());
#endif
GetSceneViewport(scene, cam, area, viewport);
// store the computed viewport in the scene

View File

@ -238,6 +238,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_attr_dict = NULL;
m_draw_call_pre = NULL;
m_draw_call_post = NULL;
m_draw_setup_call_pre = NULL;
#endif
}
@ -2399,6 +2400,17 @@ PyObject *KX_Scene::pyattr_get_drawing_callback_post(void *self_v, const KX_PYAT
return self->m_draw_call_post;
}
PyObject *KX_Scene::pyattr_get_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
if (self->m_draw_setup_call_pre == NULL)
self->m_draw_setup_call_pre = PyList_New(0);
Py_INCREF(self->m_draw_setup_call_pre);
return self->m_draw_setup_call_pre;
}
int KX_Scene::pyattr_set_drawing_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
@ -2433,6 +2445,22 @@ int KX_Scene::pyattr_set_drawing_callback_post(void *self_v, const KX_PYATTRIBUT
return PY_SET_ATTR_SUCCESS;
}
int KX_Scene::pyattr_set_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
if (!PyList_CheckExact(value)) {
PyErr_SetString(PyExc_ValueError, "Expected a list");
return PY_SET_ATTR_FAIL;
}
Py_XDECREF(self->m_draw_setup_call_pre);
Py_INCREF(value);
self->m_draw_setup_call_pre = value;
return PY_SET_ATTR_SUCCESS;
}
PyObject *KX_Scene::pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
@ -2462,6 +2490,7 @@ PyAttributeDef KX_Scene::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera),
KX_PYATTRIBUTE_RW_FUNCTION("pre_draw", KX_Scene, pyattr_get_drawing_callback_pre, pyattr_set_drawing_callback_pre),
KX_PYATTRIBUTE_RW_FUNCTION("post_draw", KX_Scene, pyattr_get_drawing_callback_post, pyattr_set_drawing_callback_post),
KX_PYATTRIBUTE_RW_FUNCTION("pre_draw_setup", KX_Scene, pyattr_get_drawing_setup_callback_pre, pyattr_set_drawing_setup_callback_pre),
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_Scene, pyattr_get_gravity, pyattr_set_gravity),
KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend),
KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling),

View File

@ -107,6 +107,7 @@ class KX_Scene : public PyObjectPlus, public SCA_IScene
PyObject* m_attr_dict;
PyObject* m_draw_call_pre;
PyObject* m_draw_call_post;
PyObject* m_draw_setup_call_pre;
#endif
struct CullingInfo {
@ -631,6 +632,8 @@ public:
static int pyattr_set_drawing_callback_pre(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_drawing_callback_post(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_drawing_setup_callback_pre(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_gravity(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@ -647,6 +650,7 @@ public:
PyObject *GetPreDrawCB() { return m_draw_call_pre; }
PyObject *GetPostDrawCB() { return m_draw_call_post; }
PyObject *GetPreDrawSetupCB() { return m_draw_setup_call_pre; }
#endif
/**