selector.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "selector.h"
  2. #include "boxcol.h"
  3. #include "forms\mainwindow.h"
  4. #include "attributes\AttributeList.h"
  5. extern MissionEditor* sMission;
  6. extern MOSafePointer pCurrentSelected; // Текущий выбранный объект
  7. extern TMainWindow* MainWindow;
  8. extern Matrix ViewPortProjectionMatrix;
  9. ObjectSelector::ObjectSelector () : ObjInTrace (_FL_)
  10. {
  11. LastIntersectionPoint = Vector(0.0f);
  12. Active = false;
  13. pRS = (IRender*)api->GetService("DX9Render");
  14. r1 = Vector (0.0f);
  15. r2 = Vector (0.0f);
  16. }
  17. ObjectSelector::~ObjectSelector ()
  18. {
  19. }
  20. bool ObjectSelector::GetIsActive ()
  21. {
  22. return Active;
  23. }
  24. void ObjectSelector::Draw ()
  25. {
  26. if (!Active) return;
  27. //pRS->DrawVector(r1, r2, 0xFFFFFF00);
  28. //for (int n =0; n < ObjInTrace; n++)
  29. //{
  30. //Vector point = ObjInTrace[n].point;
  31. //float distance = ObjInTrace[n].IntersectionDistance;
  32. //Color clr(distance, distance, distance);
  33. //pRS->DrawSphere(point, 0.5f, clr.GetDword());
  34. //pRS->DrawBox(ObjInTrace[n].bMin, ObjInTrace[n].bMax, ObjInTrace[n].bWorld, 0xFFFFFF00);
  35. //}
  36. }
  37. void ObjectSelector::Activate (bool Active)
  38. {
  39. this->Active = Active;
  40. }
  41. void ObjectSelector::MouseMove (const GUIPoint &ptCursor, const RENDERVIEWPORT& viewport)
  42. {
  43. if (!Active) return;
  44. }
  45. void ObjectSelector::ExtractRay (const RENDERVIEWPORT& viewport, const GUIPoint &ptCursor, Vector& raystart, Vector& rayend)
  46. {
  47. Matrix matProj = ViewPortProjectionMatrix;
  48. Vector v;
  49. v.x = ( ( ( 2.0f * ptCursor.x ) / viewport.Width ) - 1 ) / matProj.m[0][0];
  50. v.y = -( ( ( 2.0f * ptCursor.y ) / viewport.Height ) - 1 ) / matProj.m[1][1];
  51. v.z = 1.0f;
  52. Matrix mView = pRS->GetView();
  53. mView.Inverse ();
  54. Vector raydir;
  55. Vector rayorig;
  56. raydir = mView.MulNormal(v);
  57. rayorig = mView.pos;
  58. raystart = rayorig;
  59. rayend = (rayorig + (raydir * 100.f));
  60. }
  61. bool ObjectSelector::CompareFunc (const ObjectSelector::TracedObjects &item1, const ObjectSelector::TracedObjects &item2)
  62. {
  63. if (item1.IntersectionDistance < item2.IntersectionDistance) return true;
  64. return false;
  65. }
  66. void ObjectSelector::ButtonIsPressed (bool bPressed, const GUIPoint &ptCursor, const RENDERVIEWPORT& viewport)
  67. {
  68. static SlowBoxCollider BoxColl;
  69. if (!bPressed) return;
  70. if (!Active) return;
  71. ObjInTrace.DelAll();
  72. ExtractRay (viewport, ptCursor, r1, r2);
  73. // Надо протестить луч на пересечение со всеми коробками
  74. // и выбрать ближайшую
  75. for (DWORD i =0; i < sMission->GetCreatedMissionObjectsCount(); i++)
  76. {
  77. MOSafePointer missObj = sMission->GetCreatedMissionObjectByIndex(i);
  78. if (!missObj.SPtr()->EditMode_IsVisible()) continue;
  79. Vector min(0.0f), max(0.0f);
  80. missObj.Ptr()->EditMode_GetSelectBox(min, max);
  81. Matrix matWorld;
  82. missObj.Ptr()->GetMatrix (matWorld);
  83. BoxColl.Init(min, max, matWorld);
  84. float val = BoxColl.RayTrace(r1, r2);
  85. if (val > 0)
  86. {
  87. TracedObjects newEnt;
  88. newEnt.IntersectionDistance = val;
  89. newEnt.NearMissionObject = missObj;
  90. newEnt.mObj = &sMission->GetCreatedMissionObjectStructByIndex(i);
  91. newEnt.point = BoxColl.IntersectionPoint;
  92. newEnt.bMin = min;
  93. newEnt.bMax = max;
  94. newEnt.bWorld = matWorld;
  95. ObjInTrace.Add(newEnt);
  96. }
  97. }
  98. ObjInTrace.QSort(CompareFunc);
  99. //api->Trace ("TRACE START ------------------------");
  100. for (DWORD j = 0; j < ObjInTrace.Size(); j++)
  101. {
  102. const char* oName = ObjInTrace[j].NearMissionObject.Ptr()->GetObjectID().c_str();
  103. float d = ObjInTrace[j].IntersectionDistance;
  104. //api->Trace("[%d] Obj - %s, Distance - %3.2f", j, oName, d);
  105. }
  106. bool ControlState = false;
  107. if (GetAsyncKeyState(VK_CONTROL) < 0) ControlState = true;
  108. // simple like Maya selector
  109. if ((!ControlState) || !LastSelectedObject.Validate())
  110. {
  111. if (ObjInTrace.Size() >= 1)
  112. {
  113. SelectObject (0);
  114. }
  115. } else
  116. {
  117. bool NeedLoop = true;
  118. for (int i = 0; i < ObjInTrace; i++)
  119. {
  120. Vector cam_pos = pRS->GetView().GetCamPos();
  121. float new_dist = Vector(ObjInTrace[i].point - cam_pos).GetLength();
  122. float old_dist = Vector(LastIntersectionPoint - cam_pos).GetLength();
  123. if ((new_dist > old_dist) && (LastSelectedObject != ObjInTrace[i].NearMissionObject))
  124. {
  125. SelectObject (i);
  126. NeedLoop = false;
  127. break;
  128. }
  129. }
  130. if (NeedLoop) SelectObject (0);
  131. }
  132. }
  133. void ObjectSelector::SelectObject (int index)
  134. {
  135. if ((int)ObjInTrace.Size() <= index) return;
  136. ObjInTrace[index].NearMissionObject.SPtr()->EditMode_Select (true);
  137. if (pCurrentSelected.Validate()) pCurrentSelected.Ptr()->EditMode_Select (false);
  138. pCurrentSelected = ObjInTrace[index].NearMissionObject;
  139. LastSelectedObject = ObjInTrace[index].NearMissionObject;
  140. LastIntersectionPoint = ObjInTrace[index].point;
  141. MainWindow->TreeView1->ResetSelection(*MainWindow->TreeView1->Items);
  142. if (ObjInTrace[index].mObj)
  143. {
  144. string FullPath = ObjInTrace[index].mObj->PathInTree;
  145. FullPath += ObjInTrace[index].NearMissionObject.SPtr()->GetObjectID().c_str();
  146. GUITreeNode* fItem = MainWindow->TreeView1->FindItem (FullPath.GetBuffer ());
  147. if (fItem)
  148. {
  149. if (fItem->Parent) Expand (fItem->Parent);
  150. MainWindow->TreeView1->SetSelectedNode (fItem, false);
  151. }
  152. }
  153. }
  154. void ObjectSelector::Expand (GUITreeNode* fItem)
  155. {
  156. fItem->Expanded = true;
  157. if (fItem->Parent) Expand (fItem->Parent);
  158. }