Ticket #1213: 1213.diff
File 1213.diff, 9.3 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.size() > 0 && ((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 560 } 556 561 } 557 562 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 AtlasMessage::qCanPlaceObject canPlaceObject; 575 canPlaceObject.Post(); 576 canPlaceObjectResponse = canPlaceObject.response; 577 if (!canPlaceObjectResponse) 578 { 579 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 580 ScenarioEditor::GetCommandProc().Undo(); 581 } 582 } 583 SET_STATE(Waiting); 584 return true; 585 } 586 else if (evt.Dragging()) 587 { 588 bool newRotateFromCenterPoint = wxGetKeyState(SELECTION_ADD_HOTKEY); 589 if (newRotateFromCenterPoint != rotateFromCenterPoint) 590 { 591 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 592 rotateFromCenterPoint = newRotateFromCenterPoint; 593 } 594 595 Position pos(evt.GetPosition()); 596 597 if (rotateFromCenterPoint) 598 POST_COMMAND(RotateObjectsFromCenterPoint, (g_SelectedObjects, pos)); 599 else 600 POST_COMMAND(RotateObject, (g_SelectedObjects, pos)); 601 602 return true; 603 } 604 else 605 return false; 606 } 607 608 bool OnKey(TransformObject* obj, wxKeyEvent& evt, KeyEventType type) 609 { 610 if (type == KEY_UP && evt.GetKeyCode() == WXK_ESCAPE) 611 { 612 // Cancel move action 613 ScenarioEditor::GetCommandProc().FinaliseLastCommand(); 614 ScenarioEditor::GetCommandProc().Undo(); 615 SET_STATE(Waiting); 616 617 return true; 618 } 619 else 620 return false; 621 } 622 } 623 Rotating; 558 624 }; 559 625 560 626 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 … … 765 832 }; 766 833 END_COMMAND(MoveObjects) 767 834 835 BEGIN_COMMAND(RotateObjectsFromCenterPoint) 836 { 837 typedef std::map<entity_id_t, CVector3D> ObjectPositionMap; 838 ObjectPositionMap m_PosOld, m_PosNew; 839 CVector3D m_centerPoint = CVector3D(0,0,0); 840 float m_angleInitialRotation; 768 841 842 void Do() 843 { 844 std::vector<entity_id_t> ids = *msg->ids; 845 846 CVector3D minPos; 847 CVector3D maxPos; 848 849 //getting min position and max position 850 for (size_t i = 0; i < ids.size(); ++i) 851 { 852 entity_id_t id = (entity_id_t)ids[i]; 853 854 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 855 if (!cmpPosition) 856 continue; 857 858 CVector3D pos = cmpPosition->GetPosition(); 859 860 m_PosOld[id] = cmpPosition->GetPosition(); 861 862 if (i == 0) { 863 minPos = pos; 864 maxPos = pos; 865 m_centerPoint.Y = pos.Y; 866 continue; 867 } 868 869 if (pos.X < minPos.X) 870 minPos.X = pos.X; 871 872 if (pos.X > maxPos.X) 873 maxPos.X = pos.X; 874 875 if (pos.Z < minPos.Z) 876 minPos.Z = pos.Z; 877 878 if (pos.Z > maxPos.Z) 879 maxPos.Z = pos.Z; 880 } 881 882 //Calculate objects center point 883 m_centerPoint.X = maxPos.X - ((maxPos.X - minPos.X) * 0.5); 884 m_centerPoint.Z = maxPos.Z - ((maxPos.Z - minPos.Z) * 0.5); 885 886 CVector3D target = msg->target->GetWorldSpace(m_centerPoint.Y); 887 m_angleInitialRotation = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z); 888 } 889 890 void SetPos(ObjectPositionMap position) 891 { 892 ObjectPositionMap::iterator it; 893 for (it = position.begin(); it != position.end(); ++it) 894 { 895 entity_id_t id = (entity_id_t)it->first; 896 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 897 if (!cmpPosition) 898 return; 899 900 // Set 2D position, ignoring height 901 CVector3D pos = it->second; 902 cmpPosition->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 903 } 904 905 for (it = position.begin(); it != position.end(); ++it) 906 { 907 entity_id_t id = (entity_id_t)it->first; 908 //Check build Constraint 909 CheckObstructionAndUpdateVisual(id); 910 } 911 } 912 913 void Redo() 914 { 915 SetPos(m_PosNew); 916 } 917 918 void RecalculateRotation(Position newPoint) 919 { 920 std::vector<entity_id_t> ids = *msg->ids; 921 922 CVector3D target = newPoint.GetWorldSpace(m_centerPoint.Y); 923 float newAngle = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z); 924 925 float globalAngle = m_angleInitialRotation - newAngle; 926 927 //Recalculate positions 928 for (size_t i = 0; i < ids.size(); ++i) 929 { 930 entity_id_t id = (entity_id_t)ids[i]; 931 932 CVector3D pos = m_PosOld[id]; 933 float angle = atan2(pos.X - m_centerPoint.X, pos.Z - m_centerPoint.Z); 934 float localAngle = angle + (globalAngle - angle); 935 float xCos = cosf(localAngle); 936 float xSin = sinf(localAngle); 937 938 pos.X -= m_centerPoint.X; 939 pos.Z -= m_centerPoint.Z; 940 941 float newX = pos.X * xCos - pos.Z * xSin; 942 float newZ = pos.X * xSin + pos.Z * xCos; 943 944 pos.X = newX + m_centerPoint.X; 945 pos.Z = newZ + m_centerPoint.Z; 946 947 m_PosNew[id] = pos; 948 } 949 950 SetPos(m_PosNew); 951 } 952 953 void Undo() 954 { 955 SetPos(m_PosOld); 956 } 957 958 void MergeIntoPrevious(cRotateObjectsFromCenterPoint* prev) 959 { 960 // TODO: do something valid if prev unit != this unit 961 ENSURE(*prev->msg->ids == *msg->ids); 962 m_PosOld = prev->m_PosOld; 963 m_angleInitialRotation = prev->m_angleInitialRotation; 964 m_centerPoint = prev->m_centerPoint; 965 966 RecalculateRotation(msg->target); 967 } 968 }; 969 END_COMMAND(RotateObjectsFromCenterPoint) 970 769 971 BEGIN_COMMAND(RotateObject) 770 972 { 771 float m_AngleOld, m_AngleNew; 973 typedef std::map<entity_id_t, float> ObjectAngleMap; 974 ObjectAngleMap m_AngleOld, m_AngleNew; 772 975 773 976 void Do() 774 977 { 775 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 776 if (!cmpPosition) 777 return; 978 std::vector<entity_id_t> ids = *msg->ids; 778 979 779 m_AngleOld = cmpPosition->GetRotation().Y.ToFloat(); 780 if (msg->usetarget) 980 for (size_t i = 0; i < ids.size(); ++i) 781 981 { 982 entity_id_t id = (entity_id_t)ids[i]; 983 984 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 985 if (!cmpPosition) 986 return; 987 988 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 989 782 990 CMatrix3D transform = cmpPosition->GetInterpolatedTransform(0.f); 783 991 CVector3D pos = transform.GetTranslation(); 784 992 CVector3D target = msg->target->GetWorldSpace(pos.Y); 785 m_AngleNew = atan2(target.X-pos.X, target.Z-pos.Z);993 m_AngleNew[id] = atan2(target.X-pos.X, target.Z-pos.Z); 786 994 } 787 else788 {789 m_AngleNew = msg->angle;790 }791 995 792 996 SetAngle(m_AngleNew); 793 997 } 794 998 795 void SetAngle( float angle)999 void SetAngle(ObjectAngleMap angles) 796 1000 { 797 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 798 if (!cmpPosition) 799 return; 1001 ObjectAngleMap::iterator it; 1002 for (it = angles.begin(); it != angles.end(); ++it) 1003 { 1004 entity_id_t id = (entity_id_t)it->first; 1005 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 1006 if (!cmpPosition) 1007 return; 800 1008 801 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle)); 1009 cmpPosition->SetYRotation(entity_angle_t::FromFloat(it->second)); 1010 } 802 1011 } 803 1012 804 1013 void Redo() … … 814 1023 void MergeIntoPrevious(cRotateObject* prev) 815 1024 { 816 1025 // TODO: do something valid if prev unit != this unit 817 ENSURE( prev->msg->id == msg->id);1026 ENSURE(*prev->msg->ids == *msg->ids); 818 1027 prev->m_AngleNew = m_AngleNew; 819 1028 } 820 1029 }; -
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 588 ((Position, pos)) 580 589 ); 581 590 591 COMMAND(RotateObjectsFromCenterPoint, MERGE, 592 ((std::vector<ObjectID>, ids)) 593 ((Position, target)) 594 ); 595 582 596 COMMAND(RotateObject, MERGE, 583 ((ObjectID, id)) 584 ((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle' 597 ((std::vector<ObjectID>, ids)) 585 598 ((Position, target)) 586 ((float, angle))587 599 ); 588 600 589 601 COMMAND(DeleteObjects, NOMERGE,