Ticket #1213: 1213.4.diff
File 1213.4.diff, 9.5 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 … … 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 = (entity_id_t)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 = (entity_id_t)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 { 897 entity_id_t id = (entity_id_t)it->first; 898 // Check build Constraint 899 CheckObstructionAndUpdateVisual(id); 900 } 901 } 902 903 void Redo() 904 { 905 SetPos(m_PosNew); 906 } 907 908 void RecalculateRotation(Position newPoint) 909 { 910 std::vector<entity_id_t> ids = *msg->ids; 911 912 CVector3D target = newPoint.GetWorldSpace(m_centerPoint.Y); 913 float newAngle = atan2(target.X-m_centerPoint.X, target.Z-m_centerPoint.Z); 914 915 float globalAngle = m_angleInitialRotation - newAngle; 916 917 //Recalculate positions 918 for (size_t i = 0; i < ids.size(); ++i) 919 { 920 entity_id_t id = (entity_id_t)ids[i]; 921 922 CVector3D pos = m_PosOld[id]; 923 float angle = atan2(pos.X - m_centerPoint.X, pos.Z - m_centerPoint.Z); 924 float localAngle = angle + (globalAngle - angle); 925 float xCos = cosf(localAngle); 926 float xSin = sinf(localAngle); 927 928 pos.X -= m_centerPoint.X; 929 pos.Z -= m_centerPoint.Z; 930 931 float newX = pos.X * xCos - pos.Z * xSin; 932 float newZ = pos.X * xSin + pos.Z * xCos; 933 934 pos.X = newX + m_centerPoint.X; 935 pos.Z = newZ + m_centerPoint.Z; 936 937 m_PosNew[id] = pos; 938 939 float oldAngle = m_AngleOld[id]; 940 m_AngleNew[id] = oldAngle - globalAngle; 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_AngleOld = prev->m_AngleOld; 958 m_centerPoint = prev->m_centerPoint; 959 960 RecalculateRotation(msg->target); 961 } 962 }; 963 END_COMMAND(RotateObjectsFromCenterPoint) 964 769 965 BEGIN_COMMAND(RotateObject) 770 966 { 771 float m_AngleOld, m_AngleNew; 967 typedef std::map<entity_id_t, float> ObjectAngleMap; 968 ObjectAngleMap m_AngleOld, m_AngleNew; 772 969 773 970 void Do() 774 971 { 775 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 776 if (!cmpPosition) 777 return; 972 std::vector<entity_id_t> ids = *msg->ids; 778 973 779 m_AngleOld = cmpPosition->GetRotation().Y.ToFloat(); 780 if (msg->usetarget) 974 for (size_t i = 0; i < ids.size(); ++i) 781 975 { 976 entity_id_t id = (entity_id_t)ids[i]; 977 978 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 979 if (!cmpPosition) 980 return; 981 982 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 983 782 984 CMatrix3D transform = cmpPosition->GetInterpolatedTransform(0.f); 783 985 CVector3D pos = transform.GetTranslation(); 784 986 CVector3D target = msg->target->GetWorldSpace(pos.Y); 785 m_AngleNew = atan2(target.X-pos.X, target.Z-pos.Z);987 m_AngleNew[id] = atan2(target.X-pos.X, target.Z-pos.Z); 786 988 } 787 else788 {789 m_AngleNew = msg->angle;790 }791 989 792 990 SetAngle(m_AngleNew); 793 991 } 794 992 795 void SetAngle( float angle)993 void SetAngle(ObjectAngleMap angles) 796 994 { 797 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 798 if (!cmpPosition) 799 return; 995 ObjectAngleMap::iterator it; 996 for (it = angles.begin(); it != angles.end(); ++it) 997 { 998 entity_id_t id = (entity_id_t)it->first; 999 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 1000 if (!cmpPosition) 1001 return; 800 1002 801 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle)); 1003 cmpPosition->SetYRotation(entity_angle_t::FromFloat(it->second)); 1004 } 802 1005 } 803 1006 804 1007 void Redo() … … 814 1017 void MergeIntoPrevious(cRotateObject* prev) 815 1018 { 816 1019 // TODO: do something valid if prev unit != this unit 817 ENSURE( prev->msg->id == msg->id);1020 ENSURE(*prev->msg->ids == *msg->ids); 818 1021 prev->m_AngleNew = m_AngleNew; 819 1022 } 820 1023 }; -
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,