BGE Fix: [#19951] mouse over sensor is broken with letterboxing framing
authorDalai Felinto <dfelinto@gmail.com>
Fri, 23 Apr 2010 22:48:26 +0000 (22:48 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Fri, 23 Apr 2010 22:48:26 +0000 (22:48 +0000)
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/

13 files changed:
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
source/gameengine/GameLogic/SCA_MouseManager.cpp
source/gameengine/GameLogic/SCA_MouseManager.h
source/gameengine/GameLogic/SCA_PythonMouse.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
source/gameengine/GamePlayer/ghost/GPG_Canvas.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Rasterizer/RAS_ICanvas.h

index 4137dc376389f8fead38ff67af52e843b5bd67b2..5b7ceaa296c51942e5166e7d3521c6ed7680af8d 100644 (file)
@@ -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
index ec6923e280e185ca85ff4fb4813f451933ecb77c..b04e951028d3a6a3d806c41d00f709049752b4bb 100644 (file)
 #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(
index f352a082421ddfd322fd060d4e8003a3e331198c..0d80bdee0551b6216278db8a52a43eb4cdbc7071 100644 (file)
@@ -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
index 19d7422df1dd564c1f8aa81faaf01efa6f577f62..f7f9a566c8dd9e4a36f7807811c76d7bf828770a 100644 (file)
 #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);
index 82a8c996ef5e200dc935f49db1ebd5bc4ab170f6..0e7dfa2a284fd0a766c49b4cc244f067affa7436 100644 (file)
@@ -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();
 
        /**
index ccbac882c968513b1ec76e59ac7b41154b917a45..b2bb68f020e770079d65f35241a48bdd8b042375 100644 (file)
@@ -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;
 }
index 18043849bf3098ac8d8ed5dd7d71960c366afa57..7c3a6adf881561cce85df6bdad40f90503e146c8 100644 (file)
@@ -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
index 6b478c1ab4efe60d1bb52fa53e713d4d1bef5c18..24c0102a87c123287660e331700643a8c104c780 100644 (file)
@@ -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();
+}
index 18e58691d2c70fa3063e71e8aac880521b9b1c87..7b19c03d3c3978bea7c478ba717be0e2050fb58f 100644 (file)
@@ -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() {};
index a13cd71fdacdb957ea77acd468a3ca44ed1e973d..71cd8b36045d8be824aff61a9a698d02a48ce3a9 100644 (file)
@@ -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,
index 5bcaa3ee01e7a4c9e5c3d78018aa7b765b060b4a..5249c91832e0e4e44fab3cbde8893d949a3be1cf 100644 (file)
@@ -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);
index 407f3f1cf1aabe2b2fb49a2eb7459b997d001016..4755eee6a6be8c0f4de781b11fa847d36f5f8530 100644 (file)
@@ -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();
index 0821e369f75757c5bf1643b4380728e5c8ac6769..339521cb093aff97ad5b43ff8acdedcd65f48e2b 100644 (file)
@@ -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(