VOID tEDGE_RING<_Mesh_Type, _Half_Edge_Filter>::FindRadialOrder() { cPOINT3 pointOnPlane = m_he->MidPoint(); cVECTOR3 planeNormal = m_he->UniqueVector(); cPLANE3 projectionPlane(pointOnPlane, planeNormal); eCOORD maxCoord = planeNormal.AbsMaxCoord(); center = projectionPlane.Projection(pointOnPlane).DropCoord(maxCoord); cHALF_EDGE* loopingHe = m_he; do { if(!loopingHe->IsBorder() && loopingHe->Opp()->IsBorder()) Add(loopingHe, projectionPlane. Projection(loopingHe->Next() ->Head()->Point()) .DropCoord(maxCoord)); loopingHe = loopingHe->NextInRing(); } while(loopingHe != m_he); ComputeRadialOrder(); }
bool SpriteData::GenerateConvexHull() { bool success = false; #if defined(WIN32) && USE_HAVOK_PHYSICS_2D const int bytesPerPixel = spriteSheetTexture->GetBitsPerPixel(spriteSheetTexture->GetTextureFormat()) / 8; IDirect3DTexture9 *pTexture2D = (IDirect3DTexture9 *)spriteSheetTexture->GetD3DInterface(); const int iMipLevel = 0; const int iLockFlags = D3DLOCK_READONLY; D3DLOCKED_RECT destRect; RECT lockRect = { 0, 0, spriteSheetTexture->GetTextureWidth(), spriteSheetTexture->GetTextureHeight() }; HRESULT result = pTexture2D->LockRect(iMipLevel, &destRect, NULL, spriteSheetTexture->GetD3D9LockFlags(iLockFlags)); if (result == S_OK) { const unsigned char thresholdMin = 10; unsigned char *pDest = (unsigned char *)destRect.pBits; for (int stateIndex = 0; stateIndex < cells.GetLength(); stateIndex++) { SpriteCell &cell = cells[stateIndex]; const int width = static_cast<int>(cell.width); const int height = static_cast<int>(cell.height); int *mins = new int[height]; int *maxs = new int[height]; memset(mins, -1, sizeof(int) * height); memset(maxs, -1, sizeof(int) * height); const int startX = static_cast<int>(cell.offset.x); const int endX = startX + width; const int startY = static_cast<int>(cell.offset.y); const int endY = startY + height; for (int y = startY; y < endY; y++) { bool findMin = true; const int positionY = y - startY; for (int x = startX; x < endX; x++) { unsigned char *pixelRaw = &pDest[y * destRect.Pitch + x * bytesPerPixel]; unsigned int alpha = 0; // if there's an alpha channel, just worry about that if (bytesPerPixel == 4) { const unsigned int *pixel = reinterpret_cast<unsigned int*>(pixelRaw); alpha = ((*pixel) & 0xff000000) >> 24; } else { for (int offset = 0; offset < bytesPerPixel; offset++) { alpha += pixelRaw[offset]; } } const int positionX = x - startX; const bool withinThreshold = (alpha >= thresholdMin); if (findMin && withinThreshold) { mins[positionY] = positionX; findMin = false; } else if (!findMin && !withinThreshold) { maxs[positionY] = positionX; break; } } if (maxs[positionY] == -1) { maxs[positionY] = width; } } const float hwidth = static_cast<float>(width) / 2.0f; const float hheight = static_cast<float>(height) / 2.0f; hkArray<hkVector4> vertices; for (int y = 0; y < height; y++) { if (mins[y] != -1) { hkReal xx1 = static_cast<hkReal>(mins[y]) - hwidth; hkReal xx2 = static_cast<hkReal>(maxs[y]) - hwidth; hkReal hh = static_cast<hkReal>(y) - hheight; vertices.pushBack( hkVector4(xx1, hh, 0, 0) ); vertices.pushBack( hkVector4(xx2, hh, 0, 0) ); if (y == height - 1) { hkReal hh2 = static_cast<hkReal>(y + 1) - hheight; vertices.pushBack( hkVector4(xx1, hh2, 0, 0) ); vertices.pushBack( hkVector4(xx2, hh2, 0, 0) ); } } } delete [] mins; delete [] maxs; const bool sortInputs = true; const bool simplify = false; hkgpConvexHull::BuildConfig config; config.m_allowLowerDimensions = true; config.m_buildIndices = true; config.m_sortInputs = sortInputs; hkVector4 projectionPlane(0, 0, 1); hkgpConvexHull convexHull; if ( convexHull.build(vertices, config) != -1 ) { hkgpConvexHull *result = &convexHull; result->generateIndexedFaces(hkgpConvexHull::INTERNAL_VERTICES, cell.verticesPerFace, cell.vertexIndices, true); result->fetchPositions(hkgpConvexHull::INTERNAL_VERTICES, cell.vertexPositions); hkpConvexVerticesShape::BuildConfig config; config.m_convexRadius = 0.0f; config.m_shrinkByConvexRadius = false; config.m_useOptimizedShrinking = false; cell.shape = new hkpConvexVerticesShape(cell.vertexPositions, config); const hkReal depth = 100.0f; // Generate a 3d hkArray<hkVector4> vertexPositions3d; for (int vertexIndex = 0; vertexIndex < cell.vertexPositions.getSize(); vertexIndex++) { const hkVector4 position = cell.vertexPositions[vertexIndex]; vertexPositions3d.pushBack( hkVector4(position(0), position(1), 0.0f, 0.0f) ); } // Get the bounding box of the shape and use the max extent as the depth of the 3d shape hkAabb aabb; cell.shape->getAabb( hkTransform::getIdentity(), 0.f, aabb ); const hkReal depthCenter = depth * 1.3f; hkVector4 center; aabb.getCenter(center); vertexPositions3d.pushBack( hkVector4(center(0), center(1), -depthCenter , 0.f) ); vertexPositions3d.pushBack( hkVector4(center(0), center(1), depthCenter , 0.f) ); config.m_convexRadius = 0.05f; config.m_shrinkByConvexRadius = false; cell.shape3d = new hkpConvexVerticesShape(vertexPositions3d, config); success = true; } } HRESULT unlockResult = pTexture2D->UnlockRect(iMipLevel); VASSERT(unlockResult == S_OK); }