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