Ticket #1213: 1213.5.diff
File 1213.5.diff, 9.7 KB (added by , 9 years ago) |
---|
-
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/TransformObject.cpp
1 /* Copyright (C) 201 4Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 300 300 301 301 return true; 302 302 } 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())) 304 304 { 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); 313 306 return true; 314 307 } 315 308 else if (evt.Moving()) … … 555 550 } 556 551 } 557 552 Pasting; 553 554 struct sRotating : public State 555 { 556 bool rotateFromCenterPoint = false; 557 bool OnMouse(TransformObject* obj, wxMouseEvent& evt) 558 { 559 if (evt.RightUp()) 560 { 561 POST_MESSAGE(UpdateVisualSelectedObjects, ()); 562 SET_STATE(Waiting); 563 return true; 564 } 565 else if (evt.Dragging()) 566 { 567 bool newRotateFromCenterPointAndObjectItself = evt.ControlDown(); 568 bool newRotateFromCenterPoint = evt.ShiftDown() || newRotateFromCenterPointAndObjectItself; 569 if (newRotateFromCenterPoint != rotateFromCenterPoint) 570 { 571 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 572 rotateFromCenterPoint = newRotateFromCenterPoint; 573 } 574 575 Position pos(evt.GetPosition()); 576 577 if (rotateFromCenterPoint) 578 POST_COMMAND(RotateObjectsFromCenterPoint, (g_SelectedObjects, pos, newRotateFromCenterPointAndObjectItself)); 579 else 580 POST_COMMAND(RotateObject, (g_SelectedObjects, pos)); 581 582 return true; 583 } 584 585 return false; 586 } 587 588 bool OnKey(TransformObject* obj, wxKeyEvent& evt, KeyEventType type) 589 { 590 if (type == KEY_UP && evt.GetKeyCode() == WXK_ESCAPE) 591 { 592 // Cancel move action 593 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 594 ScenarioEditor::GetCommandProc().Undo(); 595 SET_STATE(Waiting); 596 597 return true; 598 } 599 600 return false; 601 } 602 } 603 Rotating; 558 604 }; 559 605 560 606 IMPLEMENT_DYNAMIC_CLASS(TransformObject, StateDrivenTool<TransformObject>); -
source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp
1 /* Copyright (C) 201 4Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 41 41 #include "renderer/Renderer.h" 42 42 #include "renderer/WaterManager.h" 43 43 #include "simulation2/Simulation2.h" 44 #include "simulation2/components/ICmpObstruction.h" 44 45 #include "simulation2/components/ICmpOwnership.h" 45 46 #include "simulation2/components/ICmpPosition.h" 46 47 #include "simulation2/components/ICmpPlayer.h" … … 765 815 }; 766 816 END_COMMAND(MoveObjects) 767 817 818 BEGIN_COMMAND(RotateObjectsFromCenterPoint) 819 { 820 typedef std::map<entity_id_t, CVector3D> ObjectPositionMap; 821 typedef std::map<entity_id_t, float> ObjectAngleMap; 822 ObjectPositionMap m_PosOld, m_PosNew; 823 ObjectAngleMap m_AngleOld, m_AngleNew; 824 CVector3D m_centerPoint = CVector3D(0,0,0); 825 float m_angleInitialRotation; 768 826 827 void Do() 828 { 829 std::vector<entity_id_t> ids = *msg->ids; 830 831 CVector3D minPos; 832 CVector3D maxPos; 833 834 //getting min position and max position 835 for (size_t i = 0; i < ids.size(); ++i) 836 { 837 entity_id_t id = ids[i]; 838 839 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 840 if (!cmpPosition) 841 continue; 842 843 CVector3D pos = cmpPosition->GetPosition(); 844 845 m_PosOld[id] = cmpPosition->GetPosition(); 846 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 847 848 if (i == 0) { 849 minPos = pos; 850 maxPos = pos; 851 m_centerPoint.Y = pos.Y; 852 continue; 853 } 854 855 if (pos.X < minPos.X) 856 minPos.X = pos.X; 857 858 if (pos.X > maxPos.X) 859 maxPos.X = pos.X; 860 861 if (pos.Z < minPos.Z) 862 minPos.Z = pos.Z; 863 864 if (pos.Z > maxPos.Z) 865 maxPos.Z = pos.Z; 866 } 867 868 //Calculate objects center point 869 m_centerPoint.X = maxPos.X - ((maxPos.X - minPos.X) * 0.5); 870 m_centerPoint.Z = maxPos.Z - ((maxPos.Z - minPos.Z) * 0.5); 871 872 CVector3D target = msg->target->GetWorldSpace(m_centerPoint.Y); 873 m_angleInitialRotation = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z); 874 } 875 876 void SetPos(ObjectPositionMap position) 877 { 878 ObjectPositionMap::iterator it; 879 for (it = position.begin(); it != position.end(); ++it) 880 { 881 entity_id_t id = it->first; 882 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 883 if (!cmpPosition) 884 return; 885 886 // Set 2D position, ignoring height 887 CVector3D pos = it->second; 888 cmpPosition->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 889 890 if (msg->rotateObject) 891 cmpPosition->SetYRotation(entity_angle_t::FromFloat(m_AngleNew[id])); 892 893 } 894 895 for (it = position.begin(); it != position.end(); ++it) 896 CheckObstructionAndUpdateVisual(it->first); 897 } 898 899 void Redo() 900 { 901 SetPos(m_PosNew); 902 } 903 904 void RecalculateRotation(Position newPoint) 905 { 906 std::vector<entity_id_t> ids = *msg->ids; 907 908 CVector3D target = newPoint.GetWorldSpace(m_centerPoint.Y); 909 float newAngle = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z); 910 911 float globalAngle = m_angleInitialRotation - newAngle; 912 913 //Recalculate positions 914 for (size_t i = 0; i < ids.size(); ++i) 915 { 916 entity_id_t id = ids[i]; 917 918 CVector3D pos = m_PosOld[id]; 919 float angle = atan2(pos.X - m_centerPoint.X, pos.Z - m_centerPoint.Z); 920 float localAngle = angle + (globalAngle - angle); 921 float xCos = cosf(localAngle); 922 float xSin = sinf(localAngle); 923 924 pos.X -= m_centerPoint.X; 925 pos.Z -= m_centerPoint.Z; 926 927 float newX = pos.X * xCos - pos.Z * xSin; 928 float newZ = pos.X * xSin + pos.Z * xCos; 929 930 pos.X = newX + m_centerPoint.X; 931 pos.Z = newZ + m_centerPoint.Z; 932 933 m_PosNew[id] = pos; 934 935 m_AngleNew[id] = m_AngleOld[id] - globalAngle; 936 } 937 938 SetPos(m_PosNew); 939 } 940 941 void Undo() 942 { 943 SetPos(m_PosOld); 944 } 945 946 void MergeIntoPrevious(cRotateObjectsFromCenterPoint* prev) 947 { 948 // TODO: do something valid if prev unit != this unit 949 ENSURE(*prev->msg->ids == *msg->ids); 950 m_PosOld = prev->m_PosOld; 951 m_angleInitialRotation = prev->m_angleInitialRotation; 952 m_AngleOld = prev->m_AngleOld; 953 m_centerPoint = prev->m_centerPoint; 954 955 RecalculateRotation(msg->target); 956 } 957 }; 958 END_COMMAND(RotateObjectsFromCenterPoint) 959 769 960 BEGIN_COMMAND(RotateObject) 770 961 { 771 float m_AngleOld, m_AngleNew; 962 typedef std::map<entity_id_t, float> ObjectAngleMap; 963 ObjectAngleMap m_AngleOld, m_AngleNew; 772 964 773 965 void Do() 774 966 { 775 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 776 if (!cmpPosition) 777 return; 967 std::vector<entity_id_t> ids = *msg->ids; 778 968 779 m_AngleOld = cmpPosition->GetRotation().Y.ToFloat(); 780 if (msg->usetarget) 969 for (size_t i = 0; i < ids.size(); ++i) 781 970 { 971 entity_id_t id = (entity_id_t)ids[i]; 972 973 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 974 if (!cmpPosition) 975 return; 976 977 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 978 782 979 CMatrix3D transform = cmpPosition->GetInterpolatedTransform(0.f); 783 980 CVector3D pos = transform.GetTranslation(); 784 981 CVector3D target = msg->target->GetWorldSpace(pos.Y); 785 m_AngleNew = atan2(target.X-pos.X, target.Z-pos.Z);982 m_AngleNew[id] = atan2(target.X-pos.X, target.Z-pos.Z); 786 983 } 787 else788 {789 m_AngleNew = msg->angle;790 }791 984 792 985 SetAngle(m_AngleNew); 793 986 } 794 987 795 void SetAngle( float angle)988 void SetAngle(ObjectAngleMap angles) 796 989 { 797 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 798 if (!cmpPosition) 799 return; 990 ObjectAngleMap::iterator it; 991 for (it = angles.begin(); it != angles.end(); ++it) 992 { 993 entity_id_t id = (entity_id_t)it->first; 994 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 995 if (!cmpPosition) 996 return; 800 997 801 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle)); 998 cmpPosition->SetYRotation(entity_angle_t::FromFloat(it->second)); 999 } 802 1000 } 803 1001 804 1002 void Redo() … … 814 1012 void MergeIntoPrevious(cRotateObject* prev) 815 1013 { 816 1014 // TODO: do something valid if prev unit != this unit 817 ENSURE( prev->msg->id == msg->id);1015 ENSURE(*prev->msg->ids == *msg->ids); 818 1016 prev->m_AngleNew = m_AngleNew; 819 1017 } 820 1018 }; -
source/tools/atlas/GameInterface/Messages.h
1 /* Copyright (C) 201 4Wildfire Games.1 /* Copyright (C) 2015 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 579 585 ((Position, pos)) 580 586 ); 581 587 588 COMMAND(RotateObjectsFromCenterPoint, MERGE, 589 ((std::vector<ObjectID>, ids)) 590 ((Position, target)) 591 ((bool, rotateObject)) 592 ); 593 582 594 COMMAND(RotateObject, MERGE, 583 ((ObjectID, id)) 584 ((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle' 595 ((std::vector<ObjectID>, ids)) 585 596 ((Position, target)) 586 ((float, angle))587 597 ); 588 598 589 599 COMMAND(DeleteObjects, NOMERGE,