[Bf-committers] Mouse Over fixed (maybe), Patch Attached
João Eduardo
joaoedu at gmail.com
Fri Jun 24 21:19:27 CEST 2005
Skipped content of type multipart/alternative-------------- next part --------------
? blender
? blenderplayer
? config.opts
? diff.txt
? dist
? source/gameengine/KX_MouseFocusSensor.cpp
? tools/__init__.pyc
? tools/scons/__init__.pyc
? tools/scons/bs/__init__.pyc
? tools/scons/bs/bs_arc.pyc
? tools/scons/bs/bs_bincopy.pyc
? tools/scons/bs/bs_clean.pyc
? tools/scons/bs/bs_config.pyc
? tools/scons/bs/bs_default.pyc
? tools/scons/bs/bs_dirs.pyc
? tools/scons/bs/bs_globals.pyc
? tools/scons/bs/bs_libs.pyc
? tools/scons/bs/bs_nsis.pyc
Index: SConstruct
===================================================================
RCS file: /cvsroot/bf-blender/blender/SConstruct,v
retrieving revision 1.107
diff -r1.107 SConstruct
59c59
< use_openal = 'false'
---
> use_openal = 'true'
68c68
< build_blender_plugin = 'false'
---
> build_blender_plugin = 'true'
Index: source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp,v
retrieving revision 1.13
diff -r1.13 KX_MouseFocusSensor.cpp
1,443c1,406
< /**
< * $Id: KX_MouseFocusSensor.cpp,v 1.13 2005/03/25 16:31:05 sirdude Exp $
< *
< * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
< *
< * This program is free software; you can redistribute it and/or
< * modify it under the terms of the GNU General Public License
< * as published by the Free Software Foundation; either version 2
< * of the License, or (at your option) any later version. The Blender
< * Foundation also sells licenses for use in proprietary software under
< * the Blender License. See http://www.blender.org/BL/ for information
< * about this.
< *
< * This program is distributed in the hope that it will be useful,
< * but WITHOUT ANY WARRANTY; without even the implied warranty of
< * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
< * GNU General Public License for more details.
< *
< * You should have received a copy of the GNU General Public License
< * along with this program; if not, write to the Free Software Foundation,
< * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
< *
< * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
< * All rights reserved.
< *
< * The Original Code is: all of this file.
< *
< * Contributor(s): none yet.
< *
< * ***** END GPL/BL DUAL LICENSE BLOCK *****
< * KX_MouseFocusSensor determines mouse in/out/over events.
< */
<
< #ifdef WIN32
< // This warning tells us about truncation of __long__ stl-generated names.
< // It can occasionally cause DevStudio to have internal compiler warnings.
< #pragma warning( disable : 4786 )
< #endif
<
< #include "MT_Point3.h"
< #include "RAS_FramingManager.h"
< #include "RAS_ICanvas.h"
< #include "RAS_IRasterizer.h"
< #include "SCA_IScene.h"
< #include "KX_Scene.h"
< #include "KX_Camera.h"
< #include "KX_MouseFocusSensor.h"
<
< #include "KX_RayCast.h"
< #include "KX_IPhysicsController.h"
< #include "PHY_IPhysicsController.h"
< #include "PHY_IPhysicsEnvironment.h"
<
<
< #include "KX_ClientObjectInfo.h"
<
< /* ------------------------------------------------------------------------- */
< /* Native functions */
< /* ------------------------------------------------------------------------- */
<
< KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
< int startx,
< int starty,
< short int mousemode,
< bool focusmode,
< RAS_ICanvas* canvas,
< KX_Scene* kxscene,
< SCA_IObject* gameobj,
< PyTypeObject* T)
< : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T),
< m_focusmode(focusmode),
< m_gp_canvas(canvas),
< m_kxscene(kxscene)
< {
< /* Or postpone? I think a sumo scene and kx scene go pretty much
< * together, so it should be safe to do it here. */
< m_mouse_over_in_previous_frame = false;
< m_positive_event = false;
< }
<
< bool KX_MouseFocusSensor::Evaluate(CValue* event)
< {
< bool result = false;
< bool obHasFocus = false;
<
< // cout << "evaluate focus mouse sensor "<<endl;
<
< if (m_focusmode) {
< /* Focus behaviour required. Test mouse-on. The rest is
< * equivalent to handling a key. */
< obHasFocus = ParentObjectHasFocus();
<
< if (!obHasFocus) {
< if (m_mouse_over_in_previous_frame) {
< m_positive_event = false;
< result = true;
< }
< } else {
< if (!m_mouse_over_in_previous_frame) {
< m_positive_event = true;
< result = true;
< }
< }
< } else {
< /* No focus behaviour required: revert to the basic mode. This
< * mode is never used, because the converter never makes this
< * sensor for a mouse-key event. It is here for
< * completeness. */
< result = SCA_MouseSensor::Evaluate(event);
< m_positive_event = (m_val!=0);
< }
<
< m_mouse_over_in_previous_frame = obHasFocus;
<
< return result;
< }
<
< bool KX_MouseFocusSensor::RayHit(KX_ClientObjectInfo* client_info, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
< {
< KX_GameObject* hitKXObj = client_info->m_gameobject;
<
< if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
< {
< // false hit
< return false;
< }
<
< /* Is this me? In the ray test, there are a lot of extra checks
< * for aliasing artefacts from self-hits. That doesn't happen
< * here, so a simple test suffices. Or does the camera also get
< * self-hits? (No, and the raysensor shouldn't do it either, since
< * self-hits are excluded by setting the correct ignore-object.)
< * Hitspots now become valid. */
< KX_GameObject* thisObj = (KX_GameObject*) GetParent();
< if (hitKXObj == thisObj)
< {
< m_hitPosition = hit_point;
< m_hitNormal = hit_normal;
< return true;
< }
<
< return true; // object must be visible to trigger
< //return false; // occluded objects can trigger
< }
<
<
<
< bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
< {
<
< m_hitPosition = MT_Vector3(0,0,0);
< m_hitNormal = MT_Vector3(1,0,0);
< MT_Point3 resultpoint;
< MT_Vector3 resultnormal;
<
< /* All screen handling in the gameengine is done by GL,
< * specifically the model/view and projection parts. The viewport
< * part is in the creator.
< *
< * The theory is this:
< * WCS - world coordinates
< * -> wcs_camcs_trafo ->
< * camCS - camera coordinates
< * -> camcs_clip_trafo ->
< * clipCS - normalised device coordinates?
< * -> normview_win_trafo
< * winCS - window coordinates
< *
< * The first two transforms are respectively the model/view and
< * the projection matrix. These are passed to the rasterizer, and
< * we store them in the camera for easy access.
< *
< * For normalised device coords (xn = x/w, yn = y/w/zw) the
< * windows coords become (lb = left bottom)
< *
< * xwin = [(xn + 1.0) * width]/2 + x_lb
< * ywin = [(yn + 1.0) * height]/2 + y_lb
< *
< * Inverting (blender y is flipped!):
< *
< * xn = 2(xwin - x_lb)/width - 1.0
< * yn = 2(ywin - y_lb)/height - 1.0
< * = 2(height - y_blender - y_lb)/height - 1.0
< * = 1.0 - 2(y_blender - y_lb)/height
< *
< * */
<
< /* Because we don't want to worry about resize events, camera
< * changes and all that crap, we just determine this over and
< * over. Stop whining. We have lots of other calculations to do
< * here as well. These reads are not the main cost. If there is no
< * canvas, the test is irrelevant. The 1.0 makes sure the
< * calculations don't bomb. Maybe we should explicitly guard for
< * division by 0.0...*/
<
< /**
< * Get the scenes current viewport.
< */
<
< const RAS_Rect & viewport = m_kxscene->GetSceneViewport();
<
< float height = float(viewport.m_y2 - viewport.m_y1 + 1);
< float width = float(viewport.m_x2 - viewport.m_x1 + 1);
<
< float x_lb = float(viewport.m_x1);
< float y_lb = float(viewport.m_y1);
<
< KX_Camera* cam = m_kxscene->GetActiveCamera();
< /* There's some strangeness I don't fully get here... These values
< * _should_ be wrong! */
<
< /* old: */
< float nearclip = 0.0;
< float farclip = 1.0;
<
< /* build the from and to point in normalised device coordinates
< * Looks like normailized device coordinates are [-1,1] in x [-1,1] in y
< * [0,-1] in z
< *
< * The actual z coordinates used don't have to be exact just infront and
< * behind of the near and far clip planes.
< */
< MT_Vector4 frompoint = MT_Vector4(
< (2 * (m_x-x_lb) / width) - 1.0,
< 1.0 - (2 * (m_y - y_lb) / height),
< nearclip,
< 1.0
< );
< MT_Vector4 topoint = MT_Vector4(
< (2 * (m_x-x_lb) / width) - 1.0,
< 1.0 - (2 * (m_y-y_lb) / height),
< farclip,
< 1.0
< );
<
< /* camera to world */
< MT_Transform wcs_camcs_tranform = cam->GetWorldToCamera();
< if (!cam->GetCameraData()->m_perspective)
< wcs_camcs_tranform.getOrigin()[2] *= 100.0;
< MT_Transform cams_wcs_transform;
< cams_wcs_transform.invert(wcs_camcs_tranform);
<
< MT_Matrix4x4 camcs_wcs_matrix = MT_Matrix4x4(cams_wcs_transform);
<
< /* badly defined, the first time round.... I wonder why... I might
< * want to guard against floating point errors here.*/
< MT_Matrix4x4 clip_camcs_matrix = MT_Matrix4x4(cam->GetProjectionMatrix());
< clip_camcs_matrix.invert();
<
< /* shoot-points: clip to cam to wcs . win to clip was already done.*/
< frompoint = clip_camcs_matrix * frompoint;
< topoint = clip_camcs_matrix * topoint;
< frompoint = camcs_wcs_matrix * frompoint;
< topoint = camcs_wcs_matrix * topoint;
<
< /* from hom wcs to 3d wcs: */
< MT_Point3 frompoint3 = MT_Point3(frompoint[0]/frompoint[3],
< frompoint[1]/frompoint[3],
< frompoint[2]/frompoint[3]);
< MT_Point3 topoint3 = MT_Point3(topoint[0]/topoint[3],
< topoint[1]/topoint[3],
< topoint[2]/topoint[3]);
< m_prevTargetPoint = topoint3;
< m_prevSourcePoint = frompoint3;
<
< /* 2. Get the object from PhysicsEnvironment */
< /* Shoot! Beware that the first argument here is an
< * ignore-object. We don't ignore anything... */
<
< KX_IPhysicsController* physics_controller = (cam->GetPhysicsController());
< PHY_IPhysicsEnvironment* physics_environment = m_kxscene->GetPhysicsEnvironment();
<
< // MT_Vector3 todir = topoint3 - frompoint3;
< // if (todir.dot(todir) < MT_EPSILON)
< // return false;
< // todir.normalize();
<
< KX_RayCast::RayTest(physics_controller, physics_environment, frompoint3, topoint3, resultpoint, resultnormal, KX_RayCast::Callback<KX_MouseFocusSensor>(this));
<
<
< // while (true)
< // {
< // PHY__Vector3 resultpt;
< // PHY__Vector3 resultnr;
< //
< // PHY_IPhysicsController* hitCtrl= physEnv->rayTest(camCtrl,
< // frompoint3.x(),frompoint3.y(),frompoint3.z(),
< // topoint3.x(),topoint3.y(),topoint3.z(),
< // resultpt[0], resultpt[1],resultpt[2],
< // resultnr[0],resultnr[1],resultnr[2]);
< //
< // if (!hitCtrl)
< // return false;
< //
< // resultpoint = MT_Vector3(resultpt);
< // resultnormal = MT_Vector3(resultnr);
< //
< // /* all this casting makes me nervous... */
< // KX_ClientObjectInfo* client_info
< // = static_cast<KX_ClientObjectInfo*>( hitCtrl->getNewClientInfo());
< //
< // if (!client_info)
< // {
< // std::cout<< "WARNING: MouseOver sensor " << GetName() << " cannot sense - no client info.\n" << std::endl;
< //
< // return false;
< // }
< //
< // KX_GameObject* hitKXObj = client_info->m_gameobject;
< //
< // if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
< // {
< // // false hit
< // // FIXME: add raytest interface to KX_IPhysicsController, remove casting
< // PHY_IPhysicsController* hitspc = (PHY_IPhysicsController*) (static_cast<KX_GameObject*> (hitKXObj)->GetPhysicsController());
< // if (hitspc)
< // {
< // /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
< // MT_Scalar marg = 0.01 + hitspc->GetMargin();
< // marg += hitspc->GetRadius(); //this is changed, check !
< //
< // //if (hitspc->GetSumoObject()->getShapeProps())
< // //{
< // // marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius;
< // //}
< //
< // /* Calculate the other side of this object */
< // MT_Point3 hitObjPos;
< // PHY__Vector3 hitpos;
< // hitspc->getPosition(hitpos);
< // hitObjPos = MT_Vector3(hitpos);
< // MT_Vector3 hitvector = hitObjPos - resultpoint;
< // if (hitvector.dot(hitvector) > MT_EPSILON)
< // {
< // hitvector.normalize();
< // marg *= 2.*todir.dot(hitvector);
< // }
< // frompoint3 = resultpoint + marg * todir;
< // } else {
< // return false;
< // }
< // continue;
< // }
< // /* Is this me? In the ray test, there are a lot of extra checks
< // * for aliasing artefacts from self-hits. That doesn't happen
< // * here, so a simple test suffices. Or does the camera also get
< // * self-hits? (No, and the raysensor shouldn't do it either, since
< // * self-hits are excluded by setting the correct ignore-object.)
< // * Hitspots now become valid. */
< // if (hitKXObj == thisObj)
< // {
< // m_hitPosition = resultpoint;
< // m_hitNormal = resultnormal;
< // return true;
< // }
< //
< // return false;
< // }
<
< return false;
< }
<
< /* ------------------------------------------------------------------------- */
< /* Python functions */
< /* ------------------------------------------------------------------------- */
<
< /* Integration hooks ------------------------------------------------------- */
< PyTypeObject KX_MouseFocusSensor::Type = {
< PyObject_HEAD_INIT(&PyType_Type)
< 0,
< "KX_MouseFocusSensor",
< sizeof(KX_MouseFocusSensor),
< 0,
< PyDestructor,
< 0,
< __getattr,
< __setattr,
< 0, //&MyPyCompare,
< __repr,
< 0, //&cvalue_as_number,
< 0,
< 0,
< 0,
< 0
< };
<
< PyParentObject KX_MouseFocusSensor::Parents[] = {
< &KX_MouseFocusSensor::Type,
< &SCA_MouseSensor::Type,
< &SCA_ISensor::Type,
< &SCA_ILogicBrick::Type,
< &CValue::Type,
< NULL
< };
<
< PyMethodDef KX_MouseFocusSensor::Methods[] = {
< {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget,
< METH_VARARGS, GetRayTarget_doc},
< {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource,
< METH_VARARGS, GetRaySource_doc},
< {NULL,NULL} //Sentinel
< };
<
< PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) {
< _getattr_up(SCA_MouseSensor);
< }
<
< /* getRayTarget */
< char KX_MouseFocusSensor::GetRayTarget_doc[] =
< "getRayTarget()\n"
< "\tReturns the target of the ray that seeks the focus object,\n"
< "\tin worldcoordinates.";
< PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self,
< PyObject* args,
< PyObject* kwds) {
< PyObject *retVal = PyList_New(3);
<
< PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0]));
< PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1]));
< PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2]));
<
< return retVal;
< }
<
< /* getRayTarget */
< char KX_MouseFocusSensor::GetRaySource_doc[] =
< "getRaySource()\n"
< "\tReturns the source of the ray that seeks the focus object,\n"
< "\tin worldcoordinates.";
< PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self,
< PyObject* args,
< PyObject* kwds) {
< PyObject *retVal = PyList_New(3);
<
< PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0]));
< PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1]));
< PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2]));
<
< return retVal;
< }
<
< /* eof */
<
---
> /**
> * $Id: KX_MouseFocusSensor.cpp,v 1.10 2004/11/23 10:10:21 kester Exp $
> *
> * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
> *
> * This program is free software; you can redistribute it and/or
> * modify it under the terms of the GNU General Public License
> * as published by the Free Software Foundation; either version 2
> * of the License, or (at your option) any later version. The Blender
> * Foundation also sells licenses for use in proprietary software under
> * the Blender License. See http://www.blender.org/BL/ for information
> * about this.
> *
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more details.
> *
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software Foundation,
> * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> *
> * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
> * All rights reserved.
> *
> * The Original Code is: all of this file.
> *
> * Contributor(s): none yet.
> *
> * ***** END GPL/BL DUAL LICENSE BLOCK *****
> * KX_MouseFocusSensor determines mouse in/out/over events.
> */
>
> #ifdef HAVE_CONFIG_H
> #include <config.h>
> #endif
>
> #ifdef WIN32
> // This warning tells us about truncation of __long__ stl-generated names.
> // It can occasionally cause DevStudio to have internal compiler warnings.
> #pragma warning( disable : 4786 )
> #endif
>
> #include "MT_Point3.h"
> #include "RAS_FramingManager.h"
> #include "RAS_ICanvas.h"
> #include "RAS_IRasterizer.h"
> #include "SCA_IScene.h"
> #include "KX_Scene.h"
> #include "KX_Camera.h"
> #include "KX_MouseFocusSensor.h"
>
> #include "SM_Object.h"
> #include "SM_Scene.h"
> #include "SumoPhysicsEnvironment.h"
> #include "KX_SumoPhysicsController.h"
> #include "KX_ClientObjectInfo.h"
>
> /* ------------------------------------------------------------------------- */
> /* Native functions */
> /* ------------------------------------------------------------------------- */
>
> KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
> int startx,
> int starty,
> short int mousemode,
> bool focusmode,
> RAS_ICanvas* canvas,
> KX_Scene* kxscene,
> SCA_IObject* gameobj,
> PyTypeObject* T)
> : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T),
> m_focusmode(focusmode),
> m_gp_canvas(canvas),
> m_kxscene(kxscene)
> {
> /* Or postpone? I think a sumo scene and kx scene go pretty much
> * together, so it should be safe to do it here. */
> m_mouse_over_in_previous_frame = false;
> m_positive_event = false;
> }
>
> bool KX_MouseFocusSensor::Evaluate(CValue* event)
> {
> bool result = false;
> bool obHasFocus = false;
>
> // cout << "evaluate focus mouse sensor "<<endl;
>
> if (m_focusmode) {
> /* Focus behaviour required. Test mouse-on. The rest is
> * equivalent to handling a key. */
> obHasFocus = ParentObjectHasFocus();
>
> if (!obHasFocus) {
> if (m_mouse_over_in_previous_frame) {
> m_positive_event = false;
> result = true;
> }
> } else {
> if (!m_mouse_over_in_previous_frame) {
> m_positive_event = true;
> result = true;
> }
> }
> } else {
> /* No focus behaviour required: revert to the basic mode. This
> * mode is never used, because the converter never makes this
> * sensor for a mouse-key event. It is here for
> * completeness. */
> result = SCA_MouseSensor::Evaluate(event);
> m_positive_event = (m_val!=0);
> }
>
> m_mouse_over_in_previous_frame = obHasFocus;
>
> return result;
> }
>
> bool KX_MouseFocusSensor::ParentObjectHasFocus(void)
> {
>
> bool res = false;
> m_hitPosition = MT_Vector3(0,0,0);
> m_hitNormal = MT_Vector3(1,0,0);
> MT_Point3 resultpoint;
> MT_Vector3 resultnormal;
>
> /* All screen handling in the gameengine is done by GL,
> * specifically the model/view and projection parts. The viewport
> * part is in the creator.
> *
> * The theory is this:
> * WCS - world coordinates
> * -> wcs_camcs_trafo ->
> * camCS - camera coordinates
> * -> camcs_clip_trafo ->
> * clipCS - normalised device coordinates?
> * -> normview_win_trafo
> * winCS - window coordinates
> *
> * The first two transforms are respectively the model/view and
> * the projection matrix. These are passed to the rasterizer, and
> * we store them in the camera for easy access.
> *
> * For normalised device coords (xn = x/w, yn = y/w/zw) the
> * windows coords become (lb = left bottom)
> *
> * xwin = [(xn + 1.0) * width]/2 + x_lb
> * ywin = [(yn + 1.0) * height]/2 + y_lb
> *
> * Inverting (blender y is flipped!):
> *
> * xn = 2(xwin - x_lb)/width - 1.0
> * yn = 2(ywin - y_lb)/height - 1.0
> * = 2(height - y_blender - y_lb)/height - 1.0
> * = 1.0 - 2(y_blender - y_lb)/height
> *
> * */
>
> /* Because we don't want to worry about resize events, camera
> * changes and all that crap, we just determine this over and
> * over. Stop whining. We have lots of other calculations to do
> * here as well. These reads are not the main cost. If there is no
> * canvas, the test is irrelevant. The 1.0 makes sure the
> * calculations don't bomb. Maybe we should explicitly guard for
> * division by 0.0...*/
>
> /**
> * Get the scenes current viewport.
> */
>
> const RAS_Rect & viewport = m_kxscene->GetSceneViewport();
>
> float height = float(viewport.m_y2 - viewport.m_y1 + 1);
> float width = float(viewport.m_x2 - viewport.m_x1 + 1);
>
> float x_lb = float(viewport.m_x1);
> float y_lb = float(viewport.m_y1);
>
> KX_Camera* cam = m_kxscene->GetActiveCamera();
> /* There's some strangeness I don't fully get here... These values
> * _should_ be wrong! */
>
> /* old: */
> float nearclip = 0.0;
> float farclip = 1.0;
>
> /* build the from and to point in normalised device coordinates
> * Looks like normailized device coordinates are [-1,1] in x [-1,1] in y
> * [0,-1] in z
> *
> * The actual z coordinates used don't have to be exact just infront and
> * behind of the near and far clip planes.
> */
> MT_Vector4 frompoint = MT_Vector4(
> (2 * (m_x-x_lb) / width) - 1.0,
> 1.0 - (2 * (m_y - y_lb) / height),
> nearclip,
> 1.0
> );
> MT_Vector4 topoint = MT_Vector4(
> (2 * (m_x-x_lb) / width) - 1.0,
> 1.0 - (2 * (m_y-y_lb) / height),
> farclip,
> 1.0
> );
>
> /* camera to world */
> MT_Transform wcs_camcs_tranform = cam->GetWorldToCamera();
> if (!cam->GetCameraData()->m_perspective)
> wcs_camcs_tranform.getOrigin()[2] *= 100.0;
> MT_Transform cams_wcs_transform;
> cams_wcs_transform.invert(wcs_camcs_tranform);
>
> MT_Matrix4x4 camcs_wcs_matrix = MT_Matrix4x4(cams_wcs_transform);
>
> /* badly defined, the first time round.... I wonder why... I might
> * want to guard against floating point errors here.*/
> MT_Matrix4x4 clip_camcs_matrix = MT_Matrix4x4(cam->GetProjectionMatrix());
> clip_camcs_matrix.invert();
>
> /* shoot-points: clip to cam to wcs . win to clip was already done.*/
> frompoint = clip_camcs_matrix * frompoint;
> topoint = clip_camcs_matrix * topoint;
> frompoint = camcs_wcs_matrix * frompoint;
> topoint = camcs_wcs_matrix * topoint;
>
> /* from hom wcs to 3d wcs: */
> MT_Point3 frompoint3 = MT_Point3(frompoint[0]/frompoint[3],
> frompoint[1]/frompoint[3],
> frompoint[2]/frompoint[3]);
> MT_Point3 topoint3 = MT_Point3(topoint[0]/topoint[3],
> topoint[1]/topoint[3],
> topoint[2]/topoint[3]);
> m_prevTargetPoint = topoint3;
> m_prevSourcePoint = frompoint3;
>
> /* 2. Get the object from SuMO*/
> /* Shoot! Beware that the first argument here is an
> * ignore-object. We don't ignore anything... */
> KX_GameObject* thisObj = (KX_GameObject*) GetParent();
>
> SumoPhysicsEnvironment *spe = dynamic_cast<SumoPhysicsEnvironment* > (m_kxscene->GetPhysicsEnvironment());
> SM_Scene *sumoScene = spe->GetSumoScene();
> KX_SumoPhysicsController *spc = dynamic_cast<KX_SumoPhysicsController*> (cam->GetPhysicsController());
> SM_Object *sumoCam = spc?spc->GetSumoObject():NULL;
> MT_Vector3 todir = topoint3 - frompoint3;
> if (todir.dot(todir) < MT_EPSILON)
> return false;
> todir.normalize();
>
> while (true)
> {
> SM_Object* hitSMObj = sumoScene->rayTest(sumoCam,
> frompoint3,
> topoint3,
> resultpoint,
> resultnormal);
>
> if (!hitSMObj)
> return false;
>
> /* all this casting makes me nervous... */
> KX_ClientObjectInfo* client_info
> = ( hitSMObj ?
> static_cast<KX_ClientObjectInfo*>( hitSMObj->getClientObject() ):
> NULL);
>
> if (!client_info)
> {
> std::cout<< "WARNING: MouseOver sensor " << GetName() << " cannot sense SM_Object " << hitSMObj << " - no client info.\n" << std::endl;
> return false;
> }
>
> KX_GameObject* hitKXObj = client_info->m_gameobject;
>
> if (client_info->m_type > KX_ClientObjectInfo::ACTOR)
> {
> // false hit
> KX_SumoPhysicsController *hitspc = dynamic_cast<KX_SumoPhysicsController *> (static_cast<KX_GameObject*> (hitKXObj) ->GetPhysicsController());
> if (hitspc)
> {
> /* We add 0.01 of fudge, so that if the margin && radius == 0., we don't endless loop. */
> MT_Scalar marg = 0.01 + hitspc->GetSumoObject()->getMargin();
> if (hitspc->GetSumoObject()->getShapeProps())
> {
> marg += 2*hitspc->GetSumoObject()->getShapeProps()->m_radius;
> }
>
> /* Calculate the other side of this object */
> MT_Point3 hitObjPos;
> hitspc->GetWorldPosition(hitObjPos);
> MT_Vector3 hitvector = hitObjPos - resultpoint;
> if (hitvector.dot(hitvector) > MT_EPSILON)
> {
> hitvector.normalize();
> marg *= 2.*todir.dot(hitvector);
> }
> frompoint3 = resultpoint + marg * todir;
> } else {
> return false;
> }
> continue;
> }
> /* Is this me? In the ray test, there are a lot of extra checks
> * for aliasing artefacts from self-hits. That doesn't happen
> * here, so a simple test suffices. Or does the camera also get
> * self-hits? (No, and the raysensor shouldn't do it either, since
> * self-hits are excluded by setting the correct ignore-object.)
> * Hitspots now become valid. */
> if (hitKXObj == thisObj)
> {
> m_hitPosition = resultpoint;
> m_hitNormal = resultnormal;
> return true;
> }
>
> return false;
> }
>
> return false;
> }
>
> /* ------------------------------------------------------------------------- */
> /* Python functions */
> /* ------------------------------------------------------------------------- */
>
> /* Integration hooks ------------------------------------------------------- */
> PyTypeObject KX_MouseFocusSensor::Type = {
> PyObject_HEAD_INIT(&PyType_Type)
> 0,
> "KX_MouseFocusSensor",
> sizeof(KX_MouseFocusSensor),
> 0,
> PyDestructor,
> 0,
> __getattr,
> __setattr,
> 0, //&MyPyCompare,
> __repr,
> 0, //&cvalue_as_number,
> 0,
> 0,
> 0,
> 0
> };
>
> PyParentObject KX_MouseFocusSensor::Parents[] = {
> &KX_MouseFocusSensor::Type,
> &SCA_MouseSensor::Type,
> &SCA_ISensor::Type,
> &SCA_ILogicBrick::Type,
> &CValue::Type,
> NULL
> };
>
> PyMethodDef KX_MouseFocusSensor::Methods[] = {
> {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget,
> METH_VARARGS, GetRayTarget_doc},
> {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource,
> METH_VARARGS, GetRaySource_doc},
> {NULL,NULL} //Sentinel
> };
>
> PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) {
> _getattr_up(SCA_MouseSensor);
> }
>
> /* getRayTarget */
> char KX_MouseFocusSensor::GetRayTarget_doc[] =
> "getRayTarget()\n"
> "\tReturns the target of the ray that seeks the focus object,\n"
> "\tin worldcoordinates.";
> PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self,
> PyObject* args,
> PyObject* kwds) {
> PyObject *retVal = PyList_New(3);
>
> PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0]));
> PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1]));
> PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2]));
>
> return retVal;
> }
>
> /* getRayTarget */
> char KX_MouseFocusSensor::GetRaySource_doc[] =
> "getRaySource()\n"
> "\tReturns the source of the ray that seeks the focus object,\n"
> "\tin worldcoordinates.";
> PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self,
> PyObject* args,
> PyObject* kwds) {
> PyObject *retVal = PyList_New(3);
>
> PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0]));
> PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1]));
> PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2]));
>
> return retVal;
> }
>
> /* eof */
>
>
More information about the Bf-committers
mailing list