int* SoftGlowFilter::procImage() {
	int *blurPixels = new int[this->width * this->height];
	memcpy(blurPixels, pixels, width * height * sizeof(int));

	GaussianBlurFilter *gaussianFilter = new GaussianBlurFilter(blurPixels, width, height, blurSigma);
	blurPixels = gaussianFilter->procImage();

	int originR = 0, originG = 0, originB = 0, originA = 0;
	int pixR = 0, pixG = 0, pixB = 0, pixA = 0;

	double factorA = 1;
	double factorB = 0.3;
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			Color originColor(blurPixels[row * width + col]);
			originR = originColor.R();
			originG = originColor.G();
			originB = originColor.B();

			Color pixColor(pixels[row * width + col]);
			pixA = pixColor.alpha();
			pixR = pixColor.R();
			pixG = pixColor.G();
			pixB = pixColor.B();

			pixR = originR * factorA + pixR * factorB;
			pixG = originG * factorA + pixG * factorB;
			pixB = originB * factorA + pixB * factorB;
//			pixR = ((pixR < 128) ?
//					(2 * ((originR >> 1) + 64)) * ((float) pixR / 255) :
//					(255 - (2 * (255 - ((originR >> 1) + 64)) * (float) (255 - pixR) / 255)));
//
//			pixG = ((pixG < 128) ?
//					(2 * ((originG >> 1) + 64)) * ((float) pixG / 255) :
//					(255 - (2 * (255 - ((originG >> 1) + 64)) * (float) (255 - pixG) / 255)));
//			pixB = ((pixB < 128) ?
//					(2 * ((originB >> 1) + 64)) * ((float) pixB / 255) :
//					(255 - (2 * (255 - ((originB >> 1) + 64)) * (float) (255 - pixB) / 255)));

			pixR = min(255, max(pixR, 0));
			pixG = min(255, max(pixG, 0));
			pixB = min(255, max(pixB, 0));

			pixels[row * width + col] = ARGB2Color(pixA, pixR, pixG, pixB);
		}
	}

	delete gaussianFilter;
	return pixels;
}
int* SharpenFilter::procImage() {
	int pixR, pixG, pixB, newR, newG, newB, index;
	int laplacian[] = {0, -1, 0, -1, 4, -1, 0, -1, 0}; // 3 * 3 laplacian
	int maskSize = 3;
	int halfMaskSize = maskSize / 2;

	int *edgePixels = new int[width * height];
	memset(edgePixels, 0, width * height * sizeof(int));

	for (int i = halfMaskSize; i < height - halfMaskSize; i++)  {
		for (int k = halfMaskSize; k < width - halfMaskSize; k++)  {
			index = 0;
			newR = newG = newB = 0;
			for (int m = -halfMaskSize; m <= halfMaskSize; m++) {
				for (int n = -halfMaskSize; n <= halfMaskSize; n++) {

					Color pixColor(pixels[(i + n) * width + k + m]);
					pixR = pixColor.R();
					pixG = pixColor.G();
					pixB = pixColor.B();

					newR += pixR * laplacian[index];
					newG += pixG * laplacian[index];
					newB += pixB * laplacian[index];
					index++;
				}
			}

			newR = min(255, max(0, newR));
			newG = min(255, max(0, newG));
			newB = min(255, max(0, newB));

			edgePixels[i * width + k] = RGB2Color(newR, newG, newB);
		}
	}

	for (int i = 0; i < width * height; i++) {
		Color edgeColor(edgePixels[i]);
		Color originColor(pixels[i]);

		int r = min(255, max(0, edgeColor.R() + originColor.R()));
		int g = min(255, max(0, edgeColor.G() + originColor.G()));
		int b = min(255, max(0, edgeColor.B() + originColor.B()));

		pixels[i] = RGB2Color(r, g, b);
	}

	delete [] edgePixels;
	return pixels;
}
	static int CalculateContacts (const NewtonBody* const otherBody, void* const userData)
	{
		ShowCollisionCollide* const me = (ShowCollisionCollide*)userData;
		if (me->m_body != otherBody) {
			const int cMaxContacts = 15;
			dFloat contacts[cMaxContacts][3];
			dFloat normals[cMaxContacts][3];
			dFloat penetrations[cMaxContacts];
			dLong attributeA[cMaxContacts];
			dLong attributeB[cMaxContacts];
			NewtonWorld* const world = NewtonBodyGetWorld(otherBody);

			//NewtonBodyGetMatrix(me->m_body, &matrixA[0][0]);
			//NewtonBodyGetMatrix(otherBody, &matrixB[0][0]);
			DemoEntity* const entityA = (DemoEntity*)NewtonBodyGetUserData(me->m_body);
			DemoEntity* const entityB = (DemoEntity*)NewtonBodyGetUserData(otherBody);

			const dMatrix& matrixA = entityA->GetRenderMatrix (); 
			const dMatrix& matrixB = entityB->GetRenderMatrix ();  


			NewtonCollision* const collisionA = NewtonBodyGetCollision(me->m_body);
			NewtonCollision* const collisionB = NewtonBodyGetCollision(otherBody);

			int count = NewtonCollisionCollide (world, cMaxContacts, collisionA, &matrixA[0][0], collisionB, &matrixB[0][0], 
												&contacts[0][0], &normals[0][0], penetrations, attributeA, attributeB, 0);

			dVector originColor (1.0f, 0.0f, 0.0f, 0.0f);
			dVector lineColor (0.0f, 0.0f, 1.0f, 0.0f);
			for (int i = 0; i < count; i ++) {

				dVector n (normals[i][0], normals[i][1], normals[i][2], 0.0f);
				dVector p0 (contacts[i][0], contacts[i][1], contacts[i][2], 0.0f);
				dVector p1 (p0 + n.Scale (0.5f));
				p0 = matrixA.UntransformVector(p0);
				p1 = matrixA.UntransformVector(p1);
				ShowMousePicking (p0, p1, originColor, lineColor);
			}
		}
		return 1;
	}