BGE Fix: [#19951] mouse over sensor is broken with letterboxing framing

Tested with GameLogic.mouse.position and mouse over sensor.
It should be working with other mouse sensor as well. If not, please help to test and report a bug.
(couldn't test blenderplayer but it should be working there as well).

(Benoit, this is the same patch that I sent you. I hope it's OOP enough. Looking forward to hear from you on that)

I believe that this was the last "mouse" related bug we had reported. MouseLoook scripts should be working 100% in Blender/BGE 2.50 now \o/
This commit is contained in:
Dalai Felinto 2010-04-23 22:48:26 +00:00
parent 62c0ac2dc9
commit edc56fae18
13 changed files with 112 additions and 17 deletions

@ -171,7 +171,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */
// create the canvas, rasterizer and rendertools
RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar);
canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
RAS_IRasterizer* rasterizer = NULL;
@ -371,7 +371,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
mousedevice,
networkdevice,
startscenename,
blscene);
blscene,
canvas);
#ifndef DISABLE_PYTHON
// some python things

@ -31,10 +31,13 @@
#include "stdio.h"
KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect) :
KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) :
m_win(win),
m_frame_rect(rect)
{
// area boundaries needed for mouse coordinates in Letterbox framing mode
m_area_left = ar->winrct.xmin;
m_area_top = ar->winrct.ymax;
}
KX_BlenderCanvas::~KX_BlenderCanvas()
@ -100,6 +103,30 @@ int KX_BlenderCanvas::GetHeight(
return m_frame_rect.GetHeight();
}
int KX_BlenderCanvas::GetMouseX(int x)
{
float left = GetWindowArea().GetLeft();
return float(x - (left - m_area_left));
}
int KX_BlenderCanvas::GetMouseY(int y)
{
float top = GetWindowArea().GetTop();
return float(y - (m_area_top - top));
}
float KX_BlenderCanvas::GetMouseNormalizedX(int x)
{
int can_x = GetMouseX(x);
return float(can_x)/this->GetWidth();
}
float KX_BlenderCanvas::GetMouseNormalizedY(int y)
{
int can_y = GetMouseY(y);
return float(can_y)/this->GetHeight();
}
RAS_Rect &
KX_BlenderCanvas::
GetWindowArea(

@ -64,7 +64,7 @@ public:
*
* @param area The Blender ARegion to run the game within.
*/
KX_BlenderCanvas(struct wmWindow* win, class RAS_Rect &rect);
KX_BlenderCanvas(struct wmWindow* win, class RAS_Rect &rect, struct ARegion* ar);
~KX_BlenderCanvas();
void
@ -109,6 +109,22 @@ public:
GetHeight(
) const ;
int
GetMouseX(int x
);
int
GetMouseY(int y
);
float
GetMouseNormalizedX(int x
);
float
GetMouseNormalizedY(int y
);
const
RAS_Rect &
GetDisplayArea(
@ -170,6 +186,8 @@ private:
struct wmWindow* m_win;
RAS_Rect m_frame_rect;
RAS_Rect m_area_rect;
short m_area_left;
short m_area_top;
#ifdef WITH_CXX_GUARDEDALLOC

@ -40,12 +40,15 @@
#include "SCA_MouseManager.h"
#include "SCA_MouseSensor.h"
#include "IntValue.h"
#include "RAS_ICanvas.h"
SCA_MouseManager::SCA_MouseManager(SCA_LogicManager* logicmgr,
SCA_IInputDevice* mousedev)
SCA_IInputDevice* mousedev,
RAS_ICanvas* canvas)
: SCA_EventManager(logicmgr, MOUSE_EVENTMGR),
m_mousedevice (mousedev)
m_mousedevice (mousedev),
m_canvas(canvas)
{
m_xpos = 0;
m_ypos = 0;
@ -78,12 +81,13 @@ void SCA_MouseManager::NextFrame()
// coordinates
if (!mousesensor->IsSuspended())
{
const SCA_InputEvent& event =
const SCA_InputEvent& event1 =
m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
int mx = event.m_eventval;
const SCA_InputEvent& event2 =
m_mousedevice->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
int my = event2.m_eventval;
int mx = this->m_canvas->GetMouseX(event1.m_eventval);
int my = this->m_canvas->GetMouseY(event2.m_eventval);
mousesensor->setX(mx);
mousesensor->setY(my);

@ -47,12 +47,13 @@ class SCA_MouseManager : public SCA_EventManager
{
class SCA_IInputDevice* m_mousedevice;
class RAS_ICanvas* m_canvas;
unsigned short m_xpos; // Cached location of the mouse pointer
unsigned short m_ypos;
public:
SCA_MouseManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* mousedev);
SCA_MouseManager(class SCA_LogicManager* logicmgr,class SCA_IInputDevice* mousedev, class RAS_ICanvas* canvas);
virtual ~SCA_MouseManager();
/**

@ -112,10 +112,15 @@ PyObject* SCA_PythonMouse::pyattr_get_position(void *self_v, const KX_PYATTRIBUT
const SCA_InputEvent & xevent = self->m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
const SCA_InputEvent & yevent = self->m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
float x_coord, y_coord;
x_coord = self->m_canvas->GetMouseNormalizedX(xevent.m_eventval);
y_coord = self->m_canvas->GetMouseNormalizedY(yevent.m_eventval);
PyObject* ret = PyTuple_New(2);
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(float(xevent.m_eventval)/self->m_canvas->GetWidth()));
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(float(yevent.m_eventval)/self->m_canvas->GetHeight()));
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(x_coord));
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(y_coord));
return ret;
}

@ -673,7 +673,8 @@ bool GPG_Application::startEngine(void)
m_mouse,
m_networkdevice,
startscenename,
m_startScene);
m_startScene,
m_canvas);
#ifndef DISABLE_PYTHON
// some python things

@ -104,3 +104,13 @@ void GPG_Canvas::SwapBuffers()
m_window->swapBuffers();
}
}
float GPG_Canvas::GetMouseNormalizedX(int x)
{
return float(x)/this->GetWidth();
}
float GPG_Canvas::GetMouseNormalizedY(int y)
{
return float(y)/this->GetHeight();
}

@ -53,6 +53,10 @@ public:
virtual void SetMousePosition(int x, int y);
virtual void SetMouseState(RAS_MouseState mousestate);
virtual void SwapBuffers();
virtual int GetMouseX(int x){return x;};
virtual int GetMouseY(int y){return y;};
virtual float GetMouseNormalizedX(int x);
virtual float GetMouseNormalizedY(int y);
bool BeginDraw() { return true;};
void EndDraw() {};

@ -1626,7 +1626,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
m_mousedevice,
m_networkdevice,
scene->id.name+2,
scene);
scene,
m_canvas);
m_sceneconverter->ConvertScene(tmpscene,
m_rendertools,

@ -139,7 +139,8 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
class SCA_IInputDevice* mousedevice,
class NG_NetworkDeviceInterface *ndi,
const STR_String& sceneName,
Scene *scene):
Scene *scene,
class RAS_ICanvas* canvas):
PyObjectPlus(),
m_keyboardmgr(NULL),
m_mousemgr(NULL),
@ -170,7 +171,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_timemgr = new SCA_TimeEventManager(m_logicmgr);
m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice);
m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice);
m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice, canvas);
//SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
//SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);

@ -45,6 +45,7 @@
#include "RAS_FramingManager.h"
#include "RAS_Rect.h"
#include "PyObjectPlus.h"
#include "RAS_2DFilterManager.h"
@ -280,7 +281,8 @@ public:
class SCA_IInputDevice* mousedevice,
class NG_NetworkDeviceInterface* ndi,
const STR_String& scenename,
struct Scene* scene);
struct Scene* scene,
class RAS_ICanvas* canvas);
virtual
~KX_Scene();

@ -130,6 +130,26 @@ public:
GetHeight(
) const = 0;
virtual
int
GetMouseX( int x
)=0;
virtual
int
GetMouseY( int y
)= 0;
virtual
float
GetMouseNormalizedX( int x
)=0;
virtual
float
GetMouseNormalizedY( int y
)= 0;
virtual
const RAS_Rect &
GetDisplayArea(