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.

499 lines
17 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "vbsp.h"
  8. #include "disp_vbsp.h"
  9. #include "builddisp.h"
  10. #include "mathlib/vmatrix.h"
  11. void Overlay_BuildBasisOrigin( doverlay_t *pOverlay );
  12. // Overlay list.
  13. CUtlVector<mapoverlay_t> g_aMapOverlays;
  14. CUtlVector<mapoverlay_t> g_aMapWaterOverlays;
  15. //-----------------------------------------------------------------------------
  16. //-----------------------------------------------------------------------------
  17. int Overlay_GetFromEntity( entity_t *pMapEnt )
  18. {
  19. int iAccessorID = -1;
  20. // Allocate the new overlay.
  21. int iOverlay = g_aMapOverlays.AddToTail();
  22. mapoverlay_t *pMapOverlay = &g_aMapOverlays[iOverlay];
  23. // Get the overlay data.
  24. pMapOverlay->nId = g_aMapOverlays.Count() - 1;
  25. if ( ValueForKey( pMapEnt, "targetname" )[ 0 ] != '\0' )
  26. {
  27. // Overlay has a name, remember it's ID for accessing
  28. iAccessorID = pMapOverlay->nId;
  29. }
  30. pMapOverlay->flU[0] = FloatForKey( pMapEnt, "StartU" );
  31. pMapOverlay->flU[1] = FloatForKey( pMapEnt, "EndU" );
  32. pMapOverlay->flV[0] = FloatForKey( pMapEnt, "StartV" );
  33. pMapOverlay->flV[1] = FloatForKey( pMapEnt, "EndV" );
  34. pMapOverlay->flFadeDistMinSq = FloatForKey( pMapEnt, "fademindist" );
  35. if ( pMapOverlay->flFadeDistMinSq > 0 )
  36. {
  37. pMapOverlay->flFadeDistMinSq *= pMapOverlay->flFadeDistMinSq;
  38. }
  39. pMapOverlay->flFadeDistMaxSq = FloatForKey( pMapEnt, "fademaxdist" );
  40. if ( pMapOverlay->flFadeDistMaxSq > 0 )
  41. {
  42. pMapOverlay->flFadeDistMaxSq *= pMapOverlay->flFadeDistMaxSq;
  43. }
  44. pMapOverlay->nMinCPULevel = IntForKey( pMapEnt, "mincpulevel" );
  45. pMapOverlay->nMaxCPULevel = IntForKey( pMapEnt, "maxcpulevel" );
  46. pMapOverlay->nMinGPULevel = IntForKey( pMapEnt, "mingpulevel" );
  47. pMapOverlay->nMaxGPULevel = IntForKey( pMapEnt, "maxgpulevel" );
  48. GetVectorForKey( pMapEnt, "BasisOrigin", pMapOverlay->vecOrigin );
  49. pMapOverlay->m_nRenderOrder = IntForKey( pMapEnt, "RenderOrder" );
  50. if ( pMapOverlay->m_nRenderOrder < 0 || pMapOverlay->m_nRenderOrder >= OVERLAY_NUM_RENDER_ORDERS )
  51. Error( "Overlay (%s) at %f %f %f has invalid render order (%d).\n", ValueForKey( pMapEnt, "material" ), pMapOverlay->vecOrigin );
  52. GetVectorForKey( pMapEnt, "uv0", pMapOverlay->vecUVPoints[0] );
  53. GetVectorForKey( pMapEnt, "uv1", pMapOverlay->vecUVPoints[1] );
  54. GetVectorForKey( pMapEnt, "uv2", pMapOverlay->vecUVPoints[2] );
  55. GetVectorForKey( pMapEnt, "uv3", pMapOverlay->vecUVPoints[3] );
  56. GetVectorForKey( pMapEnt, "BasisU", pMapOverlay->vecBasis[0] );
  57. GetVectorForKey( pMapEnt, "BasisV", pMapOverlay->vecBasis[1] );
  58. GetVectorForKey( pMapEnt, "BasisNormal", pMapOverlay->vecBasis[2] );
  59. const char *pMaterialName = ValueForKey( pMapEnt, "material" );
  60. Assert( strlen( pMaterialName ) < OVERLAY_MAP_STRLEN );
  61. if ( strlen( pMaterialName ) >= OVERLAY_MAP_STRLEN )
  62. {
  63. Error( "Overlay Material Name (%s) too long! > OVERLAY_MAP_STRLEN (%d)", pMaterialName, OVERLAY_MAP_STRLEN );
  64. return -1;
  65. }
  66. strcpy( pMapOverlay->szMaterialName, pMaterialName );
  67. // Convert the sidelist to side id(s).
  68. const char *pSideList = ValueForKey( pMapEnt, "sides" );
  69. char *pTmpList = ( char* )_alloca( strlen( pSideList ) + 1 );
  70. strcpy( pTmpList, pSideList );
  71. const char *pScan = strtok( pTmpList, " " );
  72. if ( !pScan )
  73. return iAccessorID;
  74. pMapOverlay->aSideList.Purge();
  75. pMapOverlay->aFaceList.Purge();
  76. do
  77. {
  78. int nSideId;
  79. if ( sscanf( pScan, "%d", &nSideId ) == 1 )
  80. {
  81. pMapOverlay->aSideList.AddToTail( nSideId );
  82. }
  83. } while ( ( pScan = strtok( NULL, " " ) ) );
  84. return iAccessorID;
  85. }
  86. //-----------------------------------------------------------------------------
  87. //-----------------------------------------------------------------------------
  88. side_t *GetSide( int nSideId )
  89. {
  90. for( int iSide = 0; iSide < g_LoadingMap->nummapbrushsides; ++iSide )
  91. {
  92. if ( g_LoadingMap->brushsides[iSide].id == nSideId )
  93. return &g_LoadingMap->brushsides[iSide];
  94. }
  95. return NULL;
  96. }
  97. //-----------------------------------------------------------------------------
  98. //-----------------------------------------------------------------------------
  99. void Overlay_UpdateSideLists( int StartIndex )
  100. {
  101. int nMapOverlayCount = g_aMapOverlays.Count();
  102. for( int iMapOverlay = StartIndex; iMapOverlay < nMapOverlayCount; ++iMapOverlay )
  103. {
  104. mapoverlay_t *pMapOverlay = &g_aMapOverlays.Element( iMapOverlay );
  105. if ( pMapOverlay )
  106. {
  107. int nSideCount = pMapOverlay->aSideList.Count();
  108. for( int iSide = 0; iSide < nSideCount; ++iSide )
  109. {
  110. side_t *pSide = GetSide( pMapOverlay->aSideList[iSide] );
  111. if ( pSide )
  112. {
  113. if ( pSide->aOverlayIds.Find( pMapOverlay->nId ) == -1 )
  114. {
  115. pSide->aOverlayIds.AddToTail( pMapOverlay->nId );
  116. }
  117. }
  118. }
  119. }
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. //-----------------------------------------------------------------------------
  124. void OverlayTransition_UpdateSideLists( int StartIndex )
  125. {
  126. int nOverlayCount = g_aMapWaterOverlays.Count();
  127. for( int iOverlay = StartIndex; iOverlay < nOverlayCount; ++iOverlay )
  128. {
  129. mapoverlay_t *pOverlay = &g_aMapWaterOverlays.Element( iOverlay );
  130. if ( pOverlay )
  131. {
  132. int nSideCount = pOverlay->aSideList.Count();
  133. for( int iSide = 0; iSide < nSideCount; ++iSide )
  134. {
  135. side_t *pSide = GetSide( pOverlay->aSideList[iSide] );
  136. if ( pSide )
  137. {
  138. if ( pSide->aWaterOverlayIds.Find( pOverlay->nId ) == -1 )
  139. {
  140. pSide->aWaterOverlayIds.AddToTail( pOverlay->nId );
  141. }
  142. }
  143. }
  144. }
  145. }
  146. }
  147. //-----------------------------------------------------------------------------
  148. //-----------------------------------------------------------------------------
  149. void Overlay_AddFaceToLists( int iFace, side_t *pSide )
  150. {
  151. int nOverlayIdCount = pSide->aOverlayIds.Count();
  152. for( int iOverlayId = 0; iOverlayId < nOverlayIdCount; ++iOverlayId )
  153. {
  154. mapoverlay_t *pMapOverlay = &g_aMapOverlays.Element( pSide->aOverlayIds[iOverlayId] );
  155. if ( pMapOverlay )
  156. {
  157. if( pMapOverlay->aFaceList.Find( iFace ) == -1 )
  158. {
  159. pMapOverlay->aFaceList.AddToTail( iFace );
  160. }
  161. }
  162. }
  163. }
  164. //-----------------------------------------------------------------------------
  165. //-----------------------------------------------------------------------------
  166. void OverlayTransition_AddFaceToLists( int iFace, side_t *pSide )
  167. {
  168. int nOverlayIdCount = pSide->aWaterOverlayIds.Count();
  169. for( int iOverlayId = 0; iOverlayId < nOverlayIdCount; ++iOverlayId )
  170. {
  171. mapoverlay_t *pMapOverlay = &g_aMapWaterOverlays.Element( pSide->aWaterOverlayIds[iOverlayId] - ( MAX_MAP_OVERLAYS + 1 ) );
  172. if ( pMapOverlay )
  173. {
  174. if( pMapOverlay->aFaceList.Find( iFace ) == -1 )
  175. {
  176. pMapOverlay->aFaceList.AddToTail( iFace );
  177. }
  178. }
  179. }
  180. }
  181. //-----------------------------------------------------------------------------
  182. //-----------------------------------------------------------------------------
  183. void Overlay_EmitOverlayFace( mapoverlay_t *pMapOverlay )
  184. {
  185. Assert( g_nOverlayCount < MAX_MAP_OVERLAYS );
  186. if ( g_nOverlayCount >= MAX_MAP_OVERLAYS )
  187. {
  188. Error ( "Too Many Overlays!\nMAX_MAP_OVERLAYS = %d", MAX_MAP_OVERLAYS );
  189. return;
  190. }
  191. doverlay_t *pOverlay = &g_Overlays[g_nOverlayCount];
  192. doverlayfade_t *pOverlayFade = &g_OverlayFades[g_nOverlayCount];
  193. doverlaysystemlevel_t *pOverlaySystemLevel = &g_OverlaySystemLevels[g_nOverlayCount];
  194. g_nOverlayCount++;
  195. // Conver the map overlay into a .bsp overlay (doverlay_t).
  196. if ( pOverlay )
  197. {
  198. pOverlay->nId = pMapOverlay->nId;
  199. pOverlay->flU[0] = pMapOverlay->flU[0];
  200. pOverlay->flU[1] = pMapOverlay->flU[1];
  201. pOverlay->flV[0] = pMapOverlay->flV[0];
  202. pOverlay->flV[1] = pMapOverlay->flV[1];
  203. VectorCopy( pMapOverlay->vecUVPoints[0], pOverlay->vecUVPoints[0] );
  204. VectorCopy( pMapOverlay->vecUVPoints[1], pOverlay->vecUVPoints[1] );
  205. VectorCopy( pMapOverlay->vecUVPoints[2], pOverlay->vecUVPoints[2] );
  206. VectorCopy( pMapOverlay->vecUVPoints[3], pOverlay->vecUVPoints[3] );
  207. VectorCopy( pMapOverlay->vecOrigin, pOverlay->vecOrigin );
  208. VectorCopy( pMapOverlay->vecBasis[2], pOverlay->vecBasisNormal );
  209. pOverlay->SetRenderOrder( pMapOverlay->m_nRenderOrder );
  210. // Encode the BasisU into the unused z component of the vecUVPoints 0, 1, 2
  211. pOverlay->vecUVPoints[0].z = pMapOverlay->vecBasis[0].x;
  212. pOverlay->vecUVPoints[1].z = pMapOverlay->vecBasis[0].y;
  213. pOverlay->vecUVPoints[2].z = pMapOverlay->vecBasis[0].z;
  214. // Encode whether or not the v axis should be flipped.
  215. Vector vecCross = pMapOverlay->vecBasis[2].Cross( pMapOverlay->vecBasis[0] );
  216. if ( vecCross.Dot( pMapOverlay->vecBasis[1] ) < 0.0f )
  217. {
  218. pOverlay->vecUVPoints[3].z = 1.0f;
  219. }
  220. // Texinfo.
  221. texinfo_t texInfo;
  222. texInfo.flags = 0;
  223. texInfo.texdata = FindOrCreateTexData( pMapOverlay->szMaterialName );
  224. for( int iVec = 0; iVec < 2; ++iVec )
  225. {
  226. for( int iAxis = 0; iAxis < 3; ++iAxis )
  227. {
  228. texInfo.lightmapVecsLuxelsPerWorldUnits[iVec][iAxis] = 0.0f;
  229. texInfo.textureVecsTexelsPerWorldUnits[iVec][iAxis] = 0.0f;
  230. }
  231. texInfo.lightmapVecsLuxelsPerWorldUnits[iVec][3] = -99999.0f;
  232. texInfo.textureVecsTexelsPerWorldUnits[iVec][3] = -99999.0f;
  233. }
  234. pOverlay->nTexInfo = FindOrCreateTexInfo( texInfo );
  235. // Face List
  236. int nFaceCount = pMapOverlay->aFaceList.Count();
  237. Assert( nFaceCount < OVERLAY_BSP_FACE_COUNT );
  238. if ( nFaceCount >= OVERLAY_BSP_FACE_COUNT )
  239. {
  240. Error( "Overlay touching too many faces (touching %d, max %d)\nOverlay %s at %.1f %.1f %.1f", nFaceCount, OVERLAY_BSP_FACE_COUNT, pMapOverlay->szMaterialName, pMapOverlay->vecOrigin.x, pMapOverlay->vecOrigin.y, pMapOverlay->vecOrigin.z );
  241. return;
  242. }
  243. pOverlay->SetFaceCount( nFaceCount );
  244. for( int iFace = 0; iFace < nFaceCount; ++iFace )
  245. {
  246. pOverlay->aFaces[iFace] = pMapOverlay->aFaceList.Element( iFace );
  247. }
  248. }
  249. // Convert the map overlay fade data into a .bsp overlay fade (doverlayfade_t).
  250. if ( pOverlayFade )
  251. {
  252. pOverlayFade->flFadeDistMinSq = pMapOverlay->flFadeDistMinSq;
  253. pOverlayFade->flFadeDistMaxSq = pMapOverlay->flFadeDistMaxSq;
  254. }
  255. if ( pOverlaySystemLevel )
  256. {
  257. pOverlaySystemLevel->nMinCPULevel = pMapOverlay->nMinCPULevel;
  258. pOverlaySystemLevel->nMaxCPULevel = pMapOverlay->nMaxCPULevel;
  259. pOverlaySystemLevel->nMinGPULevel = pMapOverlay->nMinGPULevel;
  260. pOverlaySystemLevel->nMaxGPULevel = pMapOverlay->nMaxGPULevel;
  261. }
  262. }
  263. //-----------------------------------------------------------------------------
  264. //-----------------------------------------------------------------------------
  265. void OverlayTransition_EmitOverlayFace( mapoverlay_t *pMapOverlay )
  266. {
  267. Assert( g_nWaterOverlayCount < MAX_MAP_WATEROVERLAYS );
  268. if ( g_nWaterOverlayCount >= MAX_MAP_WATEROVERLAYS )
  269. {
  270. Error ( "Too many water overlays!\nMAX_MAP_WATEROVERLAYS = %d", MAX_MAP_WATEROVERLAYS );
  271. return;
  272. }
  273. dwateroverlay_t *pOverlay = &g_WaterOverlays[g_nWaterOverlayCount];
  274. g_nWaterOverlayCount++;
  275. // Conver the map overlay into a .bsp overlay (doverlay_t).
  276. if ( pOverlay )
  277. {
  278. pOverlay->nId = pMapOverlay->nId;
  279. pOverlay->flU[0] = pMapOverlay->flU[0];
  280. pOverlay->flU[1] = pMapOverlay->flU[1];
  281. pOverlay->flV[0] = pMapOverlay->flV[0];
  282. pOverlay->flV[1] = pMapOverlay->flV[1];
  283. VectorCopy( pMapOverlay->vecUVPoints[0], pOverlay->vecUVPoints[0] );
  284. VectorCopy( pMapOverlay->vecUVPoints[1], pOverlay->vecUVPoints[1] );
  285. VectorCopy( pMapOverlay->vecUVPoints[2], pOverlay->vecUVPoints[2] );
  286. VectorCopy( pMapOverlay->vecUVPoints[3], pOverlay->vecUVPoints[3] );
  287. VectorCopy( pMapOverlay->vecOrigin, pOverlay->vecOrigin );
  288. VectorCopy( pMapOverlay->vecBasis[2], pOverlay->vecBasisNormal );
  289. pOverlay->SetRenderOrder( pMapOverlay->m_nRenderOrder );
  290. // Encode the BasisU into the unused z component of the vecUVPoints 0, 1, 2
  291. pOverlay->vecUVPoints[0].z = pMapOverlay->vecBasis[0].x;
  292. pOverlay->vecUVPoints[1].z = pMapOverlay->vecBasis[0].y;
  293. pOverlay->vecUVPoints[2].z = pMapOverlay->vecBasis[0].z;
  294. // Encode whether or not the v axis should be flipped.
  295. Vector vecCross = pMapOverlay->vecBasis[2].Cross( pMapOverlay->vecBasis[0] );
  296. if ( vecCross.Dot( pMapOverlay->vecBasis[1] ) < 0.0f )
  297. {
  298. pOverlay->vecUVPoints[3].z = 1.0f;
  299. }
  300. // Texinfo.
  301. texinfo_t texInfo;
  302. texInfo.flags = 0;
  303. texInfo.texdata = FindOrCreateTexData( pMapOverlay->szMaterialName );
  304. for( int iVec = 0; iVec < 2; ++iVec )
  305. {
  306. for( int iAxis = 0; iAxis < 3; ++iAxis )
  307. {
  308. texInfo.lightmapVecsLuxelsPerWorldUnits[iVec][iAxis] = 0.0f;
  309. texInfo.textureVecsTexelsPerWorldUnits[iVec][iAxis] = 0.0f;
  310. }
  311. texInfo.lightmapVecsLuxelsPerWorldUnits[iVec][3] = -99999.0f;
  312. texInfo.textureVecsTexelsPerWorldUnits[iVec][3] = -99999.0f;
  313. }
  314. pOverlay->nTexInfo = FindOrCreateTexInfo( texInfo );
  315. // Face List
  316. int nFaceCount = pMapOverlay->aFaceList.Count();
  317. Assert( nFaceCount < WATEROVERLAY_BSP_FACE_COUNT );
  318. if ( nFaceCount >= WATEROVERLAY_BSP_FACE_COUNT )
  319. {
  320. Error( "Water Overlay touching too many faces (touching %d, max %d)\nOverlay %s at %.1f %.1f %.1f", nFaceCount, OVERLAY_BSP_FACE_COUNT, pMapOverlay->szMaterialName, pMapOverlay->vecOrigin.x, pMapOverlay->vecOrigin.y, pMapOverlay->vecOrigin.z );
  321. return;
  322. }
  323. pOverlay->SetFaceCount( nFaceCount );
  324. for( int iFace = 0; iFace < nFaceCount; ++iFace )
  325. {
  326. pOverlay->aFaces[iFace] = pMapOverlay->aFaceList.Element( iFace );
  327. }
  328. }
  329. }
  330. //-----------------------------------------------------------------------------
  331. // Purpose:
  332. //-----------------------------------------------------------------------------
  333. void Overlay_EmitOverlayFaces( void )
  334. {
  335. int nMapOverlayCount = g_aMapOverlays.Count();
  336. for( int iMapOverlay = 0; iMapOverlay < nMapOverlayCount; ++iMapOverlay )
  337. {
  338. Overlay_EmitOverlayFace( &g_aMapOverlays.Element( iMapOverlay ) );
  339. }
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Purpose:
  343. //-----------------------------------------------------------------------------
  344. void OverlayTransition_EmitOverlayFaces( void )
  345. {
  346. int nMapOverlayCount = g_aMapWaterOverlays.Count();
  347. for( int iMapOverlay = 0; iMapOverlay < nMapOverlayCount; ++iMapOverlay )
  348. {
  349. OverlayTransition_EmitOverlayFace( &g_aMapWaterOverlays.Element( iMapOverlay ) );
  350. }
  351. }
  352. //-----------------------------------------------------------------------------
  353. // These routines were mostly stolen from MapOverlay.cpp in Hammer
  354. //-----------------------------------------------------------------------------
  355. #define OVERLAY_BASIS_U 0
  356. #define OVERLAY_BASIS_V 1
  357. #define OVERLAY_BASIS_NORMAL 2
  358. #define OVERLAY_HANDLES_COUNT 4
  359. inline void TransformPoint( const VMatrix& matrix, Vector &point )
  360. {
  361. Vector orgVector = point;
  362. matrix.V3Mul( orgVector, point );
  363. }
  364. inline bool fequal( float value, float target, float delta) { return ( (value<(target+delta))&&(value>(target-delta)) ); }
  365. //-----------------------------------------------------------------------------
  366. // Purpose: this function translate / rotate an overlay.
  367. // Input : pOverlay - the overlay to be translated
  368. // OriginOffset - the translation
  369. // AngleOffset - the rotation
  370. // Matrix - the translation / rotation matrix
  371. // Output : none
  372. //-----------------------------------------------------------------------------
  373. void Overlay_Translate( mapoverlay_t *pOverlay, Vector &OriginOffset, QAngle &AngleOffset, matrix3x4_t &Matrix )
  374. {
  375. VMatrix tmpMatrix( Matrix );
  376. Vector temp = pOverlay->vecOrigin;
  377. VectorTransform( temp, Matrix, pOverlay->vecOrigin );
  378. // erase move component
  379. tmpMatrix.SetTranslation( vec3_origin );
  380. // check if matrix would still change something
  381. if ( !tmpMatrix.IsIdentity() )
  382. {
  383. // make sure axes are normalized (they should be anyways)
  384. pOverlay->vecBasis[OVERLAY_BASIS_U].NormalizeInPlace();
  385. pOverlay->vecBasis[OVERLAY_BASIS_V].NormalizeInPlace();
  386. Vector vecU = pOverlay->vecBasis[OVERLAY_BASIS_U];
  387. Vector vecV = pOverlay->vecBasis[OVERLAY_BASIS_V];
  388. Vector vecNormal = pOverlay->vecBasis[OVERLAY_BASIS_NORMAL];
  389. TransformPoint( tmpMatrix, vecU );
  390. TransformPoint( tmpMatrix, vecV );
  391. TransformPoint( tmpMatrix, vecNormal );
  392. float fScaleU = vecU.Length();
  393. float fScaleV = vecV.Length();
  394. float flScaleNormal = vecNormal.Length();
  395. bool bIsUnit = ( fequal( fScaleU, 1.0f, 0.0001 ) && fequal( fScaleV, 1.0f, 0.0001 ) && fequal( flScaleNormal, 1.0f, 0.0001 ) );
  396. bool bIsPerp = ( fequal( DotProduct( vecU, vecV ), 0.0f, 0.0025 ) && fequal( DotProduct( vecU, vecNormal ), 0.0f, 0.0025 ) && fequal( DotProduct( vecV, vecNormal ), 0.0f, 0.0025 ) );
  397. // if ( fequal(fScaleU,1,0.0001) && fequal(fScaleV,1,0.0001) && fequal(DotProduct( vecU, vecV ),0,0.0025) )
  398. if ( bIsUnit && bIsPerp )
  399. {
  400. // transformation doesnt scale or shear anything, so just update base axes
  401. pOverlay->vecBasis[OVERLAY_BASIS_U] = vecU;
  402. pOverlay->vecBasis[OVERLAY_BASIS_V] = vecV;
  403. pOverlay->vecBasis[OVERLAY_BASIS_NORMAL] = vecNormal;
  404. }
  405. else
  406. {
  407. // more complex transformation, move UV coordinates, but leave base axes
  408. for ( int iHandle=0; iHandle<OVERLAY_HANDLES_COUNT;iHandle++)
  409. {
  410. Vector vecUV = pOverlay->vecUVPoints[iHandle];
  411. Vector vecPos = ( vecUV.x * pOverlay->vecBasis[OVERLAY_BASIS_U] + vecUV.y * pOverlay->vecBasis[OVERLAY_BASIS_V] );
  412. // to transform in world space
  413. TransformPoint( tmpMatrix, vecPos );
  414. vecUV.x = pOverlay->vecBasis[OVERLAY_BASIS_U].Dot( vecPos );
  415. vecUV.y = pOverlay->vecBasis[OVERLAY_BASIS_V].Dot( vecPos );
  416. pOverlay->vecUVPoints[iHandle] = vecUV;
  417. }
  418. }
  419. }
  420. }