Page 1 of 1

Unit selection from screen coordinates

Posted: Sun Mar 10, 2019 1:41 am
by Seven
looking for some help selecting units.

assume a 3d world with a top down camera, user presses LMouse to start selection rectangle and when LMouse is released we have a screen area highlighted.
if I use getRayFromScreenCoordinates then the ray is from the camera through the screen point and ends up not directly under the screen point but rather angled through the screen point.

how would I calculate a line that goes straight down through the corners of the screen selection rectangle?
I would then create an aabbox3d<f32> m_SelectionBox; that I can test units against to see if they were selected.

current attempt looks like this...

Code: Select all

 
        virtual bool onLMouseButtonUp(const SEvent & e)
        {
            if (m_Selecting)
            {
                if (getLevel())
                {
                    m_SelectedObjects.clear();
                    line3df l1 = getLevel()->getCollisionManager()->getRayFromScreenCoordinates(vector2di(m_ScreenSelectionArea.UpperLeftCorner.X, m_ScreenSelectionArea.UpperLeftCorner.Y));
                    line3df l2 = getLevel()->getCollisionManager()->getRayFromScreenCoordinates(vector2di(m_ScreenSelectionArea.LowerRightCorner.X, m_ScreenSelectionArea.LowerRightCorner.Y));
                    float BOX_DEPTH = 1000;
                    m_SelectionBox.MinEdge.set(vector3df(l1.end.X, -BOX_DEPTH, l1.end.Z));
                    m_SelectionBox.MaxEdge.set(vector3df(l2.end.X, BOX_DEPTH, l2.end.Z));
                    getLevel()->selectObjectsInArea(m_SelectionBox, FSOT_CHARACTER, m_SelectedObjects);
                }
            }
            m_Selecting = false;
            
            for (int x = 0; x < m_SelectedObjects.size(); x++) printf("Object in list %d\n",m_SelectedObjects[x]);
 
            return false;
        }
 

Re: Unit selection from screen coordinates

Posted: Mon Mar 11, 2019 12:53 pm
by CuteAlien
The floor of your level is some plane. getRayFromScreenCoordinates returns a ray going through that plane. So to find the exact point of collision use ray-plane intersection. plane3d has some functions for that (if your floor has height 0 and y is up then you can use the default constructor of plane3d which describes just such a plane).