Ticket #1213: 1213.2.diff

File 1213.2.diff, 11.0 KB (added by trompetin17, 9 years ago)
  • source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp

     
    1 /* Copyright (C) 2013 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    181181                return true;
    182182            else if (evt.LeftUp())
    183183            {
    184                 obj->m_Target = Position(evt.GetPosition());
    185                 // Create the actual object
    186                 obj->SendObjectMsg(false);
     184                AtlasMessage::qCanPlaceObject canPlaceObject;
     185                canPlaceObject.Post();
     186
     187                if (canPlaceObject.response)
     188                {
     189                    obj->m_Target = Position(evt.GetPosition());
     190                    // Create the actual object
     191                    obj->SendObjectMsg(false);
     192                }
    187193                // Go back to preview mode
    188194                SET_STATE(Waiting);
    189195                obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target;
  • source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    300300
    301301                return true;
    302302            }
    303             else if (g_SelectedObjects.size() == 1 && ((evt.Dragging() && evt.RightIsDown()) || evt.RightDown()))
     303            else if (!g_SelectedObjects.empty() && ((evt.Dragging() && evt.RightIsDown()) || evt.RightDown()))
    304304            {
    305                 // TODO: Rotation of selections with multiple objects?
    306 
    307                 // Dragging with right mouse button -> rotate objects to look
    308                 // at mouse
    309                 Position pos(evt.GetPosition());
    310                 for (size_t i = 0; i < g_SelectedObjects.size(); ++i)
    311                     POST_COMMAND(RotateObject, (g_SelectedObjects[i], true, pos, 0.f));
    312 
     305                SET_STATE(Rotating);
    313306                return true;
    314307            }
    315308            else if (evt.Moving())
     
    366359        {
    367360            if (evt.LeftUp())
    368361            {
     362                AtlasMessage::qCanPlaceObject canPlaceObject;
     363                canPlaceObject.Post();
     364
     365                if (!canPlaceObject.response)
     366                {
     367                    ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     368                    ScenarioEditor::GetCommandProc().Undo();
     369                }
    369370                SET_STATE(Waiting);
    370371                return true;
    371372            }
     
    536537            }
    537538            else if (evt.LeftDown())
    538539            {
    539                 //Place the object and update
    540                 obj->OnPasteEnd(false);
     540                AtlasMessage::qCanPlaceObject canPlaceObject;
     541                canPlaceObject.Post();
     542
     543                if (canPlaceObject.response)
     544                    obj->OnPasteEnd(false); //Place the object and update
     545
    541546                return true;
    542547            }
    543548            else
     
    555560        }
    556561    }
    557562    Pasting;
     563
     564    struct sRotating : public State
     565    {
     566        bool rotateFromCenterPoint = false;
     567        bool OnMouse(TransformObject* obj, wxMouseEvent& evt)
     568        {
     569            if (evt.RightUp())
     570            {
     571                bool canPlaceObjectResponse = false;
     572               
     573                while (!canPlaceObjectResponse)
     574                {
     575                    AtlasMessage::qCanPlaceObject canPlaceObject;
     576                    canPlaceObject.Post();
     577                    canPlaceObjectResponse = canPlaceObject.response;
     578                    if (!canPlaceObjectResponse)
     579                    {
     580                        ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     581                        ScenarioEditor::GetCommandProc().Undo();
     582                    }
     583                }
     584                SET_STATE(Waiting);
     585                return true;
     586            }
     587            else if (evt.Dragging())
     588            {
     589                bool newRotateFromCenterPoint = wxGetKeyState(SELECTION_ADD_HOTKEY);
     590                if (newRotateFromCenterPoint != rotateFromCenterPoint)
     591                {
     592                    ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     593                    rotateFromCenterPoint = newRotateFromCenterPoint;
     594                }
     595
     596                Position pos(evt.GetPosition());
     597
     598                if (rotateFromCenterPoint)
     599                    POST_COMMAND(RotateObjectsFromCenterPoint, (g_SelectedObjects, pos));
     600                else
     601                    POST_COMMAND(RotateObject, (g_SelectedObjects, pos));
     602
     603                return true;
     604            }
     605
     606            return false;
     607        }
     608
     609        bool OnKey(TransformObject* obj, wxKeyEvent& evt, KeyEventType type)
     610        {
     611            if (type == KEY_UP && evt.GetKeyCode() == WXK_ESCAPE)
     612            {
     613                // Cancel move action
     614                ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     615                ScenarioEditor::GetCommandProc().Undo();
     616                SET_STATE(Waiting);
     617
     618                return true;
     619            }
     620
     621            return false;
     622        }
     623    }
     624    Rotating;
    558625};
    559626
    560627IMPLEMENT_DYNAMIC_CLASS(TransformObject, StateDrivenTool<TransformObject>);
  • source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    765825};
    766826END_COMMAND(MoveObjects)
    767827
     828BEGIN_COMMAND(RotateObjectsFromCenterPoint)
     829{
     830    typedef std::map<entity_id_t, CVector3D> ObjectPositionMap;
     831    ObjectPositionMap m_PosOld, m_PosNew;
     832    CVector3D m_centerPoint = CVector3D(0,0,0);
     833    float m_angleInitialRotation;
    768834
     835    void Do()
     836    {
     837        std::vector<entity_id_t> ids = *msg->ids;
     838
     839        CVector3D minPos;
     840        CVector3D maxPos;
     841
     842        //getting min position and max position
     843        for (size_t i = 0; i < ids.size(); ++i)
     844        {
     845            entity_id_t id = (entity_id_t)ids[i];
     846
     847            CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id);
     848            if (!cmpPosition)
     849                continue;
     850
     851            CVector3D pos = cmpPosition->GetPosition();
     852
     853            m_PosOld[id] = cmpPosition->GetPosition();
     854
     855            if (i == 0) {
     856                minPos = pos;
     857                maxPos = pos;
     858                m_centerPoint.Y = pos.Y;
     859                continue;
     860            }
     861
     862            if (pos.X < minPos.X)
     863                minPos.X = pos.X;
     864
     865            if (pos.X > maxPos.X)
     866                maxPos.X = pos.X;
     867
     868            if (pos.Z < minPos.Z)
     869                minPos.Z = pos.Z;
     870
     871            if (pos.Z > maxPos.Z)
     872                maxPos.Z = pos.Z;
     873        }
     874
     875        //Calculate objects center point
     876        m_centerPoint.X = maxPos.X - ((maxPos.X - minPos.X) * 0.5);
     877        m_centerPoint.Z = maxPos.Z - ((maxPos.Z - minPos.Z) * 0.5);
     878
     879        CVector3D target = msg->target->GetWorldSpace(m_centerPoint.Y);
     880        m_angleInitialRotation = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z);
     881    }
     882
     883    void SetPos(ObjectPositionMap position)
     884    {
     885        ObjectPositionMap::iterator it;
     886        for (it = position.begin(); it != position.end(); ++it)
     887        {
     888            entity_id_t id = (entity_id_t)it->first;
     889            CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id);
     890            if (!cmpPosition)
     891                return;
     892
     893            // Set 2D position, ignoring height
     894            CVector3D pos = it->second;
     895            cmpPosition->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z));
     896        }
     897
     898        for (it = position.begin(); it != position.end(); ++it)
     899        {
     900            entity_id_t id = (entity_id_t)it->first;
     901            //Check build Constraint
     902            CheckObstructionAndUpdateVisual(id);
     903        }
     904    }
     905
     906    void Redo()
     907    {
     908        SetPos(m_PosNew);
     909    }
     910
     911    void RecalculateRotation(Position newPoint)
     912    {
     913        std::vector<entity_id_t> ids = *msg->ids;
     914
     915        CVector3D target = newPoint.GetWorldSpace(m_centerPoint.Y);
     916        float newAngle = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z);
     917
     918        float globalAngle = m_angleInitialRotation - newAngle;
     919
     920        //Recalculate positions
     921        for (size_t i = 0; i < ids.size(); ++i)
     922        {
     923            entity_id_t id = (entity_id_t)ids[i];
     924
     925            CVector3D pos = m_PosOld[id];
     926            float angle = atan2(pos.X - m_centerPoint.X, pos.Z - m_centerPoint.Z);
     927            float localAngle = angle + (globalAngle - angle);
     928            float xCos = cosf(localAngle);
     929            float xSin = sinf(localAngle);
     930
     931            pos.X -= m_centerPoint.X;
     932            pos.Z -= m_centerPoint.Z;
     933
     934            float newX = pos.X * xCos - pos.Z * xSin;
     935            float newZ = pos.X * xSin + pos.Z * xCos;
     936
     937            pos.X = newX + m_centerPoint.X;
     938            pos.Z = newZ + m_centerPoint.Z;
     939
     940            m_PosNew[id] = pos;
     941        }
     942
     943        SetPos(m_PosNew);
     944    }
     945
     946    void Undo()
     947    {
     948        SetPos(m_PosOld);
     949    }
     950
     951    void MergeIntoPrevious(cRotateObjectsFromCenterPoint* prev)
     952    {
     953        // TODO: do something valid if prev unit != this unit
     954        ENSURE(*prev->msg->ids == *msg->ids);
     955        m_PosOld = prev->m_PosOld;
     956        m_angleInitialRotation = prev->m_angleInitialRotation;
     957        m_centerPoint = prev->m_centerPoint;
     958
     959        RecalculateRotation(msg->target);
     960    }
     961};
     962END_COMMAND(RotateObjectsFromCenterPoint)
     963
    769964BEGIN_COMMAND(RotateObject)
    770965{
    771     float m_AngleOld, m_AngleNew;
     966    typedef std::map<entity_id_t, float> ObjectAngleMap;
     967    ObjectAngleMap m_AngleOld, m_AngleNew;
    772968
    773969    void Do()
    774970    {
    775         CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id);
    776         if (!cmpPosition)
    777             return;
     971        std::vector<entity_id_t> ids = *msg->ids;
    778972
    779         m_AngleOld = cmpPosition->GetRotation().Y.ToFloat();
    780         if (msg->usetarget)
     973        for (size_t i = 0; i < ids.size(); ++i)
    781974        {
     975            entity_id_t id = (entity_id_t)ids[i];
     976
     977            CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id);
     978            if (!cmpPosition)
     979                return;
     980
     981            m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat();
     982
    782983            CMatrix3D transform = cmpPosition->GetInterpolatedTransform(0.f);
    783984            CVector3D pos = transform.GetTranslation();
    784985            CVector3D target = msg->target->GetWorldSpace(pos.Y);
    785             m_AngleNew = atan2(target.X-pos.X, target.Z-pos.Z);
     986            m_AngleNew[id] = atan2(target.X-pos.X, target.Z-pos.Z);
    786987        }
    787         else
    788         {
    789             m_AngleNew = msg->angle;
    790         }
    791988
    792989        SetAngle(m_AngleNew);
    793990    }
    794991
    795     void SetAngle(float angle)
     992    void SetAngle(ObjectAngleMap angles)
    796993    {
    797         CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id);
    798         if (!cmpPosition)
    799             return;
     994        ObjectAngleMap::iterator it;
     995        for (it = angles.begin(); it != angles.end(); ++it)
     996        {
     997            entity_id_t id = (entity_id_t)it->first;
     998            CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id);
     999            if (!cmpPosition)
     1000                return;
    8001001
    801         cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle));
     1002            cmpPosition->SetYRotation(entity_angle_t::FromFloat(it->second));
     1003        }
    8021004    }
    8031005
    8041006    void Redo()
     
    8141016    void MergeIntoPrevious(cRotateObject* prev)
    8151017    {
    8161018        // TODO: do something valid if prev unit != this unit
    817         ENSURE(prev->msg->id == msg->id);
     1019        ENSURE(*prev->msg->ids == *msg->ids);
    8181020        prev->m_AngleNew = m_AngleNew;
    8191021    }
    8201022};
  • source/tools/atlas/GameInterface/Messages.h

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    579588        ((Position, pos))
    580589        );
    581590
     591COMMAND(RotateObjectsFromCenterPoint, MERGE,
     592        ((std::vector<ObjectID>, ids))
     593        ((Position, target))
     594        );
     595
    582596COMMAND(RotateObject, MERGE,
    583         ((ObjectID, id))
    584         ((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle'
     597        ((std::vector<ObjectID>, ids))
    585598        ((Position, target))
    586         ((float, angle))
    587599        );
    588600
    589601COMMAND(DeleteObjects, NOMERGE,