Esempio n. 1
0
  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();
  }
Esempio n. 2
0
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);
	}