Ticket #1213: 1213.8.diff
File 1213.8.diff, 8.9 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 = true; 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() && !evt.ShiftDown(); 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
811 837 }; 812 838 END_COMMAND(MoveObjects) 813 839 840 BEGIN_COMMAND(RotateObjectsFromCenterPoint) 841 { 842 typedef std::map<entity_id_t, CVector3D> ObjectPositionMap; 843 typedef std::map<entity_id_t, float> ObjectAngleMap; 844 ObjectPositionMap m_PosOld, m_PosNew; 845 ObjectAngleMap m_AngleOld, m_AngleNew; 846 CVector3D m_CenterPoint; 847 float m_AngleInitialRotation; 814 848 849 void Do() 850 { 851 std::vector<entity_id_t> ids = *msg->ids; 852 853 CVector3D minPos; 854 CVector3D maxPos; 855 856 //getting min position and max position 857 for (size_t i = 0; i < ids.size(); ++i) 858 { 859 entity_id_t id = ids[i]; 860 861 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 862 if (!cmpPosition) 863 continue; 864 865 CVector3D pos = cmpPosition->GetPosition(); 866 867 m_PosOld[id] = cmpPosition->GetPosition(); 868 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 869 870 if (i == 0) { 871 minPos = pos; 872 maxPos = pos; 873 m_CenterPoint.Y = pos.Y; 874 continue; 875 } 876 877 if (pos.X < minPos.X) 878 minPos.X = pos.X; 879 880 if (pos.X > maxPos.X) 881 maxPos.X = pos.X; 882 883 if (pos.Z < minPos.Z) 884 minPos.Z = pos.Z; 885 886 if (pos.Z > maxPos.Z) 887 maxPos.Z = pos.Z; 888 } 889 890 //Calculate objects center point 891 m_CenterPoint.X = maxPos.X - ((maxPos.X - minPos.X) * 0.5); 892 m_CenterPoint.Z = maxPos.Z - ((maxPos.Z - minPos.Z) * 0.5); 893 894 CVector3D target = msg->target->GetWorldSpace(m_CenterPoint.Y); 895 m_AngleInitialRotation = atan2(target.X-m_CenterPoint.X, target.Z-m_CenterPoint.Z); 896 } 897 898 void SetPos(ObjectPositionMap position, ObjectAngleMap angle) 899 { 900 ObjectPositionMap::iterator it; 901 for (it = position.begin(); it != position.end(); ++it) 902 { 903 entity_id_t id = it->first; 904 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 905 if (!cmpPosition) 906 return; 907 908 // Set 2D position, ignoring height 909 CVector3D pos = it->second; 910 cmpPosition->JumpTo(entity_pos_t::FromFloat(pos.X), entity_pos_t::FromFloat(pos.Z)); 911 912 if (msg->rotateObject) 913 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle[id])); 914 915 } 916 917 for (it = position.begin(); it != position.end(); ++it) 918 CheckObstructionAndUpdateVisual(it->first); 919 } 920 921 void Redo() 922 { 923 SetPos(m_PosNew, m_AngleNew); 924 } 925 926 void RecalculateRotation(Position newPoint) 927 { 928 std::vector<entity_id_t> ids = *msg->ids; 929 930 CVector3D target = newPoint.GetWorldSpace(m_CenterPoint.Y); 931 float newAngle = atan2(target.X-m_CenterPoint.X, target.Z-m_CenterPoint.Z); 932 933 float globalAngle = m_AngleInitialRotation - newAngle; 934 935 //Recalculate positions 936 for (size_t i = 0; i < ids.size(); ++i) 937 { 938 entity_id_t id = ids[i]; 939 940 CVector3D pos = m_PosOld[id]; 941 float angle = atan2(pos.X - m_CenterPoint.X, pos.Z - m_CenterPoint.Z); 942 float localAngle = angle + (globalAngle - angle); 943 float xCos = cosf(localAngle); 944 float xSin = sinf(localAngle); 945 946 pos.X -= m_CenterPoint.X; 947 pos.Z -= m_CenterPoint.Z; 948 949 float newX = pos.X * xCos - pos.Z * xSin; 950 float newZ = pos.X * xSin + pos.Z * xCos; 951 952 pos.X = newX + m_CenterPoint.X; 953 pos.Z = newZ + m_CenterPoint.Z; 954 955 m_PosNew[id] = pos; 956 957 m_AngleNew[id] = m_AngleOld[id] - globalAngle; 958 } 959 960 SetPos(m_PosNew, m_AngleNew); 961 } 962 963 void Undo() 964 { 965 SetPos(m_PosOld, m_AngleOld); 966 } 967 968 void MergeIntoPrevious(cRotateObjectsFromCenterPoint* prev) 969 { 970 // TODO: do something valid if prev unit != this unit 971 ENSURE(*prev->msg->ids == *msg->ids); 972 m_PosOld = prev->m_PosOld; 973 m_AngleInitialRotation = prev->m_AngleInitialRotation; 974 m_AngleOld = prev->m_AngleOld; 975 m_CenterPoint = prev->m_CenterPoint; 976 977 RecalculateRotation(msg->target); 978 } 979 }; 980 END_COMMAND(RotateObjectsFromCenterPoint) 981 815 982 BEGIN_COMMAND(RotateObject) 816 983 { 817 float m_AngleOld, m_AngleNew; 984 typedef std::map<entity_id_t, float> ObjectAngleMap; 985 ObjectAngleMap m_AngleOld, m_AngleNew; 818 986 819 987 void Do() 820 988 { 821 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 822 if (!cmpPosition) 823 return; 989 std::vector<entity_id_t> ids = *msg->ids; 824 990 825 m_AngleOld = cmpPosition->GetRotation().Y.ToFloat(); 826 if (msg->usetarget) 991 for (size_t i = 0; i < ids.size(); ++i) 827 992 { 993 entity_id_t id = (entity_id_t)ids[i]; 994 995 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 996 if (!cmpPosition) 997 return; 998 999 m_AngleOld[id] = cmpPosition->GetRotation().Y.ToFloat(); 1000 828 1001 CMatrix3D transform = cmpPosition->GetInterpolatedTransform(0.f); 829 1002 CVector3D pos = transform.GetTranslation(); 830 1003 CVector3D target = msg->target->GetWorldSpace(pos.Y); 831 m_AngleNew = atan2(target.X-pos.X, target.Z-pos.Z);1004 m_AngleNew[id] = atan2(target.X-pos.X, target.Z-pos.Z); 832 1005 } 833 else834 {835 m_AngleNew = msg->angle;836 }837 1006 838 1007 SetAngle(m_AngleNew); 839 1008 } 840 1009 841 void SetAngle( float angle)1010 void SetAngle(ObjectAngleMap angles) 842 1011 { 843 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), (entity_id_t)msg->id); 844 if (!cmpPosition) 845 return; 1012 ObjectAngleMap::iterator it; 1013 for (it = angles.begin(); it != angles.end(); ++it) 1014 { 1015 entity_id_t id = (entity_id_t)it->first; 1016 CmpPtr<ICmpPosition> cmpPosition(*g_Game->GetSimulation2(), id); 1017 if (!cmpPosition) 1018 return; 846 1019 847 cmpPosition->SetYRotation(entity_angle_t::FromFloat(angle)); 1020 cmpPosition->SetYRotation(entity_angle_t::FromFloat(it->second)); 1021 } 848 1022 } 849 1023 850 1024 void Redo() … … 860 1034 void MergeIntoPrevious(cRotateObject* prev) 861 1035 { 862 1036 // TODO: do something valid if prev unit != this unit 863 ENSURE( prev->msg->id == msg->id);1037 ENSURE(*prev->msg->ids == *msg->ids); 864 1038 prev->m_AngleNew = m_AngleNew; 865 1039 } 866 1040 }; -
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,