| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #include "selector.h"
- #include "boxcol.h"
- #include "forms\mainwindow.h"
- #include "attributes\AttributeList.h"
- extern MissionEditor* sMission;
- extern MOSafePointer pCurrentSelected; // Текущий выбранный объект
- extern TMainWindow* MainWindow;
- extern Matrix ViewPortProjectionMatrix;
- ObjectSelector::ObjectSelector () : ObjInTrace (_FL_)
- {
- LastIntersectionPoint = Vector(0.0f);
- Active = false;
- pRS = (IRender*)api->GetService("DX9Render");
- r1 = Vector (0.0f);
- r2 = Vector (0.0f);
- }
- ObjectSelector::~ObjectSelector ()
- {
- }
-
- bool ObjectSelector::GetIsActive ()
- {
- return Active;
- }
- void ObjectSelector::Draw ()
- {
- if (!Active) return;
- //pRS->DrawVector(r1, r2, 0xFFFFFF00);
- //for (int n =0; n < ObjInTrace; n++)
- //{
- //Vector point = ObjInTrace[n].point;
- //float distance = ObjInTrace[n].IntersectionDistance;
- //Color clr(distance, distance, distance);
- //pRS->DrawSphere(point, 0.5f, clr.GetDword());
- //pRS->DrawBox(ObjInTrace[n].bMin, ObjInTrace[n].bMax, ObjInTrace[n].bWorld, 0xFFFFFF00);
- //}
- }
- void ObjectSelector::Activate (bool Active)
- {
- this->Active = Active;
- }
- void ObjectSelector::MouseMove (const GUIPoint &ptCursor, const RENDERVIEWPORT& viewport)
- {
- if (!Active) return;
- }
- void ObjectSelector::ExtractRay (const RENDERVIEWPORT& viewport, const GUIPoint &ptCursor, Vector& raystart, Vector& rayend)
- {
- Matrix matProj = ViewPortProjectionMatrix;
- Vector v;
- v.x = ( ( ( 2.0f * ptCursor.x ) / viewport.Width ) - 1 ) / matProj.m[0][0];
- v.y = -( ( ( 2.0f * ptCursor.y ) / viewport.Height ) - 1 ) / matProj.m[1][1];
- v.z = 1.0f;
- Matrix mView = pRS->GetView();
- mView.Inverse ();
- Vector raydir;
- Vector rayorig;
- raydir = mView.MulNormal(v);
- rayorig = mView.pos;
- raystart = rayorig;
- rayend = (rayorig + (raydir * 100.f));
- }
- bool ObjectSelector::CompareFunc (const ObjectSelector::TracedObjects &item1, const ObjectSelector::TracedObjects &item2)
- {
- if (item1.IntersectionDistance < item2.IntersectionDistance) return true;
- return false;
- }
- void ObjectSelector::ButtonIsPressed (bool bPressed, const GUIPoint &ptCursor, const RENDERVIEWPORT& viewport)
- {
- static SlowBoxCollider BoxColl;
- if (!bPressed) return;
- if (!Active) return;
- ObjInTrace.DelAll();
-
- ExtractRay (viewport, ptCursor, r1, r2);
- // Надо протестить луч на пересечение со всеми коробками
- // и выбрать ближайшую
-
- for (DWORD i =0; i < sMission->GetCreatedMissionObjectsCount(); i++)
- {
- MOSafePointer missObj = sMission->GetCreatedMissionObjectByIndex(i);
-
- if (!missObj.SPtr()->EditMode_IsVisible()) continue;
- Vector min(0.0f), max(0.0f);
- missObj.Ptr()->EditMode_GetSelectBox(min, max);
- Matrix matWorld;
- missObj.Ptr()->GetMatrix (matWorld);
- BoxColl.Init(min, max, matWorld);
- float val = BoxColl.RayTrace(r1, r2);
- if (val > 0)
- {
- TracedObjects newEnt;
- newEnt.IntersectionDistance = val;
- newEnt.NearMissionObject = missObj;
-
- newEnt.mObj = &sMission->GetCreatedMissionObjectStructByIndex(i);
- newEnt.point = BoxColl.IntersectionPoint;
- newEnt.bMin = min;
- newEnt.bMax = max;
- newEnt.bWorld = matWorld;
- ObjInTrace.Add(newEnt);
- }
- }
- ObjInTrace.QSort(CompareFunc);
- //api->Trace ("TRACE START ------------------------");
- for (DWORD j = 0; j < ObjInTrace.Size(); j++)
- {
- const char* oName = ObjInTrace[j].NearMissionObject.Ptr()->GetObjectID().c_str();
- float d = ObjInTrace[j].IntersectionDistance;
- //api->Trace("[%d] Obj - %s, Distance - %3.2f", j, oName, d);
- }
- bool ControlState = false;
- if (GetAsyncKeyState(VK_CONTROL) < 0) ControlState = true;
- // simple like Maya selector
- if ((!ControlState) || !LastSelectedObject.Validate())
- {
- if (ObjInTrace.Size() >= 1)
- {
- SelectObject (0);
- }
- } else
- {
- bool NeedLoop = true;
- for (int i = 0; i < ObjInTrace; i++)
- {
- Vector cam_pos = pRS->GetView().GetCamPos();
- float new_dist = Vector(ObjInTrace[i].point - cam_pos).GetLength();
- float old_dist = Vector(LastIntersectionPoint - cam_pos).GetLength();
- if ((new_dist > old_dist) && (LastSelectedObject != ObjInTrace[i].NearMissionObject))
- {
- SelectObject (i);
- NeedLoop = false;
- break;
- }
- }
- if (NeedLoop) SelectObject (0);
- }
- }
- void ObjectSelector::SelectObject (int index)
- {
- if ((int)ObjInTrace.Size() <= index) return;
- ObjInTrace[index].NearMissionObject.SPtr()->EditMode_Select (true);
- if (pCurrentSelected.Validate()) pCurrentSelected.Ptr()->EditMode_Select (false);
- pCurrentSelected = ObjInTrace[index].NearMissionObject;
- LastSelectedObject = ObjInTrace[index].NearMissionObject;
- LastIntersectionPoint = ObjInTrace[index].point;
- MainWindow->TreeView1->ResetSelection(*MainWindow->TreeView1->Items);
- if (ObjInTrace[index].mObj)
- {
- string FullPath = ObjInTrace[index].mObj->PathInTree;
- FullPath += ObjInTrace[index].NearMissionObject.SPtr()->GetObjectID().c_str();
- GUITreeNode* fItem = MainWindow->TreeView1->FindItem (FullPath.GetBuffer ());
- if (fItem)
- {
- if (fItem->Parent) Expand (fItem->Parent);
- MainWindow->TreeView1->SetSelectedNode (fItem, false);
- }
- }
- }
- void ObjectSelector::Expand (GUITreeNode* fItem)
- {
- fItem->Expanded = true;
- if (fItem->Parent) Expand (fItem->Parent);
- }
|