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.

462 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 "MapOccluder.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(CMapOccluder)
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Factory function. Used for creating a CMapOccluder 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 *CMapOccluder::Create(CHelperInfo *pHelperInfo, CMapEntity *pParent)
  32. {
  33. CMapOccluder *pOccluder = new CMapOccluder;
  34. if (pOccluder != 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(pOccluder->m_szKeyName, pszKeyName);
  44. }
  45. else
  46. {
  47. strcpy(pOccluder->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. pOccluder->SetRenderColor(chRed, chGreen, chBlue);
  71. }
  72. return pOccluder;
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose: Constructor.
  76. //-----------------------------------------------------------------------------
  77. CMapOccluder::CMapOccluder(bool AddToFoW) :
  78. CMapSphere()
  79. {
  80. m_szKeyName[0] = '\0';
  81. m_flRadius = 0;
  82. r = 255;
  83. g = 0;
  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->AddOccluder( false );
  94. }
  95. }
  96. m_bWasSelected = false;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Destructor.
  100. //-----------------------------------------------------------------------------
  101. CMapOccluder::~CMapOccluder(void)
  102. {
  103. if ( m_FoWHandle != -1 )
  104. {
  105. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  106. if ( pFoW != NULL && m_FoWHandle != -1 )
  107. {
  108. pFoW->RemoveOccluder( m_FoWHandle );
  109. }
  110. m_FoWHandle = -1;
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Purpose:
  115. // Input : bFullUpdate -
  116. //-----------------------------------------------------------------------------
  117. void CMapOccluder::CalcBounds(BOOL bFullUpdate)
  118. {
  119. CMapClass::CalcBounds(bFullUpdate);
  120. Vector mins;
  121. Vector maxs;
  122. //
  123. // Pretend we're a point so that we don't change our parent entity bounds
  124. // in the 2D view.
  125. //
  126. m_Render2DBox.ResetBounds();
  127. m_Render2DBox.UpdateBounds(m_Origin);
  128. mins = m_Origin - Vector(m_flRadius, m_flRadius, m_flRadius);
  129. maxs = m_Origin + Vector(m_flRadius, m_flRadius, m_flRadius);
  130. m_Render2DBox.UpdateBounds(mins, maxs);
  131. //
  132. // Build our bounds for frustum culling in the 3D views.
  133. //
  134. m_CullBox.ResetBounds();
  135. mins = m_Origin - Vector(m_flRadius, m_flRadius, m_flRadius);
  136. maxs = m_Origin + Vector(m_flRadius, m_flRadius, m_flRadius);
  137. m_CullBox.UpdateBounds(mins, maxs);
  138. m_BoundingBox.ResetBounds(); // we don't want to use the bounds of the sphere for our bounding box
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose:
  142. // Output : CMapClass
  143. //-----------------------------------------------------------------------------
  144. CMapClass *CMapOccluder::Copy(bool bUpdateDependencies)
  145. {
  146. CMapOccluder *pCopy = new CMapOccluder( false );
  147. if (pCopy != NULL)
  148. {
  149. pCopy->CopyFrom(this, bUpdateDependencies);
  150. }
  151. return(pCopy);
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose: Makes this an exact duplicate of pObject.
  155. // Input : pObject - Object to copy.
  156. // Output : Returns this.
  157. //-----------------------------------------------------------------------------
  158. CMapClass *CMapOccluder::CopyFrom(CMapClass *pObject, bool bUpdateDependencies)
  159. {
  160. Assert(pObject->IsMapClass(MAPCLASS_TYPE(CMapOccluder)));
  161. CMapOccluder *pFrom = (CMapOccluder *)pObject;
  162. CMapClass::CopyFrom(pObject, bUpdateDependencies);
  163. m_flRadius = pFrom->m_flRadius;
  164. strcpy(m_szKeyName, pFrom->m_szKeyName);
  165. return(this);
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose: Gets the tool object for a given context data from HitTest2D.
  169. //-----------------------------------------------------------------------------
  170. CBaseTool *CMapOccluder::GetToolObject(int nHitData, bool bAttachObject)
  171. {
  172. CToolSphere *pTool = (CToolSphere *)ToolManager()->GetToolForID(TOOL_SPHERE);
  173. if ( bAttachObject )
  174. pTool->Attach(this);
  175. return pTool;
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Purpose:
  179. // Input : pView -
  180. // point - point in client coordinates
  181. // Output :
  182. //-----------------------------------------------------------------------------
  183. bool CMapOccluder::HitTest2D(CMapView2D *pView, const Vector2D &point, HitInfo_t &HitData)
  184. {
  185. if ( m_flRadius <= 0 )
  186. {
  187. return NULL;
  188. }
  189. Vector2D vecClientOrigin;
  190. pView->WorldToClient(vecClientOrigin, m_Origin);
  191. Vector vecRadius = m_Origin;
  192. vecRadius[pView->axHorz] += m_flRadius;
  193. Vector2D vecClientRadius;
  194. pView->WorldToClient(vecClientRadius, vecRadius);
  195. int nRadius = abs(vecClientRadius.x - vecClientOrigin.x);
  196. vecClientRadius.x = nRadius;
  197. vecClientRadius.y = nRadius;
  198. HitData.pObject = this;
  199. HitData.nDepth = 0; // handles have no depth
  200. HitData.uData = nRadius;
  201. Vector2D vecClientMin = vecClientOrigin - vecClientRadius;
  202. Vector2D vecClientMax = vecClientOrigin + vecClientRadius;
  203. //
  204. // Check the four resize handles.
  205. //
  206. Vector2D vecTemp(vecClientOrigin.x, vecClientMin.y - HANDLE_OFFSET);
  207. if (pView->CheckDistance(point, vecTemp, 6))
  208. {
  209. // Top handle
  210. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  211. return true;
  212. }
  213. vecTemp.x = vecClientOrigin.x;
  214. vecTemp.y = vecClientMax.y + HANDLE_OFFSET;
  215. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  216. {
  217. // Bottom handle
  218. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
  219. return true;
  220. }
  221. vecTemp.x = vecClientMin.x - HANDLE_OFFSET;
  222. vecTemp.y = vecClientOrigin.y;
  223. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  224. {
  225. // Left handle
  226. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  227. return true;
  228. }
  229. vecTemp.x = vecClientMax.x + HANDLE_OFFSET;
  230. vecTemp.y = vecClientOrigin.y;
  231. if (pView->CheckDistance(point, vecTemp, HANDLE_RADIUS))
  232. {
  233. // Right handle
  234. SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE));
  235. return true;
  236. }
  237. HitData.pObject = NULL;
  238. return false;
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Purpose: Notifies that this object's parent entity has had a key value change.
  242. // Input : szKey - The key that changed.
  243. // szValue - The new value of the key.
  244. //-----------------------------------------------------------------------------
  245. void CMapOccluder::OnParentKeyChanged(const char *szKey, const char *szValue)
  246. {
  247. if (!stricmp(szKey, m_szKeyName))
  248. {
  249. m_flRadius = atof(szValue);
  250. PostUpdate(Notify_Changed);
  251. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  252. if ( pFoW )
  253. {
  254. pFoW->UpdateOccluderSize( m_FoWHandle, m_flRadius );
  255. }
  256. }
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Purpose:
  260. // Input :
  261. // Output :
  262. //-----------------------------------------------------------------------------
  263. void CMapOccluder::OnRemoveFromWorld(CMapWorld *pWorld, bool bNotifyChildren)
  264. {
  265. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  266. if ( pFoW != NULL && m_FoWHandle != -1 )
  267. {
  268. pFoW->RemoveOccluder( m_FoWHandle );
  269. }
  270. m_FoWHandle = -1;
  271. }
  272. //-----------------------------------------------------------------------------
  273. // Purpose:
  274. // Input : pRender -
  275. //-----------------------------------------------------------------------------
  276. void CMapOccluder::Render2D(CRender2D *pRender)
  277. {
  278. if ( m_flRadius > 0 )
  279. {
  280. pRender->SetDrawColor( 255, 0, 0 );
  281. Vector2D ptClientRadius;
  282. pRender->TransformNormal(ptClientRadius, Vector(m_flRadius,m_flRadius,m_flRadius) );
  283. int radius = ptClientRadius.x;
  284. pRender->DrawCircle( m_Origin, m_flRadius );
  285. bool bPopMode = pRender->BeginClientSpace();
  286. pRender->SetHandleStyle( HANDLE_RADIUS, CRender::HANDLE_SQUARE );
  287. pRender->SetHandleColor( 255,0,0 );
  288. if ( IsSelected() )
  289. {
  290. m_bWasSelected = true;
  291. //
  292. // Draw the four resize handles.
  293. //
  294. Vector2D offset;
  295. offset.x = 0;
  296. offset.y = -(radius + HANDLE_OFFSET);
  297. pRender->DrawHandle( m_Origin, &offset );
  298. offset.x = 0;
  299. offset.y = radius + HANDLE_OFFSET;
  300. pRender->DrawHandle( m_Origin, &offset );
  301. offset.x = -(radius + HANDLE_OFFSET);
  302. offset.y = 0;
  303. pRender->DrawHandle( m_Origin, &offset );
  304. offset.x = radius + HANDLE_OFFSET;
  305. offset.y = 0;
  306. pRender->DrawHandle( m_Origin, &offset );
  307. }
  308. pRender->DrawHandle( m_Origin, &vec2_origin );
  309. if ( bPopMode )
  310. {
  311. pRender->EndClientSpace();
  312. }
  313. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  314. if ( pFoW && m_bWasSelected )
  315. {
  316. float flVisibility = pFoW->GetLocationVisibilityDegree( 0, m_Origin, m_flRadius );
  317. Msg( "Visibility = %g\n", flVisibility );
  318. flVisibility = flVisibility;
  319. }
  320. }
  321. }
  322. //-----------------------------------------------------------------------------
  323. // Purpose: Renders the wireframe sphere.
  324. // Input : pRender - Interface to renderer.
  325. //-----------------------------------------------------------------------------
  326. void CMapOccluder::Render3D(CRender3D *pRender)
  327. {
  328. if ( m_flRadius > 0 )
  329. {
  330. pRender->RenderWireframeSphere(m_Origin, m_flRadius, 12, 12, 255, 0, 0);
  331. }
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: Overridden to chain down to our endpoints, which are not children.
  335. //-----------------------------------------------------------------------------
  336. void CMapOccluder::SetOrigin(Vector &vecOrigin)
  337. {
  338. BaseClass::SetOrigin(vecOrigin);
  339. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  340. if ( pFoW )
  341. {
  342. pFoW->UpdateOccluderLocation( m_FoWHandle, vecOrigin );
  343. }
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose: Overridden to chain down to our endpoints, which are not children.
  347. //-----------------------------------------------------------------------------
  348. SelectionState_t CMapOccluder::SetSelectionState(SelectionState_t eSelectionState)
  349. {
  350. SelectionState_t eState = BaseClass::SetSelectionState(eSelectionState);
  351. return eState;
  352. }
  353. //-----------------------------------------------------------------------------
  354. // Purpose: Overridden to transform our endpoints.
  355. //-----------------------------------------------------------------------------
  356. void CMapOccluder::DoTransform(const VMatrix &matrix)
  357. {
  358. BaseClass::DoTransform(matrix);
  359. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  360. if ( pFoW )
  361. {
  362. pFoW->UpdateOccluderLocation( m_FoWHandle, m_Origin );
  363. }
  364. }
  365. void CMapOccluder::SetRadius(float flRadius)
  366. {
  367. __super::SetRadius( flRadius );
  368. CFoW *pFoW = CMapDoc::GetActiveMapDoc()->GetFoW();
  369. if ( pFoW )
  370. {
  371. pFoW->UpdateOccluderSize( m_FoWHandle, m_flRadius );
  372. }
  373. }