@@ -59,6 +59,8 @@ CVertexStreamBoundingBoxManager::CVertexStreamBoundingBoxManager()
5959// /////////////////////////////////////////////////////////////
6060CVertexStreamBoundingBoxManager::~CVertexStreamBoundingBoxManager ()
6161{
62+ m_StreamBoundsInfoMap.clear ();
63+ m_pDevice = NULL ;
6264}
6365
6466// /////////////////////////////////////////////////////////////
@@ -75,6 +77,20 @@ CVertexStreamBoundingBoxManager* CVertexStreamBoundingBoxManager::GetSingleton()
7577 return ms_Singleton;
7678}
7779
80+ CVertexStreamBoundingBoxManager* CVertexStreamBoundingBoxManager::GetExistingSingleton ()
81+ {
82+ return ms_Singleton;
83+ }
84+
85+ void CVertexStreamBoundingBoxManager::DestroySingleton ()
86+ {
87+ if (ms_Singleton)
88+ {
89+ delete ms_Singleton;
90+ ms_Singleton = NULL ;
91+ }
92+ }
93+
7894// /////////////////////////////////////////////////////////////
7995//
8096// CVertexStreamBoundingBoxManager::OnDeviceCreate
@@ -97,6 +113,9 @@ void CVertexStreamBoundingBoxManager::OnDeviceCreate(IDirect3DDevice9* pDevice)
97113float CVertexStreamBoundingBoxManager::GetDistanceSqToGeometry (D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices,
98114 UINT startIndex, UINT primCount)
99115{
116+ if (!m_pDevice)
117+ return 0 .f ;
118+
100119 // Cache info
101120 SCurrentStateInfo2 state;
102121
@@ -203,12 +222,31 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta
203222
204223 const uint StridePT = state.stream .Stride ;
205224
225+ if (StridePT == 0 )
226+ return false ;
227+
206228 uint NumVerts = ReadSize / StridePT;
207229
230+ if (NumVerts == 0 )
231+ return false ;
232+
233+ if ((ReadSize % StridePT) != 0 )
234+ return false ;
235+
208236 // Adjust for the offset in the stream
237+ if (ReadSize < state.stream .elementOffset )
238+ return false ;
239+
209240 ReadOffsetStart += state.stream .elementOffset ;
210241 ReadSize -= state.stream .elementOffset ;
211- if (ReadSize < 1 )
242+ if (ReadSize == 0 )
243+ return false ;
244+
245+ const UINT bufferSize = state.decl .VertexBufferDesc .Size ;
246+ if (ReadOffsetStart > bufferSize)
247+ return false ;
248+
249+ if (ReadSize > bufferSize - ReadOffsetStart)
212250 return false ;
213251
214252 // Get the source vertex bytes
@@ -226,31 +264,57 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta
226264 // Compute bounds
227265 {
228266 // Get index data
229- if (FAILED (m_pDevice->GetIndices (&state.pIndexData )))
267+ if (FAILED (m_pDevice->GetIndices (&state.pIndexData )) || !state. pIndexData )
230268 return false ;
231269
232270 // Get index buffer desc
233271 D3DINDEXBUFFER_DESC IndexBufferDesc;
234272 state.pIndexData ->GetDesc (&IndexBufferDesc);
235273
274+ uint indexStride = 0 ;
275+ if (IndexBufferDesc.Format == D3DFMT_INDEX16)
276+ indexStride = sizeof (WORD);
277+ else if (IndexBufferDesc.Format == D3DFMT_INDEX32)
278+ indexStride = sizeof (DWORD);
279+ else
280+ return false ;
281+
236282 uint numIndices = state.args .primCount + 2 ;
237283 uint step = 1 ;
238284 if (state.args .PrimitiveType == D3DPT_TRIANGLELIST)
239285 {
240286 numIndices = state.args .primCount * 3 ;
241287 step = 3 ;
242288 }
243- assert (IndexBufferDesc.Size >= (numIndices + state.args .startIndex ) * 2 );
244289
245- // Get index buffer data
246- std::vector<uchar> indexArray;
247- indexArray.resize (numIndices * 2 );
248- uchar* pIndexArrayBytes = &indexArray[0 ];
290+ size_t startByte = static_cast <size_t >(state.args .startIndex ) * indexStride;
291+ size_t requiredBytes = static_cast <size_t >(numIndices) * indexStride;
292+ if (startByte > IndexBufferDesc.Size )
293+ return false ;
294+
295+ if (requiredBytes > IndexBufferDesc.Size - startByte)
296+ return false ;
297+
298+ std::vector<uint32_t > indices (numIndices);
249299 {
250300 void * pIndexBytes = NULL ;
251- if (FAILED (state.pIndexData ->Lock (state.args .startIndex * 2 , numIndices * 2 , &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
301+ if (FAILED (state.pIndexData ->Lock (static_cast <UINT>(startByte), static_cast <UINT>(requiredBytes), &pIndexBytes,
302+ D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
252303 return false ;
253- memcpy (pIndexArrayBytes, pIndexBytes, numIndices * 2 );
304+
305+ if (indexStride == sizeof (WORD))
306+ {
307+ const WORD* pSrc = static_cast <const WORD*>(pIndexBytes);
308+ for (uint i = 0 ; i < numIndices; ++i)
309+ indices[i] = pSrc[i];
310+ }
311+ else
312+ {
313+ const DWORD* pSrc = static_cast <const DWORD*>(pIndexBytes);
314+ for (uint i = 0 ; i < numIndices; ++i)
315+ indices[i] = pSrc[i];
316+ }
317+
254318 state.pIndexData ->Unlock ();
255319 }
256320
@@ -263,9 +327,9 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta
263327 for (uint i = 0 ; i < numIndices - 2 ; i += step)
264328 {
265329 // Get triangle vertex indici
266- WORD v0 = ((WORD*)pIndexArrayBytes) [i];
267- WORD v1 = ((WORD*)pIndexArrayBytes) [i + 1 ];
268- WORD v2 = ((WORD*)pIndexArrayBytes) [i + 2 ];
330+ uint32_t v0 = indices [i];
331+ uint32_t v1 = indices [i + 1 ];
332+ uint32_t v2 = indices [i + 2 ];
269333
270334 if (v0 >= NumVerts || v1 >= NumVerts || v2 >= NumVerts)
271335 continue ; // vert index out of range
@@ -314,6 +378,9 @@ bool CVertexStreamBoundingBoxManager::ComputeVertexStreamBoundingBox(SCurrentSta
314378// ///////////////////////////////////////////////////////////
315379bool CVertexStreamBoundingBoxManager::CheckCanDoThis (SCurrentStateInfo2& state)
316380{
381+ if (!m_pDevice)
382+ return false ;
383+
317384 // Only tri-lists and tri-strips
318385 if (state.args .PrimitiveType != D3DPT_TRIANGLESTRIP && state.args .PrimitiveType != D3DPT_TRIANGLELIST)
319386 return false ;
0 commit comments