void GeometryManager::_updateGeometry(Ogre::Camera* c, const Ogre::Real& timeSinceLastFrame)
	{
		// Look for current camera data
		std::vector<VClouds::CameraData>& camerasData = mVClouds->_getCamerasData();
		std::vector<VClouds::CameraData>::iterator currentCameraDataIt;

		for (currentCameraDataIt = camerasData.begin(); currentCameraDataIt != camerasData.end(); currentCameraDataIt++)
		{
			if ((*currentCameraDataIt).camera == c)
			{
				break;
			}
		}

		std::vector<VClouds::CameraData>::reference currentCameraData = (*currentCameraDataIt);

		// Calculate wind offset
		Ogre::Vector2 CameraDirection = Ogre::Vector2(c->getDerivedDirection().x, c->getDerivedDirection().z);
		float offset = - CameraDirection.dotProduct(mVClouds->getWindDirectionV2()) * mVClouds->getWindSpeed() * timeSinceLastFrame;

		// Calculate camera offset
		Ogre::Vector2 CameraOffset = Ogre::Vector2(c->getDerivedPosition().x - currentCameraData.lastPosition.x, c->getDerivedPosition().z - currentCameraData.lastPosition.z);
		offset -= CameraOffset.dotProduct(CameraDirection);

		// Update camera data
		currentCameraData.cameraOffset += CameraOffset;
		currentCameraData.lastPosition = c->getDerivedPosition();

		// Update geometry displacement
		currentCameraData.geometryDisplacement += Ogre::Vector3(offset);

		if (currentCameraData.geometryDisplacement.z < 0 || currentCameraData.geometryDisplacement.z > (mC-mB)/mNc)
		{
			currentCameraData.geometryDisplacement.z -= ((mC-mB)/mNc)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.z)/((mC-mB)/mNc));
		}

		if (currentCameraData.geometryDisplacement.y < 0 || currentCameraData.geometryDisplacement.y > (mB-mA)/mNb)
		{
			currentCameraData.geometryDisplacement.y -= ((mB-mA)/mNb)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.y)/((mB-mA)/mNb));
		}

		if (currentCameraData.geometryDisplacement.x < 0 || currentCameraData.geometryDisplacement.x > mA/mNa)
		{
			currentCameraData.geometryDisplacement.x -= (mA/mNa)*Ogre::Math::IFloor((currentCameraData.geometryDisplacement.x)/(mA/mNa));
		}

		// Check under/over cloud rendering
		mCurrentDistance = c->getDerivedPosition()-mSceneNode->_getDerivedPosition();

		for (int k = 0; k < mNumberOfBlocks; k++)
		{
			mGeometryBlocks.at(k)->setWorldOffset(mWorldOffset + currentCameraData.cameraOffset);
			mGeometryBlocks.at(k)->updateGeometry(c, currentCameraData.geometryDisplacement, mCurrentDistance);
		}
	}
	void GeometryManager::_updateGeometry(const Ogre::Real& timeSinceLastFrame)
	{
		// Calculate wind offset
		Ogre::Vector2 CameraDirection = Ogre::Vector2(mVClouds->getCamera()->getDerivedDirection().x, mVClouds->getCamera()->getDerivedDirection().z);
		float offset = - CameraDirection.dotProduct(mVClouds->getWindDirectionV2()) * mVClouds->getWindSpeed() * timeSinceLastFrame;
		mWorldOffset += mVClouds->getWindDirectionV2() * mVClouds->getWindSpeed() * timeSinceLastFrame;

		// Calculate camera offset
		Ogre::Vector2 CameraOffset = Ogre::Vector2(mVClouds->getCamera()->getDerivedPosition().x - mLastCameraPosition.x, mVClouds->getCamera()->getDerivedPosition().z - mLastCameraPosition.z);
		offset -= CameraOffset.dotProduct(CameraDirection);
		mWorldOffset += CameraOffset;

		for (int k = 0; k < mNumberOfBlocks; k++)
		{
			mGeometryBlocks.at(k)->update(offset);
			mGeometryBlocks.at(k)->setWorldOffset(mWorldOffset);
		}
	}
//-----------------------------------------------------------------------
void Triangulator::addConstraints(const Shape& shape, DelaunayTriangleBuffer& tbuffer)
{	
	std::vector<DelaunaySegment> segList;
	// Determine which segments should be added
	for (int i = 0; i<shape.getPoints().size()-1; i++)
	{		
		bool isAlreadyIn = false;
		for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++)
		{
			if (it->containsSegment(i,i+1)) 
			{
					isAlreadyIn = true;
					break;
			}			
		}
		// only do something for segments not already in DT
		if (!isAlreadyIn)
		{
			segList.push_back(DelaunaySegment(i, i+1));
		}
	}
	// Re-Triangulate according to the new segments
	for (std::vector<DelaunaySegment>::iterator it=segList.begin();it!=segList.end();it++)
	{
		// TODO remove all edges intersecting *it
		// TODO build two polygons
		// TODO Triangulate each polygon (directly into DelaunayTriangleBuffer)
	}
	// Clean up segments outside of shape
	if (shape.isClosed())
	{
		for (DelaunayTriangleBuffer::iterator it = tbuffer.begin(); it!=tbuffer.end();it++)
		{
			bool isTriangleOut = false;
			for (int i=0;i<3;i++)
			{
				int ind1 = it->i[i];
				int ind2 = it->i[(1+i)%3];					
				// if side of triangle==segment, it won't tell us if outside or inside => skip
				if (abs(ind1-ind2)!=1)
				{
					Ogre::Vector2 v = shape.getPoint(ind2)-shape.getPoint(ind1);
					Ogre::Real d1 = v.dotProduct(shape.getNormalBefore(ind1));
					Ogre::Real d2 = v.dotProduct(shape.getNormalAfter(ind1));
					Ogre::Vector2 t1 = shape.getDirectionBefore(ind1);
					Ogre::Vector2 n1 = shape.getNormalAfter(ind1);
					if (t1.dotProduct(n1)>0.)
					{
						if (d1>0. || d2>0.)
						{
							isTriangleOut = true;
							break;
						}
					}
					else
					{
						if (d1>0. && d2>0.)
						{
							isTriangleOut = true;
							break;
						}
					}					
				}
			}
			if (isTriangleOut)
			{
				it = tbuffer.erase(it);
				it--;
			}
		}			
	}

}