[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19887] trunk/blender/source/gameengine: BGE Rasterizer methods to handle Screen Space - (getScreenPosition, getScreenVect, getScreenRay)
Dalai Felinto
dfelinto at gmail.com
Thu Apr 23 02:49:38 CEST 2009
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)
More information about the Bf-blender-cvs
mailing list