예제 #1
0
void Storm3D_Spotlight::renderStencilCone(Storm3D_Camera &camera)
{
	data->createStencilCone();

	D3DXVECTOR3 lightPosition(data->properties.position.x, data->properties.position.y, data->properties.position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(data->properties.direction.x, data->properties.direction.y, data->properties.direction.z);

	D3DXMATRIX tm;
	D3DXMatrixLookAtLH(&tm, &lightPosition, &lookAt, &up);

	/*
	VC3 cameraDir = camera.GetDirection();
	cameraDir.Normalize();
	D3DXVECTOR3 direction(cameraDir.x, cameraDir.y, cameraDir.z);
	D3DXVec3TransformNormal(&direction, &direction, &tm);
	*/

	float det = D3DXMatrixDeterminant(&tm);
	D3DXMatrixInverse(&tm, &det, &tm);
	Storm3D_ShaderManager::GetSingleton()->SetWorldTransform(data->device, tm, true);

	data->coneStencilVertexShader->apply();
	data->coneStencilVertexBuffer.apply(data->device, 0);
	data->coneStencilIndexBuffer.render(data->device, CONE_FACES, CONE_VERTICES);
}
예제 #2
0
	/**
	*	Use the transform of the camera to create the view matrix used for rendering (by taking its inverse)
	*   This is called within camera functions every time its transform is changed
	*	@author Serge Radinovich
	*/
	void Camera::updateViewMatrix()
	{
		D3DXMATRIX _worldMtx = *m_transform.matrix();

		float _fDeterminant = D3DXMatrixDeterminant(&_worldMtx);
		D3DXMatrixInverse(&_worldMtx, &_fDeterminant, &_worldMtx);

		m_viewMtx = _worldMtx;

	}
예제 #3
0
void Storm3D_SpotlightShared::setClipPlanes(const float *cameraView)
{

	D3DXMATRIX m(cameraView);
	float determinant = D3DXMatrixDeterminant(&m);
	D3DXMatrixInverse(&m, &determinant, &m);
	D3DXMatrixTranspose(&m, &m);

	D3DXVECTOR3 d(direction.x, direction.y, direction.z);
	VC2 bd(d.x, d.z);
	bd.Normalize();		
	D3DXVECTOR3 p1(position.x - 8*bd.x, position.y, position.z - 8*bd.y);
	//D3DXVECTOR3 p1(position.x - 1*bd.x, position.y, position.z - 1*bd.y);
	D3DXVECTOR3 p2(p1.x, p1.y + 5.f, p1.z);

	float angle = D3DXToRadian(fov) * .55f;

	D3DXPLANE leftPlane;
	D3DXMATRIX leftTransform;
	D3DXMatrixRotationY(&leftTransform, -angle);
	D3DXVECTOR3 leftPoint(direction.x, 0, direction.z);
	D3DXVECTOR4 leftPoint2;
	D3DXVec3Transform(&leftPoint2, &leftPoint, &leftTransform);
	leftPoint = p1;
	leftPoint.x += leftPoint2.x;
	leftPoint.z += leftPoint2.z;
	D3DXPlaneFromPoints(&leftPlane, &p1, &p2, &leftPoint);
	D3DXPlaneNormalize(&leftPlane, &leftPlane);
	D3DXPlaneTransform(&leftPlane, &leftPlane, &m);

	D3DXPLANE rightPlane;
	D3DXMATRIX rightTransform;
	D3DXMatrixRotationY(&rightTransform, angle);
	D3DXVECTOR3 rightPoint(direction.x, 0, direction.z);
	D3DXVECTOR4 rightPoint2;
	D3DXVec3Transform(&rightPoint2, &rightPoint, &rightTransform);
	rightPoint = p1;
	rightPoint.x += rightPoint2.x;
	rightPoint.z += rightPoint2.z;
	D3DXPlaneFromPoints(&rightPlane, &rightPoint, &p2, &p1);
	D3DXPlaneNormalize(&rightPlane, &rightPlane);
	D3DXPlaneTransform(&rightPlane, &rightPlane, &m);

	D3DXPLANE backPlane;
	D3DXVECTOR3 pb(p1.x, p1.y, p1.z);
	D3DXPlaneFromPointNormal(&backPlane, &pb, &d);
	D3DXPlaneNormalize(&backPlane, &backPlane);
	D3DXPlaneTransform(&backPlane, &backPlane, &m);

	device.SetClipPlane(0, leftPlane);
	device.SetClipPlane(1, rightPlane);
	device.SetClipPlane(2, backPlane);
	device.SetRenderState(D3DRS_CLIPPLANEENABLE, D3DCLIPPLANE0 | D3DCLIPPLANE1 | D3DCLIPPLANE2);
}
예제 #4
0
void lcNode::AttachChild(lcNode* a_pChild)
{
	//Change Local of Child
	D3DXMATRIX kInvRotate;
	float fDeterminant = D3DXMatrixDeterminant(&m_mLocalRotate);
	D3DXMatrixInverse(&kInvRotate,&fDeterminant,&m_mLocalRotate);
	a_pChild->m_kLocalTranslate -= m_kLocalTranslate;
	D3DXVec3TransformCoord(&a_pChild->m_kLocalTranslate,&a_pChild->m_kLocalTranslate,&kInvRotate);
	D3DXMatrixMultiply(&a_pChild->m_mLocalRotate,&a_pChild->m_mLocalRotate,&kInvRotate);
	
	a_pChild->m_pParent = this;
	m_pChildren.push_back(a_pChild);
	m_uiChildCount++;
}
예제 #5
0
QUAT Storm3D_Spotlight::getOrientation() const
{
	D3DXVECTOR3 lightPosition(data->properties.position.x, data->properties.position.y, data->properties.position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(data->properties.direction.x, data->properties.direction.y, data->properties.direction.z);

	D3DXMATRIX tm;
	D3DXMatrixLookAtLH(&tm, &lightPosition, &lookAt, &up);

	float det = D3DXMatrixDeterminant(&tm);
	D3DXMatrixInverse(&tm, &det, &tm);

	MAT m;

	for(int j = 0; j < 4; ++j)
	for(int i = 0; i < 4; ++i)
		m.Set(j*4 + i, tm[j*4 + i]);

	return m.GetRotation();
}
예제 #6
0
Matrix3& Matrix3::Invert()
{
#ifdef __USE_D3DX__
	Float32 fDet;
	fDet = D3DXMatrixDeterminant( (D3DXMATRIX*)&mat );
	D3DXMatrixInverse( (D3DXMATRIX*)&mat, &fDet, (D3DXMATRIX*)&mat );
#else

	Real inv[16], fDet;

	inv[0]  = e[5] * e[10] * e[15] - e[5] * e[11] * e[14] - e[9] * e[6] * e[15] + e[9] * e[7] * e[14] + e[13] * e[6] * e[11] - e[13] * e[7] * e[10];
	inv[4]  =-e[4] * e[10] * e[15] + e[4] * e[11] * e[14] + e[8] * e[6] * e[15] - e[8] * e[7] * e[14] - e[12] * e[6] * e[11] + e[12] * e[7] * e[10];
	inv[8]  = e[4] * e[9] * e[15] - e[4] * e[11] * e[13] - e[8] * e[5] * e[15] + e[8] * e[7] * e[13] + e[12] * e[5] * e[11] - e[12] * e[7] * e[9];
	inv[12] =-e[4] * e[9] * e[14] + e[4] * e[10] * e[13] + e[8] * e[5] * e[14] - e[8] * e[6] * e[13] - e[12] * e[5] * e[10] + e[12] * e[6] * e[9];
	inv[1]  =-e[1] * e[10] * e[15] + e[1] * e[11] * e[14] + e[9] * e[2] * e[15] - e[9] * e[3] * e[14] - e[13] * e[2] * e[11] + e[13] * e[3] * e[10];
	inv[5]  = e[0] * e[10] * e[15] - e[0] * e[11] * e[14] - e[8] * e[2] * e[15] + e[8] * e[3] * e[14] + e[12] * e[2] * e[11] - e[12] * e[3] * e[10];
	inv[9]  =-e[0] * e[9] * e[15] + e[0] * e[11] * e[13] + e[8] * e[1] * e[15] - e[8] * e[3] * e[13] - e[12] * e[1] * e[11] + e[12] * e[3] * e[9];
	inv[13] = e[0] * e[9] * e[14] - e[0] * e[10] * e[13] - e[8] * e[1] * e[14] + e[8] * e[2] * e[13] + e[12] * e[1] * e[10] - e[12] * e[2] * e[9];
	inv[2]  = e[1] * e[6] * e[15] - e[1] * e[7] * e[14] - e[5] * e[2] * e[15] + e[5] * e[3] * e[14] + e[13] * e[2] * e[7] - e[13] * e[3] * e[6];
	inv[6]  =-e[0] * e[6] * e[15] + e[0] * e[7] * e[14] + e[4] * e[2] * e[15] - e[4] * e[3] * e[14] - e[12] * e[2] * e[7] + e[12] * e[3] * e[6];
	inv[10] = e[0] * e[5] * e[15] - e[0] * e[7] * e[13] - e[4] * e[1] * e[15] + e[4] * e[3] * e[13] + e[12] * e[1] * e[7] - e[12] * e[3] * e[5];
	inv[14] =-e[0] * e[5] * e[14] + e[0] * e[6] * e[13] + e[4] * e[1] * e[14] - e[4] * e[2] * e[13] - e[12] * e[1] * e[6] + e[12] * e[2] * e[5];
	inv[3]  =-e[1] * e[6] * e[11] + e[1] * e[7] * e[10] + e[5] * e[2] * e[11] - e[5] * e[3] * e[10] - e[9] * e[2] * e[7] + e[9] * e[3] * e[6];
	inv[7]  = e[0] * e[6] * e[11] - e[0] * e[7] * e[10] - e[4] * e[2] * e[11] + e[4] * e[3] * e[10] + e[8] * e[2] * e[7] - e[8] * e[3] * e[6];
	inv[11] =-e[0] * e[5] * e[11] + e[0] * e[7] * e[9] + e[4] * e[1] * e[11] - e[4] * e[3] * e[9] - e[8] * e[1] * e[7] + e[8] * e[3] * e[5];
	inv[15] = e[0] * e[5] * e[10] - e[0] * e[6] * e[9] - e[4] * e[1] * e[10] + e[4] * e[2] * e[9] + e[8] * e[1] * e[6] - e[8] * e[2] * e[5];

    fDet = e[0] * inv[0] + e[1] * inv[4] + e[2] * inv[8] + e[3] * inv[12];

    if( fDet != 0 )
	{
		fDet = 1.0f / fDet;

		for( Int32 i = 0; i < 16; i++ )
			(*this)[i] = inv[i] * fDet;
	}

#endif
	return *this;
}
예제 #7
0
LRESULT CALLBACK d3d9::WndProc(
	HWND hWnd,
	UINT msg,
	WPARAM wParam,
	LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
			DestroyWindow(hWnd);
		break;
	case WM_LBUTTONDOWN:
	{
		Ray ray;
		if (CalcPickingRay(LOWORD(lParam), HIWORD(lParam), g_pDevice, &ray))
		{
			D3DXMATRIX view;
			g_pDevice->GetTransform(D3DTS_VIEW, &view);
			D3DXMATRIX inverse;
			float determinant = D3DXMatrixDeterminant(&view);
			D3DXMatrixInverse(&inverse, &determinant, &view);
			TransformRay(&ray, &inverse);

			if (RayHitSephere(&ray, &g_BSephere))
			{
				MessageBox(0, "Hit!", "HIT", 0);
			}
		}
		break;
	}
		
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}
예제 #8
0
bool Storm3D_SpotlightShared::setScissorRect(Storm3D_Camera &camera, const VC2I &screenSize, Storm3D_Scene *scene)
{
	D3DXMATRIX light;
	D3DXVECTOR3 lightPosition(position.x, position.y, position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(direction.x, direction.y, direction.z);
	D3DXMatrixLookAtLH(&light, &lightPosition, &lookAt, &up);

	// Create frustum vertices

	D3DXVECTOR3 v[5];
	v[0] = D3DXVECTOR3(0, 0, 0);
	v[1] = D3DXVECTOR3(0, 0, 1.f);
	v[2] = D3DXVECTOR3(0, 0, 1.f);
	v[3] = D3DXVECTOR3(0, 0, 1.f);
	v[4] = D3DXVECTOR3(0, 0, 1.f);

	float det = D3DXMatrixDeterminant(&light);
	D3DXMatrixInverse(&light, &det, &light);
	float angle = D3DXToRadian(fov) * .5f;
	for(int i = 0; i <= 4; ++i)
	{
		if(i > 0)
		{
			float z = v[i].z;
			if(i == 1 || i == 2)
			{
				v[i].x = z * sinf(angle);
				v[i].z = z * cosf(angle);
			}
			else
			{
				v[i].x = z * sinf(-angle);
				v[i].z = z * cosf(-angle);
			}

			if(i == 1 || i == 3)
				v[i].y = z * sinf(angle);
			else
				v[i].y = z * sinf(-angle);

			float scale = range / cosf(angle);
			v[i] *= scale;
		}

		D3DXVec3TransformCoord(&v[i], &v[i], &light);
	}

	// Create area

	const Frustum &frustum = camera.getFrustum();
	int minX = screenSize.x;
	int minY = screenSize.y;
	int maxX = 0;
	int maxY = 0;

	for(int i = 0; i < 6; ++i)
	{
		VC3 v1;
		VC3 v2;
		VC3 v3;

		if(i == 0)
		{
			v1 = toVC3(v[0]);
			v2 = toVC3(v[1]);
			v3 = toVC3(v[2]);
		}
		else if(i == 1)
		{
			v1 = toVC3(v[0]);
			v2 = toVC3(v[2]);
			v3 = toVC3(v[4]);
		}
		else if(i == 2)
		{
			v1 = toVC3(v[0]);
			v2 = toVC3(v[3]);
			v3 = toVC3(v[4]);
		}
		else if(i == 3)
		{
			v1 = toVC3(v[0]);
			v2 = toVC3(v[1]);
			v3 = toVC3(v[3]);
		}
		else if(i == 4)
		{
			v1 = toVC3(v[1]);
			v2 = toVC3(v[2]);
			v3 = toVC3(v[3]);
		}
		else if(i == 5)
		{
			v1 = toVC3(v[4]);
			v2 = toVC3(v[2]);
			v3 = toVC3(v[3]);
		}

		const ClipPolygon &clipPolygon = clipTriangleToFrustum(v1, v2, v3, frustum);
		for(int j = 0; j < clipPolygon.vertexAmount; ++j)
		{
			VC3 result;
			float rhw = 0.f;
			float real_z = 0.f;
			camera.GetTransformedToScreen(clipPolygon.vertices[j], result, rhw, real_z);

			int x = int(result.x * screenSize.x);
			int y = int(result.y * screenSize.y);
			//if(x < -1 || x > screenSize.x)
			//	continue;
			//if(y < -1 || x > screenSize.y)
			//	continue;

			x = max(x, 0);
			y = max(y, 0);
			x = min(x, screenSize.x - 1);
			y = min(y, screenSize.y - 1);

			maxX = max(x, maxX);
			maxY = max(y, maxY);
			minX = min(x, minX);
			minY = min(y, minY);

			/*
			// Visualize clipped polygons
			if(scene)
			{
				VC3 p1 = clipPolygon.vertices[j];
				VC3 p2 = clipPolygon.vertices[(j + 1) % clipPolygon.vertexAmount];


				for(int k = 0; k < 5; ++k)
				{
					const VC3 &planeNormal = frustum.planeNormals[k];
					PLANE plane;

					if(k == 0)
						plane.MakeFromNormalAndPosition(planeNormal, frustum.position + planeNormal);
					else
						plane.MakeFromNormalAndPosition(planeNormal, frustum.position);
	
					float d1 = plane.GetPointRange(p1);
					float d2 = plane.GetPointRange(p2);

					if(d1 < .25f)
						p1 += planeNormal * (.25f - d1);
					if(d2 < .25f)
						p2 += planeNormal * (.25f - d2);
				}

				scene->AddLine(p1, p2, COL(1.f, 1.f, 1.f));
			}
			*/
		}
	}

	RECT rc;
	bool visible = false;

	if(maxX > minX && maxY > minY)
	{
		visible = true;
		rc.left = minX;
		rc.top = minY;
		rc.right = maxX;
		rc.bottom = maxY;
	}
	else
	{
		visible = false;
		rc.left = 0;
		rc.top = 0;
		rc.right = 1;
		rc.bottom = 1;
	}
/*
	// Visualize scissor area
	if(scene && visible)
	{
		static DWORD foo = GetTickCount();
		int dif = (GetTickCount() - foo) % 2000;
		if(dif < 1000)
			scene->Render2D_Picture(0, VC2(float(minX), float(minY)), VC2(float(maxX - minX), float(maxY - minY)), 0.5f, 0.f, 0, 0, 0, 0, false);
	}
*/
	device.SetScissorRect(&rc);
	device.SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);

	return visible;
}
예제 #9
0
void Storm3D_SpotlightShared::updateMatrices(const D3DXMATRIX &cameraView, float bias)
{
	D3DXVECTOR3 lightPosition(position.x, position.y, position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(direction.x, direction.y, direction.z);

	D3DXMatrixPerspectiveFovLH(&lightProjection, D3DXToRadian(fov), 1.f, .2f, range);
	D3DXMATRIX cameraMatrix(cameraView);
	float det = D3DXMatrixDeterminant(&cameraMatrix);
	D3DXMatrixInverse(&cameraMatrix, &det, &cameraMatrix);

	float currentBias = bias;
	for(int i = 0; i < 2; ++i)
	{	
		D3DXMatrixLookAtLH(&lightView[i], &lightPosition, &lookAt, &up);
		//if(i == 1)
		//	currentBias = 0;
		if(i == 1)
			currentBias = 1.f;

		// Tweak matrix
		float soffsetX = 0.5f;
		float soffsetY = 0.5f;
		float scale = 0.5f;

		/*
		D3DXMATRIX shadowTweak( scale,    0.0f,     0.0f,				0.0f,
								0.0f,     -scale,   0.0f,				0.0f,
								0.0f,      0.0f,     float(tweakRange),	0.0f,
								soffsetX,  soffsetY, currentBias,		1.0f );
		*/
		D3DXMATRIX shadowTweak( scale,    0.0f,      0.0f,				0.0f,
								0.0f,     -scale,    0.0f,				0.0f,
								0.0f,      0.0f,	 currentBias,		0.0f,
								soffsetX,  soffsetY, 0.f,				1.0f );

		D3DXMatrixMultiply(&shadowProjection[i], &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&shadowProjection[i], &lightView[i], &shadowProjection[i]);
		D3DXMatrixMultiply(&lightViewProjection[i], &lightView[i], &lightProjection);

		shaderProjection[i] = shadowProjection[i];
		D3DXMatrixMultiply(&shadowProjection[i], &cameraMatrix, &shadowProjection[i]);
	}

	{
		float xf = (1.f / resolutionX * .5f);
		float yf = (1.f / resolutionY * .5f);
		float sX = soffsetX + (2 * targetPos.x * soffsetX) - xf;
		float sY = soffsetY + (2 * targetPos.y * soffsetY) - yf;

		/*
		D3DXMATRIX shadowTweak( scaleX,    0.0f,	0.0f,				0.0f,
								0.0f,    -scaleY,	0.0f,				0.0f,
								0.0f,     0.0f,     float(tweakRange),	0.0f,
								sX,       sY,		bias,				1.0f );
		*/

		D3DXMATRIX shadowTweak( scaleX,    0.0f,	0.0f,				0.0f,
								0.0f,    -scaleY,	0.0f,				0.0f,
								0.0f,     0.0f,     bias,				0.0f,
								sX,       sY,		0.f,				1.0f );

		D3DXMatrixMultiply(&targetProjection, &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&targetProjection, &lightView[0], &targetProjection);
	}
}
예제 #10
0
void Storm3D_SpotlightShared::updateMatricesOffCenter(const D3DXMATRIX &cameraView, const VC2 &min, const VC2 &max, float height, Storm3D_Camera &camera)
{
	// Position of the light in global coordinates
	// Y-axis is height
	D3DXVECTOR3 lightPosition(position.x, position.y, position.z);
	// Up vector (z-axis)
	D3DXVECTOR3 up(0.f, 0.f, 1.f);
	// Look direction
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt.y -= 1.f;

	{
		// max and min define the extents of light area in local coordinates
		// Z-axis is height
		float zmin = 0.2f;
		//float zmax = std::max(range, height) * 1.4f;
		// height is light height from light properties
		float zmax = height;
		float factor = 1.5f * zmin / height;
		float xmin = min.x * factor;
		float xmax = max.x * factor;
		float ymin = min.y * factor;
		float ymax = max.y * factor;
		D3DXMatrixPerspectiveOffCenterLH(&lightProjection, xmin, xmax, ymin, ymax, zmin, zmax);

		// Calculate the extents of light area in global coordinates
		VC2 worldMin = min;
		worldMin.x += position.x;
		worldMin.y += position.z;
		VC2 worldMax = max;
		worldMax.x += position.x;
		worldMax.y += position.z;

		// Generate approximate camera for culling.

		// Calculate range of the camera.
		// Y-axis is height
		float planeY = position.y - height;
		// Calculate distances from light position to light plane edges
		VC3 p1 = VC3( worldMin.x, planeY, worldMin.y ) - position;
		VC3 p2 = VC3( worldMax.x, planeY, worldMin.y ) - position;
		VC3 p3 = VC3( worldMax.x, planeY, worldMax.y ) - position;
		VC3 p4 = VC3( worldMin.x, planeY, worldMax.y ) - position;
		float d1 = p1.GetLength();
		float d2 = p2.GetLength();
		float d3 = p3.GetLength();
		float d4 = p4.GetLength();
		float maxRange = 0.0f;
		maxRange = MAX( maxRange, d1 );
		maxRange = MAX( maxRange, d2 );
		maxRange = MAX( maxRange, d3 );
		maxRange = MAX( maxRange, d4 );
		//maxRange = sqrtf(maxRange);

		// Calculate FOV of the camera.
		VC3 planeCenter = VC3( (worldMin.x + worldMax.x) * 0.5f, planeY, (worldMin.y + worldMax.y) * 0.5f );
		VC3 camVec = planeCenter - position;
		camVec.Normalize();
		float minDot = 10000.0f;
		float t1 = camVec.GetDotWith( p1 ) / d1;
		float t2 = camVec.GetDotWith( p2 ) / d2;
		float t3 = camVec.GetDotWith( p3 ) / d3;
		float t4 = camVec.GetDotWith( p4 ) / d4;
		minDot = MIN( minDot, t1 );
		minDot = MIN( minDot, t2 );
		minDot = MIN( minDot, t3 );
		minDot = MIN( minDot, t4 );
		float maxAngle = acosf( minDot );

		// Place camera to light position
		camera.SetPosition(position);
		camera.SetUpVec(VC3(0.f, 0.f, 1.f));
		// Point camera at light plane center
		camera.SetTarget(planeCenter);
		camera.SetFieldOfView( maxAngle );
		camera.SetVisibilityRange( maxRange );
	}
	
	D3DXMATRIX cameraMatrix(cameraView);
	float det = D3DXMatrixDeterminant(&cameraMatrix);
	D3DXMatrixInverse(&cameraMatrix, &det, &cameraMatrix);

	unsigned int tweakRange = 1;
	float bias = 0.f;
	float currentBias = 0.f;
	for(int i = 0; i < 2; ++i)
	{	
		D3DXMatrixLookAtLH(&lightView[i], &lightPosition, &lookAt, &up);
		if(i == 1)
			currentBias = 0;

		// Tweak matrix
		float soffsetX = 0.5f;
		float soffsetY = 0.5f;
		float scale = 0.5f;

		D3DXMATRIX shadowTweak( scale,    0.0f,     0.0f,				0.0f,
								0.0f,     -scale,   0.0f,				0.0f,
								0.0f,      0.0f,     float(tweakRange),	0.0f,
								soffsetX,  soffsetY, currentBias,		1.0f );

		D3DXMatrixMultiply(&shadowProjection[i], &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&shadowProjection[i], &lightView[i], &shadowProjection[i]);
		D3DXMatrixMultiply(&lightViewProjection[i], &lightView[i], &lightProjection);

		shaderProjection[i] = shadowProjection[i];
		D3DXMatrixMultiply(&shadowProjection[i], &cameraMatrix, &shadowProjection[i]);
	}

	{
		float xf = (1.f / resolutionX * .5f);
		float yf = (1.f / resolutionY * .5f);
		float sX = soffsetX + (2 * targetPos.x * soffsetX) - xf;
		float sY = soffsetY + (2 * targetPos.y * soffsetY) - yf;

		D3DXMATRIX shadowTweak( scaleX,    0.0f,	0.0f,				0.0f,
								0.0f,    -scaleY,	0.0f,				0.0f,
								0.0f,     0.0f,     float(tweakRange),	0.0f,
								sX,       sY,		bias,				1.0f );

		D3DXMatrixMultiply(&targetProjection, &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&targetProjection, &lightView[0], &targetProjection);
	}
}
bool Storm3D_SpotlightShared::setScissorRect(Storm3D_Camera &camera, const VC2I &screenSize)
{
	D3DXMATRIX light;
	D3DXVECTOR3 lightPosition(position.x, position.y, position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(direction.x, direction.y, direction.z);
	D3DXMatrixLookAtLH(&light, &lightPosition, &lookAt, &up);

	D3DXVECTOR3 v[5];
	v[0] = D3DXVECTOR3(0, 0, 0);
	v[1] = D3DXVECTOR3(0, 0, 1.f);
	v[2] = D3DXVECTOR3(0, 0, 1.f);
	v[3] = D3DXVECTOR3(0, 0, 1.f);
	v[4] = D3DXVECTOR3(0, 0, 1.f);

	int minX = screenSize.x;
	int minY = screenSize.y;
	int maxX = 0;
	int maxY = 0;

	float det = D3DXMatrixDeterminant(&light);
	D3DXMatrixInverse(&light, &det, &light);

	float angle = D3DXToRadian(fov) * .5f;
	for(int i = 0; i <= 4; ++i)
	{
		if(i > 0)
		{
			float z = v[i].z;
			if(i == 1 || i == 2)
			{
				v[i].x = z * sinf(angle);
				v[i].z = z * cosf(angle);
			}
			else
			{
				v[i].x = z * sinf(-angle);
				v[i].z = z * cosf(-angle);
			}

			if(i == 1 || i == 3)
				v[i].y = z * sinf(angle);
			else
				v[i].y = z * sinf(-angle);

			float scale = range / cosf(angle);
			v[i] *= scale;
		}

		D3DXVec3TransformCoord(&v[i], &v[i], &light);
	}

	const Frustum &frustum = camera.getFrustum();
	calculateLineToScissor(toVC3(v[0]), toVC3(v[1]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[0]), toVC3(v[2]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[0]), toVC3(v[3]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[0]), toVC3(v[4]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[1]), toVC3(v[2]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[2]), toVC3(v[3]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[3]), toVC3(v[4]), frustum, camera, screenSize, minX, minY, maxX, maxY);
	calculateLineToScissor(toVC3(v[4]), toVC3(v[1]), frustum, camera, screenSize, minX, minY, maxX, maxY);

	/*
	VC3 cameraPos = camera.GetPosition();
	VC3 cameraPosResult;
	float cameraRhw = 0, cameraRealZ = 0;
	bool cameraVisible = camera.GetTransformedToScreen(cameraPos, cameraPosResult, cameraRhw, cameraRealZ);

	for(i = 0; i <= 4; ++i)
	{
		VC3 source(v[i].x, v[i].y, v[i].z);
		VC3 result;
		float rhw = 0, realZ = 0;
		bool inFront = camera.GetTransformedToScreen(source, result, rhw, realZ);

		// HAX HAX!

		result.x = std::max(0.f, result.x);
		result.y = std::max(0.f, result.y);
		result.x = std::min(1.f, result.x);
		result.y = std::min(1.f, result.y);

		//if(fabsf(rhw) < 0.0001f)
		//	continue;

		bool flip = false;
		if(realZ < cameraRealZ)
			flip = true;

		if(flip)
		{
			result.x = 1.f - result.x;
			result.y = 1.f - result.y;

			//minX = 0;
			//minY = 0;
			//maxX = screenSize.x;
			//maxY = screenSize.y;
		}

		int x = int(result.x * screenSize.x);
		int y = int(result.y * screenSize.y);

		maxX = std::max(x, maxX);
		maxY = std::max(y, maxY);
		minX = std::min(x, minX);
		minY = std::min(y, minY);
	}
	*/

	if(maxX > screenSize.x)
		maxX = screenSize.x;
	if(maxY > screenSize.y)
		maxY = screenSize.y;
	if(minX < 0)
		minX = 0;
	if(minY < 0)
		minY = 0;

	RECT rc;
	rc.left = minX;
	rc.top = minY;
	rc.right = maxX;
	rc.bottom = maxY;

	if(rc.left < rc.right && rc.top < rc.bottom)
	{
		device.SetScissorRect(&rc);
		device.SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
	}
	else
	{
		RECT rc;
		rc.left = 0;
		rc.top = 0;
		rc.right = 1;
		rc.bottom = 1;

		device.SetScissorRect(&rc);
		device.SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);

		return false;
	}

	return true;
}
예제 #12
0
float float4x4::Determinant() {
	return D3DXMatrixDeterminant(this);
}
예제 #13
0
void Storm3D_Spotlight::renderCone(Storm3D_Camera &camera, float timeFactor, bool renderGlows)
{
	if(!data->hasCone || !data->hasShadows || !data->shadowMap)
		return;

	bool normalPass = !data->coneUpdated;
	if(data->hasCone && data->updateCone && !data->coneUpdated)
	{
		data->createCone();
		data->coneUpdated = true;
	}

	D3DXVECTOR3 lightPosition(data->properties.position.x, data->properties.position.y, data->properties.position.z);
	D3DXVECTOR3 up(0, 1.f, 0);
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt += D3DXVECTOR3(data->properties.direction.x, data->properties.direction.y, data->properties.direction.z);

	D3DXMATRIX tm;
	D3DXMatrixLookAtLH(&tm, &lightPosition, &lookAt, &up);

	VC3 cameraDir = camera.GetDirection();
	cameraDir.Normalize();
	D3DXVECTOR3 direction(cameraDir.x, cameraDir.y, cameraDir.z);
	D3DXVec3TransformNormal(&direction, &direction, &tm);

	Storm3D_ShaderManager::GetSingleton()->setSpot(data->properties.color, data->properties.position, data->properties.direction, data->properties.range, .1f);
	Storm3D_ShaderManager::GetSingleton()->setTextureTm(data->properties.shaderProjection[0]);
	Storm3D_ShaderManager::GetSingleton()->setSpotTarget(data->properties.targetProjection);

	float det = D3DXMatrixDeterminant(&tm);
	D3DXMatrixInverse(&tm, &det, &tm);
	Storm3D_ShaderManager::GetSingleton()->SetWorldTransform(data->device, tm, true);

	if(data->shadowMap && data->shadowMap->hasInitialized())
		data->shadowMap->apply(0);
	if(data->coneTexture)
	{
		data->coneTexture->AnimateVideo();
		data->coneTexture->Apply(3);

		if(type == AtiBuffer || type == AtiFloatBuffer)
			data->coneTexture->Apply(4);
		else
			data->coneTexture->Apply(1);
	}

	if(type == AtiBuffer)
	{
		if(data->coneTexture)
			data->coneAtiPixelShader_Texture->apply();
		else
			data->coneAtiPixelShader_NoTexture->apply();

	}
	else if(type == AtiFloatBuffer)
	{
		if(data->coneTexture)
			data->coneAtiFloatPixelShader_Texture->apply();
		else
			data->coneAtiFloatPixelShader_NoTexture->apply();
	}
	else
	{
		if(data->coneTexture)
			data->coneNvPixelShader_Texture->apply();
		else
			data->coneNvPixelShader_NoTexture->apply();
	}

	float colorMul = data->coneColorMultiplier;
	float colorData[4] = { data->properties.color.r * colorMul, data->properties.color.g * colorMul, data->properties.color.b * colorMul, 1.f };
	if(renderGlows)
	{
		if(normalPass)
		{
			colorData[0] *= 0.2f;
			colorData[1] *= 0.2f;
			colorData[2] *= 0.2f;
			colorData[3] *= 0.2f;
		}
		else
		{
			colorData[0] *= 0.4f;
			colorData[1] *= 0.4f;
			colorData[2] *= 0.4f;
			colorData[3] *= 0.4f;
		}
	}

	data->device.SetVertexShaderConstantF(9, colorData, 1);

	float bias = 0.005f;
	float directionData[4] = { -direction.x, -direction.y, -direction.z, bias };
	data->device.SetVertexShaderConstantF(10, directionData, 1);

	for(int i = 0; i < 2; ++i)
	{
		data->angle[i] += data->speed[i] * timeFactor;
		D3DXVECTOR3 center(0.5f, 0.5f, 0.f);
		D3DXQUATERNION quat1;
		D3DXQuaternionRotationYawPitchRoll(&quat1, 0, 0, data->angle[i]);
		D3DXMATRIX rot1;
		D3DXMatrixAffineTransformation(&rot1, 1.f, &center, &quat1, 0);
		D3DXMatrixTranspose(&rot1, &rot1);
		
		if(i == 0)
			data->device.SetVertexShaderConstantF(16, rot1, 3);
		else
			data->device.SetVertexShaderConstantF(19, rot1, 3);
	}

	frozenbyte::storm::enableMipFiltering(data->device, 0, 0, false);
	data->coneVertexBuffer.apply(data->device, 0);
	data->coneIndexBuffer.render(data->device, CONE_FACES, CONE_VERTICES);
	frozenbyte::storm::enableMipFiltering(data->device, 0, 0, true);
}
예제 #14
0
D3DXMATRIX Interpolate( const D3DXMATRIX& MatrixA, const D3DXMATRIX& MatrixB, float lamda)
{
	D3DXMATRIX iMat = MatrixA;
	D3DXMATRIX result = MatrixB;

	// Inverse of MatrixA
	FLOAT determinant = D3DXMatrixDeterminant(&iMat);
	D3DXMatrixInverse(&iMat, &determinant, &iMat);

	// Remove MatrixA's transformation from MatrixB
	result *= iMat;

	// iMat is now the intermediary transformation from MatrixA to MatrixB
	// ie: iMat * MatrixA = MatrixB
	iMat = result;

	// The trace of our matrix
	float trace = 1.0f + iMat._11 + iMat._22 + iMat._33;

	float quatResult[4];

	// Calculate the quaternion of iMat
	// If trace is greater than 0, but consider small values that
	// might result in 0 when operated upon due to floating point error
	if( trace > 0.00000001 )
	{
		float S = sqrt(trace)*2;
		quatResult[0] = (iMat._32 - iMat._23) / S;
		quatResult[1] = (iMat._13 - iMat._31) / S;
		quatResult[2] = (iMat._21 - iMat._12) / S;
		quatResult[3] = 0.25f * S;
	}
	else
	{
		if( iMat._11 > iMat._22 && iMat._11 > iMat._33 )
		{
			float S = float(sqrt( 1.0 + iMat._11 - iMat._22 - iMat._33 ) * 2);
			quatResult[0] = 0.25f * S;
			quatResult[1] = (iMat._21 + iMat._12) / S;
			quatResult[2] = (iMat._13 + iMat._31) / S;
			quatResult[3] = (iMat._32 - iMat._23) / S;
		}
		else if( iMat._22 > iMat._33 )
		{
			float S = float(sqrt( 1.0 + iMat._22 - iMat._11 - iMat._33 ) * 2);
			quatResult[0] = (iMat._21 + iMat._12) / S;
			quatResult[1] = 0.25f * S;
			quatResult[2] = (iMat._32 + iMat._23) / S;
			quatResult[3] = (iMat._13 - iMat._31) / S;
		}
		else
		{
			float S = float(sqrt( 1.0 + iMat._33 - iMat._11 - iMat._22 ) * 2);
			quatResult[0] = (iMat._13 + iMat._31) / S;
			quatResult[1] = (iMat._32 + iMat._23) / S;
			quatResult[2] = 0.25f * S;
			quatResult[3] = (iMat._21 - iMat._12) / S;
		}
	}

	// Get the magnitude of our quaternion
	float quatMagnitude = sqrt( quatResult[0]*quatResult[0] + quatResult[1]*quatResult[1] + quatResult[2]*quatResult[2] + quatResult[3]*quatResult[3] );

	// Normalize our quaternion
	float quatNormalized[4] = { quatResult[0]/quatMagnitude, quatResult[1]/quatMagnitude, quatResult[2]/quatMagnitude, quatResult[3]/quatMagnitude }; 

	// Calculate the angles relevant to our quaternion
	float cos_a = quatNormalized[3];
	float angle = acos( cos_a ) * 2;
	float sin_a = float(sqrt( 1.0 - cos_a * cos_a ));
	
	// If there was no rotation between matrices, calculation
	// of the rotation matrix will end badly. So just do the linear
	// interpolation of the translation component and return
	if( angle == 0.0 )
	{
		result = MatrixA;

		result.m[3][0] = MatrixA.m[3][0] + ((MatrixB.m[3][0]-MatrixA.m[3][0])*lamda);
		result.m[3][1] = MatrixA.m[3][1] + ((MatrixB.m[3][1]-MatrixA.m[3][1])*lamda);
		result.m[3][2] = MatrixA.m[3][2] + ((MatrixB.m[3][2]-MatrixA.m[3][2])*lamda);

		return result;
	}


	// Our axis of abitrary rotation
	D3DXVECTOR3 axis;

	if( fabs( sin_a ) < 0.0005 )
		sin_a = 1;

	axis.x = quatNormalized[0] / sin_a;
	axis.y = quatNormalized[1] / sin_a;
	axis.z = quatNormalized[2] / sin_a;

	// Get the portion of the angle to rotate by
	angle *= lamda;

	D3DXVec3Normalize(&axis, &axis);

	// Calculate the quaternion for our new (partial) angle of rotation
	sin_a = sin( angle / 2 );
	cos_a = cos( angle / 2 );
	quatNormalized[0] = axis.x * sin_a;
	quatNormalized[1] = axis.y * sin_a;
	quatNormalized[2] = axis.z * sin_a;
	quatNormalized[3] = cos_a;

	quatMagnitude = sqrt( quatNormalized[0]*quatNormalized[0] + quatNormalized[1]*quatNormalized[1] + quatNormalized[2]*quatNormalized[2] + quatNormalized[3]*quatNormalized[3] );		
	quatNormalized[0] /= quatMagnitude;
	quatNormalized[1] /= quatMagnitude;
	quatNormalized[2] /= quatMagnitude;
	quatNormalized[3] /= quatMagnitude;

	// Calculate our partial rotation matrix
	float xx      = quatNormalized[0] * quatNormalized[0];
	float xy      = quatNormalized[0] * quatNormalized[1];
	float xz      = quatNormalized[0] * quatNormalized[2];
	float xw      = quatNormalized[0] * quatNormalized[3];
	float yy      = quatNormalized[1] * quatNormalized[1];
	float yz      = quatNormalized[1] * quatNormalized[2];
	float yw      = quatNormalized[1] * quatNormalized[3];
	float zz      = quatNormalized[2] * quatNormalized[2];
	float zw      = quatNormalized[2] * quatNormalized[3];

	result._11  = 1 - 2 * ( yy + zz );
	result._12  =     2 * ( xy - zw );
	result._13  =     2 * ( xz + yw );
	result._21  =     2 * ( xy + zw );
	result._22  = 1 - 2 * ( xx + zz );
	result._23  =     2 * ( yz - xw );
	result._31  =     2 * ( xz - yw );
	result._32  =     2 * ( yz + xw );
	result._33 = 1 - 2 * ( xx + yy );
	result._14  = result._24 = result._34 = result._41 = result._42 = result._43 = 0;
	result._44 = 1;

	// Combine our partial rotation with MatrixA
	result *= MatrixA;

	// Linear interpolation of the translation components of the matrices
	result.m[3][0] = MatrixA.m[3][0] + ((MatrixB.m[3][0]-MatrixA.m[3][0])*lamda);
	result.m[3][1] = MatrixA.m[3][1] + ((MatrixB.m[3][1]-MatrixA.m[3][1])*lamda);
	result.m[3][2] = MatrixA.m[3][2] + ((MatrixB.m[3][2]-MatrixA.m[3][2])*lamda);

	return result;
}