Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

449 lines
12 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "stdafx.h"
  7. #include "Box3D.h"
  8. #include "fgdlib/HelperInfo.h"
  9. #include "materialsystem/imaterialsystem.h"
  10. #include "materialsystem/IMesh.h"
  11. #include "MapDoc.h"
  12. #include "MapViewer.h"
  13. #include "MapView2D.h"
  14. #include "Material.h"
  15. #include "mathlib/MathLib.h"
  16. #include "Render2D.h"
  17. #include "Render3D.h"
  18. #include "ToolManager.h"
  19. #include "ToolSphere.h"
  20. #include "..\FoW\FoW.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include <tier0/memdbgon.h>
  23. IMPLEMENT_MAPCLASS(CMapViewer)
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Factory function. Used for creating a CMapViewer helper from a
  26. // set of string parameters from the FGD file.
  27. // Input : pInfo - Pointer to helper info class which gives us information
  28. // about how to create the helper.
  29. // Output : Returns a pointer to the helper, NULL if an error occurs.
  30. //-----------------------------------------------------------------------------
  31. CMapClass *CMapViewer::Create(CHelperInfo *pHelperInfo, CMapEntity *pParent)
  32. {
  33. CMapViewer *pViewer = new CMapViewer;
  34. if (pViewer != NULL)
  35. {
  36. //
  37. // The first parameter should be the key name to represent. If it isn't
  38. // there we assume "radius".
  39. //
  40. const char *pszKeyName = pHelperInfo->GetParameter(0);
  41. if (pszKeyName != NULL)
  42. {
  43. strcpy(pViewer->m_szKeyName, pszKeyName);
  44. }
  45. else
  46. {
  47. strcpy(pViewer->m_szKeyName, "radius");
  48. }
  49. //
  50. // Extract the line color from the parameter list.
  51. //
  52. unsigned char chRed = 255;
  53. unsigned char chGreen = 255;
  54. unsigned char chBlue = 255;
  55. const char *pszParam = pHelperInfo->GetParameter(1);
  56. if (pszParam != NULL)
  57. {
  58. chRed = atoi(pszParam);
  59. }
  60. pszParam = pHelperInfo->GetParameter(2);
  61. if (pszParam != NULL)
  62. {
  63. chGreen = atoi(pszParam);
  64. }
  65. pszParam = pHelperInfo->GetParameter(3);
  66. if (pszParam != NULL)
  67. {
  68. chBlue = atoi(pszParam);
  69. }
  70. pViewer->SetRenderColor(chRed, chGreen, chBlue);
  71. }
  72. return pViewer;
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose: Constructor.
  76. //-----------------------------------------------------------------------------
  77. CMapViewer::CMapViewer(bool AddToFoW) :
  78. CMapSphere()
  79. {
  80. m_szKeyName[0] = '\0';
  81. m_flRadius = 0;
  82. r = 0;
  83. g = 255;
  84. b = 0;
  85. SetVisible( true );
  86. SetVisible2D( true );
  87. m_FoWHandle = -1;
  88. if ( AddToFoW )
  89. {
  90. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  91. if ( pFoW )
  92. {
  93. m_FoWHandle = pFoW->AddViewer( 0 );
  94. }
  95. }
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Purpose: Destructor.
  99. //-----------------------------------------------------------------------------
  100. CMapViewer::~CMapViewer(void)
  101. {
  102. if ( m_FoWHandle != -1 )
  103. {
  104. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  105. if ( pFoW )
  106. {
  107. pFoW->RemoveViewer( m_FoWHandle );
  108. }
  109. m_FoWHandle = -1;
  110. }
  111. }
  112. //-----------------------------------------------------------------------------
  113. // Purpose:
  114. // Input : bFullUpdate -
  115. //-----------------------------------------------------------------------------
  116. void CMapViewer::CalcBounds(BOOL bFullUpdate)
  117. {
  118. CMapClass::CalcBounds(bFullUpdate);
  119. Vector mins;
  120. Vector maxs;
  121. //
  122. // Pretend we're a point so that we don't change our parent entity bounds
  123. // in the 2D view.
  124. //
  125. m_Render2DBox.ResetBounds();
  126. m_Render2DBox.UpdateBounds(m_Origin);
  127. mins = m_Origin - Vector(m_flRadius, m_flRadius, m_flRadius);
  128. maxs = m_Origin + Vector(m_flRadius, m_flRadius, m_flRadius);
  129. m_Render2DBox.UpdateBounds(mins, maxs);
  130. //
  131. // Build our bounds for frustum culling in the 3D views.
  132. //
  133. m_CullBox.ResetBounds();
  134. mins = m_Origin - Vector(m_flRadius, m_flRadius, m_flRadius);
  135. maxs = m_Origin + Vector(m_flRadius, m_flRadius, m_flRadius);
  136. m_CullBox.UpdateBounds(mins, maxs);
  137. m_BoundingBox.ResetBounds(); // we don't want to use the bounds of the sphere for our bounding box
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Purpose:
  141. // Output : CMapClass
  142. //-----------------------------------------------------------------------------
  143. CMapClass *CMapViewer::Copy(bool bUpdateDependencies)
  144. {
  145. CMapViewer *pCopy = new CMapViewer( false );
  146. if (pCopy != NULL)
  147. {
  148. pCopy->CopyFrom(this, bUpdateDependencies);
  149. }
  150. return(pCopy);
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Purpose: Makes this an exact duplicate of pObject.
  154. // Input : pObject - Object to copy.
  155. // Output : Returns this.
  156. //-----------------------------------------------------------------------------
  157. CMapClass *CMapViewer::CopyFrom(CMapClass *pObject, bool bUpdateDependencies)
  158. {
  159. Assert(pObject->IsMapClass(MAPCLASS_TYPE(CMapViewer)));
  160. CMapViewer *pFrom = (CMapViewer *)pObject;
  161. CMapClass::CopyFrom(pObject, bUpdateDependencies);
  162. m_flRadius = pFrom->m_flRadius;
  163. strcpy(m_szKeyName, pFrom->m_szKeyName);
  164. return(this);
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Purpose: Gets the tool object for a given context data from HitTest2D.
  168. //-----------------------------------------------------------------------------
  169. CBaseTool *CMapViewer::GetToolObject(int nHitData, bool bAttachObject)
  170. {
  171. CToolSphere *pTool = (CToolSphere *)ToolManager()->GetToolForID(TOOL_SPHERE);
  172. if ( bAttachObject )
  173. pTool->Attach(this);
  174. return pTool;
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Purpose:
  178. // Input : pView -
  179. // point - point in client coordinates
  180. // Output :
  181. //-----------------------------------------------------------------------------
  182. bool CMapViewer::HitTest2D(CMapView2D *pView, const Vector2D &point, HitInfo_t &HitData)
  183. {
  184. if ( m_flRadius <= 0 )
  185. {
  186. return NULL;
  187. }
  188. Vector2D vecClientOrigin;
  189. pView->WorldToClient(vecClientOrigin, m_Origin);
  190. Vector vecRadius = m_Origin;
  191. vecRadius[pView->axHorz] += m_flRadius;
  192. Vector2D vecClientRadius;
  193. pView->WorldToClient(vecClientRadius, vecRadius);
  194. int nRadius = abs(vecClientRadius.x - vecClientOrigin.x);
  195. vecClientRadius.x = nRadius;
  196. vecClientRadius.y = nRadius;
  197. HitData.pObject = this;
  198. HitData.nDepth = 0; // handles have no depth
  199. HitData.uData = nRadius;
  200. Vector2D vecClientMin = vecClientOrigin - vecClientRadius;
  201. Vector2D vecClientMax = vecClientOrigin + vecClientRadius;
  202. //
  203. // Check the four resize handles.
  204. //
  205. Vector2D vecTemp(vecClientOrigin.x, vecClientMin.y - HANDLE_OFFSET);
  206. if (pView->CheckDistance(point, vecTemp, 6))
  207. {
  208. // Top handle
  209. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  210. return true;
  211. }
  212. vecTemp.x = vecClientOrigin.x;
  213. vecTemp.y = vecClientMax.y + HANDLE_OFFSET;
  214. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  215. {
  216. // Bottom handle
  217. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  218. return true;
  219. }
  220. vecTemp.x = vecClientMin.x - HANDLE_OFFSET;
  221. vecTemp.y = vecClientOrigin.y;
  222. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  223. {
  224. // Left handle
  225. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  226. return true;
  227. }
  228. vecTemp.x = vecClientMax.x + HANDLE_OFFSET;
  229. vecTemp.y = vecClientOrigin.y;
  230. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  231. {
  232. // Right handle
  233. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  234. return true;
  235. }
  236. HitData.pObject = NULL;
  237. return false;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose: Notifies that this object's parent entity has had a key value change.
  241. // Input : szKey - The key that changed.
  242. // szValue - The new value of the key.
  243. //-----------------------------------------------------------------------------
  244. void CMapViewer::OnParentKeyChanged(const char *szKey, const char *szValue)
  245. {
  246. if (!stricmp(szKey, m_szKeyName))
  247. {
  248. m_flRadius = atof(szValue);
  249. PostUpdate(Notify_Changed);
  250. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  251. if ( pFoW )
  252. {
  253. pFoW->UpdateViewerSize( m_FoWHandle, m_flRadius );
  254. }
  255. }
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose:
  259. // Input :
  260. // Output :
  261. //-----------------------------------------------------------------------------
  262. void CMapViewer::OnRemoveFromWorld(CMapWorld *pWorld, bool bNotifyChildren)
  263. {
  264. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  265. if ( pFoW && m_FoWHandle != -1 )
  266. {
  267. pFoW->RemoveViewer( m_FoWHandle );
  268. }
  269. m_FoWHandle = -1;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. // Input : pRender -
  274. //-----------------------------------------------------------------------------
  275. void CMapViewer::Render2D(CRender2D *pRender)
  276. {
  277. if ( m_flRadius > 0 )
  278. {
  279. pRender->SetDrawColor( 0, 255, 0 );
  280. Vector2D ptClientRadius;
  281. pRender->TransformNormal(ptClientRadius, Vector(m_flRadius,m_flRadius,m_flRadius) );
  282. int radius = ptClientRadius.x;
  283. pRender->DrawCircle( m_Origin, m_flRadius );
  284. bool bPopMode = pRender->BeginClientSpace();
  285. //
  286. // Draw the four resize handles.
  287. //
  288. pRender->SetHandleStyle( HANDLE_RADIUS, CRender::HANDLE_SQUARE );
  289. pRender->SetHandleColor( 0,255,0 );
  290. Vector2D offset;
  291. offset.x = 0;
  292. offset.y = -(radius + HANDLE_OFFSET);
  293. pRender->DrawHandle( m_Origin, &offset );
  294. offset.x = 0;
  295. offset.y = radius + HANDLE_OFFSET;
  296. pRender->DrawHandle( m_Origin, &offset );
  297. offset.x = -(radius + HANDLE_OFFSET);
  298. offset.y = 0;
  299. pRender->DrawHandle( m_Origin, &offset );
  300. offset.x = radius + HANDLE_OFFSET;
  301. offset.y = 0;
  302. pRender->DrawHandle( m_Origin, &offset );
  303. offset.x = 0;
  304. offset.y = 0;
  305. pRender->DrawHandle( m_Origin, &offset );
  306. if ( bPopMode )
  307. pRender->EndClientSpace();
  308. }
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose: Renders the wireframe sphere.
  312. // Input : pRender - Interface to renderer.
  313. //-----------------------------------------------------------------------------
  314. void CMapViewer::Render3D(CRender3D *pRender)
  315. {
  316. if ( m_flRadius > 0 )
  317. {
  318. pRender->RenderWireframeSphere(m_Origin, m_flRadius, 12, 12, 0, 255, 0);
  319. }
  320. }
  321. //-----------------------------------------------------------------------------
  322. // Purpose: Overridden to chain down to our endpoints, which are not children.
  323. //-----------------------------------------------------------------------------
  324. void CMapViewer::SetOrigin(Vector &vecOrigin)
  325. {
  326. BaseClass::SetOrigin(vecOrigin);
  327. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  328. if ( pFoW )
  329. {
  330. pFoW->UpdateViewerLocation( m_FoWHandle, vecOrigin );
  331. }
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: Overridden to chain down to our endpoints, which are not children.
  335. //-----------------------------------------------------------------------------
  336. SelectionState_t CMapViewer::SetSelectionState(SelectionState_t eSelectionState)
  337. {
  338. SelectionState_t eState = BaseClass::SetSelectionState(eSelectionState);
  339. return eState;
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Purpose: Overridden to transform our endpoints.
  343. //-----------------------------------------------------------------------------
  344. void CMapViewer::DoTransform(const VMatrix &matrix)
  345. {
  346. BaseClass::DoTransform(matrix);
  347. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  348. if ( pFoW )
  349. {
  350. pFoW->UpdateViewerLocation( m_FoWHandle, m_Origin );
  351. }
  352. }
  353. void CMapViewer::SetRadius(float flRadius)
  354. {
  355. __super::SetRadius( flRadius );
  356. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  357. if ( pFoW )
  358. {
  359. pFoW->UpdateViewerSize( m_FoWHandle, m_flRadius );
  360. }
  361. CalcBounds( false );
  362. }