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