Revision: 19887
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19887
Author:   dfelinto
Date:     2009-04-23 02:49:38 +0200 (Thu, 23 Apr 2009)

Log Message:
-----------
BGE Rasterizer methods to handle Screen Space - (getScreenPosition, 
getScreenVect, getScreenRay)

getScreenPosition(obj):
 - Gets the position of an object projected on screen space.

getScreenVect(x, y):
 - Gets the vector from the camera position in the screen coordinate direction.

getScreenRay(x, y, dist, property):
 - Look towards a screen coordinate (x,y) and find first object hit within dist 
that matches prop.
- The ray is a call to KX_GameObject->rayCastTo from the KX_Camera object.

Patch [#18589] test files can be found there. Patch reviewed by Campbell

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp
    trunk/blender/source/gameengine/PyDoc/KX_GameObject.py
    trunk/blender/source/gameengine/PyDoc/Rasterizer.py

Modified: trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp    2009-04-23 
00:47:45 UTC (rev 19886)
+++ trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp    2009-04-23 
00:49:38 UTC (rev 19887)
@@ -484,6 +484,127 @@
 };
 
 
+static PyObject* gPyGetScreenPosition(PyObject*, PyObject* value)
+{
+       MT_Vector3 vect;
+       KX_GameObject *obj = NULL;
+
+       if (!PyVecTo(value, vect))
+       {
+               if(ConvertPythonToGameObject(value, &obj, true, ""))
+               {
+                       PyErr_Clear();
+                       vect = MT_Vector3(obj->NodeGetWorldPosition());
+               }
+               else
+               {
+                       PyErr_SetString(PyExc_TypeError, "Error in 
getScreenPosition. Expected a Vector3 or a KX_GameObject or a string for a name 
of a KX_GameObject");
+                       return NULL;
+               }
+       }
+
+       GLdouble modelMatrix[16];
+       GLdouble projMatrix[16];
+       GLint   viewport[4];
+       GLdouble win[3];
+
+       glGetIntegerv(GL_VIEWPORT, viewport);
+       glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+       glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
+
+       gluProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, 
viewport, &win[0], &win[1], &win[2]);
+
+       vect[0] =  win[0] / (viewport[0] + viewport[2]);
+       vect[1] =  win[1] / (viewport[1] + viewport[3]);
+
+       PyObject* ret = PyTuple_New(2);
+       if(ret){
+               PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(vect[0]));
+               PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(vect[1]));
+               return ret;
+       }
+
+       return NULL;
+}
+
+static PyObject* gPyGetScreenVect(PyObject*, PyObject* args)
+{
+       double x,y;
+       if (!PyArg_ParseTuple(args,"dd:getScreenVect",&x,&y))
+               return NULL;
+
+       MT_Vector3 vect;
+       MT_Point3 campos, screenpos;
+
+       GLdouble modelMatrix[16];
+       GLdouble projMatrix[16];
+       GLint   viewport[4];
+       GLdouble win[3];
+
+       glGetIntegerv(GL_VIEWPORT, viewport);
+       glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
+       glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
+
+       vect[0] = x * viewport[2];
+       vect[1] = y * viewport[3];
+
+       vect[0] += viewport[0];
+       vect[1] += viewport[1];
+
+       glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vect[2]);
+       gluUnProject(vect[0], vect[1], vect[2], modelMatrix, projMatrix, 
viewport, &win[0], &win[1], &win[2]);
+
+       campos    = gp_Rasterizer->GetCameraPosition();
+       screenpos = MT_Point3(win[0], win[1], win[2]);
+       vect = campos-screenpos;
+
+       vect.normalize();
+       return PyObjectFrom(vect);
+}
+
+static PyObject* gPyGetScreenRay(PyObject* self, PyObject* args)
+{
+       KX_Camera* cam;
+       MT_Vector3 vect;
+       double x,y,dist;
+       char *propName = NULL;
+
+       if (!PyArg_ParseTuple(args,"ddd|s:getScreenRay",&x,&y,&dist,&propName))
+               return NULL;
+
+       PyObject* argValue = PyTuple_New(2);
+       if (argValue) {
+               PyTuple_SET_ITEM(argValue, 0, PyFloat_FromDouble(x));
+               PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(y));
+       }
+
+       if(!PyVecTo(gPyGetScreenVect(self,argValue), vect))
+       {
+               Py_DECREF(argValue);
+               PyErr_SetString(PyExc_TypeError,
+                       "Error in getScreenRay. Invalid 2D coordinate. Expected 
a normalized 2D screen coordinate and an optional property argument");
+               return NULL;
+       }
+       Py_DECREF(argValue);
+
+       cam = gp_KetsjiScene->GetActiveCamera();
+       dist *= -1.0;
+
+       argValue = (propName?PyTuple_New(3):PyTuple_New(2));
+       if (argValue) {
+               PyTuple_SET_ITEM(argValue, 0, PyObjectFrom(vect));
+               PyTuple_SET_ITEM(argValue, 1, PyFloat_FromDouble(dist));
+               if (propName)
+                       PyTuple_SET_ITEM(argValue, 2, 
PyString_FromString(propName));
+
+               PyObject* ret= cam->PyrayCastTo(argValue,NULL);
+               Py_DECREF(argValue);
+               return ret;
+       }
+
+       return NULL;
+}
+
 static PyObject* gPyGetWindowHeight(PyObject*, PyObject* args)
 {
        return PyInt_FromLong((gp_Canvas ? gp_Canvas->GetHeight() : 0));
@@ -897,6 +1018,12 @@
 }
 
 static struct PyMethodDef rasterizer_methods[] = {
+  {"getScreenPosition",(PyCFunction) gPyGetScreenPosition,
+   METH_O, "getScreenPosition doc"},
+  {"getScreenVect",(PyCFunction) gPyGetScreenVect,
+   METH_VARARGS, "getScreenVect doc"},
+  {"getScreenRay",(PyCFunction) gPyGetScreenRay,
+   METH_VARARGS, "getScreenRay doc"},
   {"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
    METH_VARARGS, "getWindowWidth doc"},
    {"getWindowHeight",(PyCFunction) gPyGetWindowHeight,

Modified: trunk/blender/source/gameengine/PyDoc/KX_GameObject.py
===================================================================
--- trunk/blender/source/gameengine/PyDoc/KX_GameObject.py      2009-04-23 
00:47:45 UTC (rev 19886)
+++ trunk/blender/source/gameengine/PyDoc/KX_GameObject.py      2009-04-23 
00:49:38 UTC (rev 19887)
@@ -82,7 +82,7 @@
        @ivar isValid: Retuerns fails when the object has been removed from the 
scene and can no longer be used.
        @type isValid: bool
        """
-       def endObject(visible):
+       def endObject():
                """
                Delete this object, can be used inpace of the EndObject 
Actuator.
                The actual removal of the object from the scene is delayed.

Modified: trunk/blender/source/gameengine/PyDoc/Rasterizer.py
===================================================================
--- trunk/blender/source/gameengine/PyDoc/Rasterizer.py 2009-04-23 00:47:45 UTC 
(rev 19886)
+++ trunk/blender/source/gameengine/PyDoc/Rasterizer.py 2009-04-23 00:49:38 UTC 
(rev 19887)
@@ -44,6 +44,49 @@
 
 """
 
+def getScreenPosition(arg):
+       """
+       Gets the position of an object projected on screen space.
+
+       Example:
+       # For an object in the middle of the screen, coord = [0.5,0.5]
+       coord = Rasterizer.getScreenPosition(object)
+
+       @param arg: L{KX_GameObject}, object name or list [x, y, z]
+       @rtype: list [x, y]
+       @return: the object's position in screen coordinates.
+       """
+def getScreenVect(x, y):
+       """
+       Gets the vector from the camera position in the screen coordinate 
direction.
+
+       Example:
+       # Gets the vector of the camera front direction:
+       m_vect = Rasterizer.getScreenVect(0.5,0.5)
+
+       @type x: float
+       @type y: float
+       @rtype: 3d vector
+       @return: the vector from a screen coordinate.
+       """
+def getScreenRay(x, y, dist, property):
+       """
+       Look towards a screen coordinate (x,y) and find first object hit within 
dist that matches prop.
+       The ray is similar to KX_GameObject->rayCastTo.
+
+       Example:
+       # Gets an object with a property "wall" in front of the camera within a 
distance of 100:
+       target = Rasterizer.getScreenRay(0.5,0.5,100,"wall")
+
+       @type x: float
+       @type y: float
+       @param dist: max distance to look (can be negative => look behind); 0 
or omitted => detect up to other
+       @type dist: float
+       @param prop: property name that object must have; can be omitted => 
detect any object
+       @type prop: string
+       @rtype: L{KX_GameObject}
+       @return: the first object hit or None if no object or object does not 
match prop
+       """
 def getWindowWidth():
        """
        Gets the width of the window (in pixels)


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to