Exemplo n.º 1
0
void rtBIHNode::calcBox()
{
	if (hasLeaves())
	{
		UINT leavesCount = getLeavesCount();
		if (leavesCount > 0)
		{
			m_BoundingBox = m_pLeaves[0]->box;

			for (UINT i = 1; i<leavesCount; i++)
			{
				m_BoundingBox.Min = XMVectorMin(m_BoundingBox.Min, m_pLeaves[i]->box.Min);
				m_BoundingBox.Max = XMVectorMax(m_BoundingBox.Max, m_pLeaves[i]->box.Max);
			}
		}
		else
		{
			m_BoundingBox.Min = g_XMZero;
			m_BoundingBox.Max = g_XMZero;
		}
	}
	else
	{
		m_pChild[0].calcBox();
		m_pChild[1].calcBox();

		m_BoundingBox.Min = XMVectorMin(m_pChild[0].m_BoundingBox.Min, m_pChild[1].m_BoundingBox.Min);
		m_BoundingBox.Max = XMVectorMax(m_pChild[0].m_BoundingBox.Max, m_pChild[1].m_BoundingBox.Max);
	}
}
Exemplo n.º 2
0
VOID Bound::Merge( const Bound& Other )
{
    Sphere OtherSphere;
    OtherSphere.Center = Other.GetCenter();
    OtherSphere.Radius = Other.GetMaxRadius();

    if( m_Type == Bound::No_Bound )
    {
        SetSphere( OtherSphere );
        return;
    }

    Sphere ThisSphere;
    if( m_Type != Bound::Sphere_Bound )
    {
        // convert this bound into a sphere
        ThisSphere.Center = GetCenter();
        ThisSphere.Radius = GetMaxRadius();
    }
    else
    {
        ThisSphere = GetSphere();
    }

    XMVECTOR vThisCenter = XMLoadFloat3( &ThisSphere.Center );
    XMVECTOR vOtherCenter = XMLoadFloat3( &OtherSphere.Center );
    XMVECTOR vThisToOther = XMVectorSubtract( vOtherCenter, vThisCenter );
    XMVECTOR vDistance = XMVector3LengthEst( vThisToOther );

    FLOAT fCombinedDiameter = XMVectorGetX( vDistance ) + ThisSphere.Radius + OtherSphere.Radius;
    if( fCombinedDiameter <= ( ThisSphere.Radius * 2 ) )
    {
        SetSphere( ThisSphere );
        return;
    }
    if( fCombinedDiameter <= ( OtherSphere.Radius * 2 ) )
    {
        SetSphere( OtherSphere );
        return;
    }

    XMVECTOR vDirectionNorm = XMVector3Normalize( vThisToOther );

    XMVECTOR vRadius = XMVectorSet( ThisSphere.Radius, OtherSphere.Radius, 0, 0 );
    XMVECTOR vThisRadius = XMVectorSplatX( vRadius );
    XMVECTOR vOtherRadius = XMVectorSplatY( vRadius );
    XMVECTOR vCombinedDiameter = vThisRadius + vDistance + vOtherRadius;
    XMVECTOR vMaxDiameter = XMVectorMax( vCombinedDiameter, vThisRadius * 2 );
    vMaxDiameter = XMVectorMax( vMaxDiameter, vOtherRadius * 2 );
    XMVECTOR vMaxRadius = vMaxDiameter * 0.5f;
    ThisSphere.Radius = XMVectorGetX( vMaxRadius );
    vMaxRadius -= vThisRadius;
    XMVECTOR vCombinedCenter = vThisCenter + vMaxRadius * vDirectionNorm;
    XMStoreFloat3( &ThisSphere.Center, vCombinedCenter );
    SetSphere( ThisSphere );
}
Exemplo n.º 3
0
	//! Returns the bounding box in world space. [NOTE] Does not work [TODO].
	AxisAlignedBox AnimatedObject::GetBoundingBox()
	{
		//AxisAlignedBox aabb = mSkinnedModel->GetBoundingBox();	// [WIP] The precalculated AABB for the model.
		SkinnedMeshList* meshList = mSkinnedModel->GetMeshList();
		XNA::AxisAlignedBox aabb = meshList->operator[](0)->GetPrimitive()->GetBoundingBox();
		XMFLOAT3 min = aabb.Center - aabb.Extents;
		XMFLOAT3 max = aabb.Center + aabb.Extents;
		for(int i = 1; i < meshList->size(); i++)
		{
			AxisAlignedBox meshAABB = (*meshList)[i]->GetPrimitive()->GetBoundingBox();
			XMFLOAT3 meshMin = meshAABB.Center - meshAABB.Extents;
			XMFLOAT3 meshMax = meshAABB.Center + meshAABB.Extents;

			XMStoreFloat3(&min, XMVectorMin(XMLoadFloat3(&meshMin), XMLoadFloat3(&min)));
			XMStoreFloat3(&max, XMVectorMax(XMLoadFloat3(&meshMax), XMLoadFloat3(&max)));
		}

		aabb.Center =  (min + max) * 0.5f;
		aabb.Extents = (max - min) * 0.5f;

		// Break up the world matrix into it's components.
		XMVECTOR scale, rotation, translation;
		XMMatrixDecompose(&scale, &rotation, &translation, GetWorldMatrix());

		// Transform the AABB with the components.
		TransformAxisAlignedBoxCustom(&aabb, &aabb, scale, rotation, translation);

		aabb.Center = GetPosition();	// [NOTE] Not like this in StaticObject.

		return aabb;
	}
Exemplo n.º 4
0
void Entity::LoadVertData(std::vector<Vertex::Basic32>& verts, UINT& k)
{
	XMFLOAT3 vMinf3(+MathHelper::Infinity, +MathHelper::Infinity, +MathHelper::Infinity);
	XMFLOAT3 vMaxf3(-MathHelper::Infinity, -MathHelper::Infinity, -MathHelper::Infinity);

	XMVECTOR vMin = XMLoadFloat3(&vMinf3);
	XMVECTOR vMax = XMLoadFloat3(&vMaxf3);

	for (size_t i = 0; i < mGrid.Vertices.size(); ++i, ++k)
	{
		verts[k].Pos	= mGrid.Vertices[i].Position;
		verts[k].Normal = mGrid.Vertices[i].Normal;
		verts[k].Tex	= mGrid.Vertices[i].TexC;

		//Copy Into The Buttons Messh For Future Collision Check 
		mMeshVertices[i].Pos	= mGrid.Vertices[i].Position;
		mMeshVertices[i].Normal = mGrid.Vertices[i].Normal;

		XMVECTOR P = XMLoadFloat3(&mMeshVertices[i].Pos);

		vMin = XMVectorMin(vMin, P);
		vMax = XMVectorMax(vMax, P);
	}
	XMStoreFloat3(&mMeshBox.Center, 0.5f*(vMin + vMax));
	XMStoreFloat3(&mMeshBox.Extents, 0.5f*(vMax - vMin));

}
Exemplo n.º 5
0
bool D3D11RendererMesh::BuildBuffers(const GeoGen::MeshData& mesh)
{
	D3D11_BUFFER_DESC desc = { 0 };
	desc.ByteWidth = sizeof(VertexPositionNormalTexture) * mesh.vertices.size();
	desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	desc.Usage = D3D11_USAGE_DEFAULT;
	m_nVBSize = mesh.vertices.size();
	m_nIBSize = mesh.indices.size();

	vertices.resize(mesh.vertices.size());
	float Infinity = FLT_MAX;
	XMFLOAT3 vMinf3(+Infinity, +Infinity, +Infinity);
	XMFLOAT3 vMaxf3(-Infinity, -Infinity, -Infinity);
	vMin = XMLoadFloat3(&vMinf3);
	vMax = XMLoadFloat3(&vMaxf3);

	for (UINT i = 0; i < mesh.vertices.size(); ++i)
	{
		vertices[i].position = mesh.vertices[i].pos;
		vertices[i].normal = mesh.vertices[i].normal;
		vertices[i].textureCoordinate = mesh.vertices[i].tex;
		XMVECTOR P = XMLoadFloat3(&vertices[i].position);
		vMin = XMVectorMin(vMin, P);
		vMax = XMVectorMax(vMax, P);
	}
	D3D11_SUBRESOURCE_DATA vData;
	vData.pSysMem = &vertices[0];
	vData.SysMemPitch = 0;
	vData.SysMemSlicePitch = 0;
	if (FAILED(m_d3dDevice->CreateBuffer(&desc, &vData, &m_VB)))
	{
		MessageBox(NULL, L"Create Vertex Buffer failed!", L"Error", MB_OK);
		return false;
	}

	D3D11_BUFFER_DESC iDesc = { 0 };
	iDesc.ByteWidth = sizeof(UINT) * mesh.indices.size();
	iDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
	iDesc.Usage = D3D11_USAGE_DEFAULT;
	indices.resize(mesh.indices.size());
	for (UINT i = 0; i < mesh.indices.size(); ++i)
	{
		indices[i] = mesh.indices[i];
	}
	D3D11_SUBRESOURCE_DATA iData;
	iData.pSysMem = &indices[0];
	iData.SysMemPitch = 0;
	iData.SysMemSlicePitch = 0;
	if (FAILED(m_d3dDevice->CreateBuffer(&iDesc, &iData, &m_IB)))
	{
		MessageBox(NULL, L"Create Index Buffer failed!", L"Error", MB_OK);
		return false;
	}




	return true;
}
Exemplo n.º 6
0
/**
 *	Component wise set to maximum of this and other.
 */
CFVec4&		CFVec4::MaximizeWith( CFVec4Arg fv4Other )
{
	XMVECTOR& v4V = *reinterpret_cast<XMVECTOR*>( this );
	const XMVECTOR& v4V2 = *reinterpret_cast<const XMVECTOR*>( &fv4Other );

	v4V = XMVectorMax( v4V, v4V2 );
	
	return *this;
}
Exemplo n.º 7
0
CFVec4		CFVec4::GetMax( CFVec4Arg fv4Other ) const
{
	CFVec4 v4Return;

	const XMVECTOR& v4V = *reinterpret_cast<const XMVECTOR*>( this );
	const XMVECTOR& v4V2 = *reinterpret_cast<const XMVECTOR*>( &fv4Other );
	XMVECTOR& v4Result = *reinterpret_cast<XMVECTOR*>( &v4Return );

	v4Result = XMVectorMax( v4V, v4V2 );

	return v4Return;
}
Exemplo n.º 8
0
void Entity::UpdateAAB()
{
	XMFLOAT3 vMinf3(+MathHelper::Infinity, +MathHelper::Infinity, +MathHelper::Infinity);
	XMFLOAT3 vMaxf3(-MathHelper::Infinity, -MathHelper::Infinity, -MathHelper::Infinity);
	XMVECTOR vMin = XMLoadFloat3(&vMinf3);
	XMVECTOR vMax = XMLoadFloat3(&vMaxf3);

	for (size_t i = 0; i < mGrid.Vertices.size(); ++i)
	{
		XMVECTOR P = XMLoadFloat3(&mMeshVertices[i].Pos);
		P = XMVector3TransformCoord(P, XMLoadFloat4x4(&mWorld));
		vMin = XMVectorMin(vMin, P);
		vMax = XMVectorMax(vMax, P);
	}
	XMStoreFloat3(&mMeshBox.Center, 0.5f*(vMin + vMax));
	XMStoreFloat3(&mMeshBox.Extents, 0.5f*(vMax - vMin));
}
Exemplo n.º 9
0
//-----------------------------------------------------------------------------
// Transform an axis aligned box by an angle preserving transform.
//-----------------------------------------------------------------------------
VOID TransformAxisAlignedBoxCustom(XNA::AxisAlignedBox* pOut, const XNA::AxisAlignedBox* pIn, FXMVECTOR Scale, FXMVECTOR Rotation, FXMVECTOR Translation )
{
    XMASSERT( pOut );
    XMASSERT( pIn );

    static XMVECTOR Offset[8] =
    {
        { -1.0f, -1.0f, -1.0f, 0.0f },
        { -1.0f, -1.0f,  1.0f, 0.0f },
        { -1.0f,  1.0f, -1.0f, 0.0f },
        { -1.0f,  1.0f,  1.0f, 0.0f },
        {  1.0f, -1.0f, -1.0f, 0.0f },
        {  1.0f, -1.0f,  1.0f, 0.0f },
        {  1.0f,  1.0f, -1.0f, 0.0f },
        {  1.0f,  1.0f,  1.0f, 0.0f }
    };

    // Load center and extents.
    XMVECTOR Center = XMLoadFloat3( &pIn->Center );
    XMVECTOR Extents = XMLoadFloat3( &pIn->Extents );

    XMVECTOR VectorScale = Scale;//XMVectorReplicate( Scale );

    // Compute and transform the corners and find new min/max bounds.
    XMVECTOR Corner = Center + Extents * Offset[0];
    Corner = XMVector3Rotate( Corner * VectorScale, Rotation ) + Translation;

    XMVECTOR Min, Max;
    Min = Max = Corner;

    for( INT i = 1; i < 8; i++ )
    {
        Corner = Center + Extents * Offset[i];
        Corner = XMVector3Rotate( Corner * VectorScale, Rotation ) + Translation;

        Min = XMVectorMin( Min, Corner );
        Max = XMVectorMax( Max, Corner );
    }

    // Store center and extents.
    XMStoreFloat3( &pOut->Center, ( Min + Max ) * 0.5f );
    XMStoreFloat3( &pOut->Extents, ( Max - Min ) * 0.5f );

    return;
}
Exemplo n.º 10
0
XMVECTOR LimitAngle(const XMVECTOR& quat, const XMVECTOR& rotmin, const XMVECTOR& rotmax)
{
	XMVECTOR rot_xyz = GetAngle(quat);
	/*	XMMATRIX mtx = XMMatrixRotationQuaternion(quat);

	//ZYX Y=-90〜90°Y軸=ねじり方向
	float rx = -atan2f(XMVectorGetY(mtx.r[2]),XMVectorGetZ(mtx.r[2]));
	float ry = asinf(XMVectorGetX(mtx.r[2]));
	float rz = -atan2f(XMVectorGetX(mtx.r[1]),XMVectorGetX(mtx.r[0]));
	XMVECTOR rot_xyz = {rx,ry,rz,0};
	*rotang_before = rot_xyz;
	*/
	rot_xyz = XMVectorMax(rot_xyz, rotmin);
	rot_xyz = XMVectorMin(rot_xyz, rotmax);
	XMMATRIX mtx = XMMatrixRotationZ(XMVectorGetZ(rot_xyz));
	mtx = XMMatrixMultiply(mtx, XMMatrixRotationY(XMVectorGetY(rot_xyz)));
	mtx = XMMatrixMultiply(mtx, XMMatrixRotationX(XMVectorGetX(rot_xyz)));

	return XMQuaternionRotationMatrix(mtx);
}
Exemplo n.º 11
0
void SkinnedModel::CalculateAABB()
{
	XMFLOAT3 min = XMFLOAT3(numeric_limits<float>::infinity(), numeric_limits<float>::infinity(), numeric_limits<float>::infinity());
	XMFLOAT3 max = XMFLOAT3(-numeric_limits<float>::infinity(), -numeric_limits<float>::infinity(), -numeric_limits<float>::infinity());

	for(int i = 0; i < 1; i++)
	{
		vector<XMFLOAT4X4> transforms = mAnimator->GetTransforms(1.0f);
		for(int j = 0; j < mMeshList.size(); j++) 
		{
			XNA::AxisAlignedBox aabb = mMeshList[j]->CalculateAABB(transforms);
			XMFLOAT3 meshMin = aabb.Center - aabb.Extents;
			XMFLOAT3 meshMax = aabb.Center + aabb.Extents;

			XMStoreFloat3(&min, XMVectorMin(XMLoadFloat3(&meshMin), XMLoadFloat3(&min)));
			XMStoreFloat3(&max, XMVectorMax(XMLoadFloat3(&meshMax), XMLoadFloat3(&max)));
		}
	}

	mAABB.Center = (min + max) * 0.5f;
	mAABB.Extents = (max - min) * 0.5f;
}
Exemplo n.º 12
0
	Vector3 Vector3::maximise(const Vector3& a, const Vector3& b)
	{
		return Vector3(XMVectorMax(a, b));
	}
void InstancingAndCullingApp::BuildSkullGeometryBuffers()
{
	std::ifstream fin("Models/skull.txt");
	
	if(!fin)
	{
		MessageBox(0, L"Models/skull.txt not found.", 0, 0);
		return;
	}

	UINT vcount = 0;
	UINT tcount = 0;
	std::string ignore;

	fin >> ignore >> vcount;
	fin >> ignore >> tcount;
	fin >> ignore >> ignore >> ignore >> ignore;
	
	XMFLOAT3 vMinf3(+MathHelper::Infinity, +MathHelper::Infinity, +MathHelper::Infinity);
	XMFLOAT3 vMaxf3(-MathHelper::Infinity, -MathHelper::Infinity, -MathHelper::Infinity);
	
	XMVECTOR vMin = XMLoadFloat3(&vMinf3);
	XMVECTOR vMax = XMLoadFloat3(&vMaxf3);
	std::vector<Vertex::Basic32> vertices(vcount);
	for(UINT i = 0; i < vcount; ++i)
	{
		fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;
		fin >> vertices[i].Normal.x >> vertices[i].Normal.y >> vertices[i].Normal.z;
		
		XMVECTOR P = XMLoadFloat3(&vertices[i].Pos);
		
		vMin = XMVectorMin(vMin, P);
		vMax = XMVectorMax(vMax, P);
	}
	
	XMStoreFloat3(&mSkullBox.Center, 0.5f*(vMin+vMax));
	XMStoreFloat3(&mSkullBox.Extents, 0.5f*(vMax-vMin));

	fin >> ignore;
	fin >> ignore;
	fin >> ignore;

	mSkullIndexCount = 3*tcount;
	std::vector<UINT> indices(mSkullIndexCount);
	for(UINT i = 0; i < tcount; ++i)
	{
		fin >> indices[i*3+0] >> indices[i*3+1] >> indices[i*3+2];
	}

	fin.close();

    D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::Basic32) * vcount;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = &vertices[0];
    HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mSkullVB));

	//
	// Pack the indices of all the meshes into one index buffer.
	//

	D3D11_BUFFER_DESC ibd;
    ibd.Usage = D3D11_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof(UINT) * mSkullIndexCount;
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA iinitData;
	iinitData.pSysMem = &indices[0];
    HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mSkullIB));
}
Exemplo n.º 14
0
void rtBIHNode::buildSubNodes(rtNodeBuildDesc* pDesc, UINT* pCounter)
{
	size_t dataSize = sizeof(rtBIHLeaf*) * pDesc->leavesCount;

	if (pDesc->leavesCount < 3)
	{
		m_pLeaves = (rtBIHLeaf**)pDesc->pLeavesMemPool->alloc(dataSize);
		memcpy_4(m_pLeaves, pDesc->pSrcLeaves, dataSize);

		m_Flags = BIH_LEAF | (pDesc->leavesCount << 2);
		return;
	}

	LARGE_INTEGER start, stop;

	
	
	// sort leaves
	for (UINT i = 0; i<3; i++)
	{
		if (i != pDesc->sortedBy)
		{
			memcpy_4(pDesc->pSortedLeaves[i], pDesc->pSrcLeaves, dataSize);

			if (pDesc->leavesCount > INSERT_SORT_TRESHOLD+1)
				quickSortObjectsByAxis(pDesc->pSortedLeaves[i], 0, pDesc->leavesCount-1, i);
			else
				insertSortObjectsByAxis(pDesc->pSortedLeaves[i], 0, pDesc->leavesCount-1, i);
		}
	}

	if (pDesc->sortedBy < 3)
		memcpy_4(pDesc->pSortedLeaves[pDesc->sortedBy], pDesc->pSrcLeaves, dataSize);


	XMVECTOR leftCost, rightCost, totalCost;
	XMVECTOR bestCost = XMVectorReplicate(1.0e+30f);

	UINT bestAxis = 3;
	UINT bestSplitPos = 0;

	int i;

	QueryPerformanceCounter(&start);
	for (UINT axis = 0; axis<3; axis++)
	{
		//calculate possible left node aabbs
		pDesc->LeftAABBs[0] = pDesc->pSortedLeaves[axis][0]->box;
		XMVECTOR prevMin = pDesc->LeftAABBs[0].Min;
		XMVECTOR prevMax = pDesc->LeftAABBs[0].Max;
		for (i = 1; i<pDesc->leavesCount; i++)
		{
			prevMin = XMVectorMin(prevMin, pDesc->pSortedLeaves[axis][i]->box.Min);
			prevMax = XMVectorMax(prevMax, pDesc->pSortedLeaves[axis][i]->box.Max);
			pDesc->LeftAABBs[i].Min = prevMin;
			pDesc->LeftAABBs[i].Max = prevMax;
		}


		//calculate possible right node aabbs
		pDesc->RightAABBs[pDesc->leavesCount-1] = pDesc->pSortedLeaves[axis][pDesc->leavesCount-1]->box;
		prevMin = pDesc->RightAABBs[pDesc->leavesCount-1].Min;
		prevMax = pDesc->RightAABBs[pDesc->leavesCount-1].Max;
		for (i = pDesc->leavesCount-2; i>=0; i--)
		{
			prevMin = XMVectorMin(prevMin, pDesc->pSortedLeaves[axis][i]->box.Min);
			prevMax = XMVectorMax(prevMax, pDesc->pSortedLeaves[axis][i]->box.Max);
			pDesc->RightAABBs[i].Min = prevMin;
			pDesc->RightAABBs[i].Max = prevMax;
		}

		UINT splitpos;
		UINT max_splitpos = pDesc->leavesCount-1;
		XMVECTOR leftCount, rightcount;

		switch (pDesc->heuristics)
		{
			case SURFACE_AREA:
				for (splitpos = 2; splitpos<max_splitpos; splitpos++)
				{
					leftCost = pDesc->LeftAABBs[splitpos].getSurfaceArea();
					rightCost = pDesc->RightAABBs[splitpos+1].getSurfaceArea();
					leftCount = XMConvertVectorUIntToFloat(XMVectorReplicateInt(splitpos + 1), 0);
					rightcount = XMConvertVectorUIntToFloat(XMVectorReplicateInt(max_splitpos - splitpos), 0);
					totalCost = leftCost*leftCount + rightCost*rightcount;

					if (XMVector3Greater(bestCost, totalCost))
					{
						bestAxis = axis;
						bestSplitPos = splitpos;
						bestCost = totalCost;
					}
				}
				break;

	
			case VOLUME:
				for (splitpos = 2; splitpos<max_splitpos; splitpos++)
				{
					leftCost = pDesc->LeftAABBs[splitpos].getVolume();
					rightCost = pDesc->RightAABBs[splitpos+1].getVolume();
					leftCount = XMVectorReplicate((float)(splitpos + 1));
					rightcount = XMVectorReplicate((float)(max_splitpos - splitpos));
					totalCost = leftCost*leftCount + rightCost*rightcount;

					if (XMVector3Greater(bestCost, totalCost))
					{
						bestAxis = axis;
						bestSplitPos = splitpos;
						bestCost = totalCost;
					}
				}
				break;
		}
	}
	QueryPerformanceCounter(&stop);
	g_sortingTime.QuadPart += stop.QuadPart - start.QuadPart;



	if (bestAxis >= 3)
	{
		bestSplitPos = 1;
		bestAxis = 0;
		/*
		m_pLeaves = (rtBIHLeaf**)pDesc->pLeavesMemPool->alloc(dataSize);
		memcpy_4(m_pLeaves, pDesc->pSrcLeaves, dataSize);

		m_Flags = BIH_LEAF | (pDesc->leavesCount << 2);
		return;
		*/
	}


	//
	m_pChild = (rtBIHNode*)pDesc->pNodesMemPool->alloc(sizeof(rtBIHNode)*2);
	UINT childLeavesCount;

	rtNodeBuildDesc desc;
	desc.heuristics = pDesc->heuristics;
	desc.pLeavesMemPool = pDesc->pLeavesMemPool;
	desc.pNodesMemPool = pDesc->pNodesMemPool;
	desc.LeftAABBs = pDesc->LeftAABBs;
	desc.RightAABBs = pDesc->RightAABBs;
	desc.pSortedLeaves[0] = pDesc->pSortedLeaves[0];
	desc.pSortedLeaves[1] = pDesc->pSortedLeaves[1];
	desc.pSortedLeaves[2] = pDesc->pSortedLeaves[2];
	desc.sortedBy = bestAxis;

	//construct left node
	m_pChild[0] = rtBIHNode();
	m_pChild[0].m_ID = *pCounter;
	m_pChild[0].m_pParent = this;
	desc.leavesCount = bestSplitPos+1;
	desc.pSrcLeaves = pDesc->pSortedLeaves[bestAxis];
	(*pCounter)++;
	m_pChild[0].buildSubNodes(&desc, pCounter);

	//construct right node
	m_pChild[1] = rtBIHNode();
	m_pChild[1].m_ID = *pCounter;
	m_pChild[1].m_pParent = this;
	desc.leavesCount = pDesc->leavesCount - (bestSplitPos+1);
	desc.pSrcLeaves = &(pDesc->pSortedLeaves[bestAxis][bestSplitPos+1]);
	(*pCounter)++;
	m_pChild[1].buildSubNodes(&desc, pCounter);

	m_Flags = bestAxis;
}
Exemplo n.º 15
0
// Renders meshes using cascaded shadow mapping
void MeshRenderer::RenderSunShadowMap(ID3D11DeviceContext* context, const Camera& camera)
{
    PIXEvent event(L"Sun Shadow Map Rendering");

    const float MinDistance = reductionDepth.x;
    const float MaxDistance = reductionDepth.y;

    // Compute the split distances based on the partitioning mode
    float CascadeSplits[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

    {
        float lambda = 1.0f;

        float nearClip = camera.NearClip();
        float farClip = camera.FarClip();
        float clipRange = farClip - nearClip;

        float minZ = nearClip + MinDistance * clipRange;
        float maxZ = nearClip + MaxDistance * clipRange;

        float range = maxZ - minZ;
        float ratio = maxZ / minZ;

        for(uint32 i = 0; i < NumCascades; ++i)
        {
            float p = (i + 1) / static_cast<float>(NumCascades);
            float log = minZ * std::pow(ratio, p);
            float uniform = minZ + range * p;
            float d = lambda * (log - uniform) + uniform;
            CascadeSplits[i] = (d - nearClip) / clipRange;
        }
    }

    Float3 c0Extents;
    Float4x4 c0Matrix;

    const Float3 lightDir = AppSettings::SunDirection;

    // Render the meshes to each cascade
    for(uint32 cascadeIdx = 0; cascadeIdx < NumCascades; ++cascadeIdx)
    {
        PIXEvent cascadeEvent((L"Rendering Shadow Map Cascade " + ToString(cascadeIdx)).c_str());

        // Set the viewport
        SetViewport(context, ShadowMapSize, ShadowMapSize);

        // Set the shadow map as the depth target
        ID3D11DepthStencilView* dsv = sunShadowDepthMap.DSView;
        ID3D11RenderTargetView* nullRenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { NULL };
        context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRenderTargets, dsv);
        context->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);

        // Get the 8 points of the view frustum in world space
        XMVECTOR frustumCornersWS[8] =
        {
            XMVectorSet(-1.0f,  1.0f, 0.0f, 1.0f),
            XMVectorSet( 1.0f,  1.0f, 0.0f, 1.0f),
            XMVectorSet( 1.0f, -1.0f, 0.0f, 1.0f),
            XMVectorSet(-1.0f, -1.0f, 0.0f, 1.0f),
            XMVectorSet(-1.0f,  1.0f, 1.0f, 1.0f),
            XMVectorSet( 1.0f,  1.0f, 1.0f, 1.0f),
            XMVectorSet( 1.0f, -1.0f, 1.0f, 1.0f),
            XMVectorSet(-1.0f, -1.0f, 1.0f, 1.0f),
        };

        float prevSplitDist = cascadeIdx == 0 ? MinDistance : CascadeSplits[cascadeIdx - 1];
        float splitDist = CascadeSplits[cascadeIdx];

        XMVECTOR det;
        XMMATRIX invViewProj = XMMatrixInverse(&det, camera.ViewProjectionMatrix().ToSIMD());
        for(uint32 i = 0; i < 8; ++i)
            frustumCornersWS[i] = XMVector3TransformCoord(frustumCornersWS[i], invViewProj);

        // Get the corners of the current cascade slice of the view frustum
        for(uint32 i = 0; i < 4; ++i)
        {
            XMVECTOR cornerRay = XMVectorSubtract(frustumCornersWS[i + 4], frustumCornersWS[i]);
            XMVECTOR nearCornerRay = XMVectorScale(cornerRay, prevSplitDist);
            XMVECTOR farCornerRay = XMVectorScale(cornerRay, splitDist);
            frustumCornersWS[i + 4] = XMVectorAdd(frustumCornersWS[i], farCornerRay);
            frustumCornersWS[i] = XMVectorAdd(frustumCornersWS[i], nearCornerRay);
        }

        // Calculate the centroid of the view frustum slice
        XMVECTOR frustumCenterVec = XMVectorZero();
        for(uint32 i = 0; i < 8; ++i)
            frustumCenterVec = XMVectorAdd(frustumCenterVec, frustumCornersWS[i]);
        frustumCenterVec = XMVectorScale(frustumCenterVec, 1.0f / 8.0f);
        Float3 frustumCenter = frustumCenterVec;

        // Pick the up vector to use for the light camera
        Float3 upDir = camera.Right();

        Float3 minExtents;
        Float3 maxExtents;

        {
            // Create a temporary view matrix for the light
            Float3 lightCameraPos = frustumCenter;
            Float3 lookAt = frustumCenter - lightDir;
            XMMATRIX lightView = XMMatrixLookAtLH(lightCameraPos.ToSIMD(), lookAt.ToSIMD(), upDir.ToSIMD());

            // Calculate an AABB around the frustum corners
            XMVECTOR mins = XMVectorSet(REAL_MAX, REAL_MAX, REAL_MAX, REAL_MAX);
            XMVECTOR maxes = XMVectorSet(-REAL_MAX, -REAL_MAX, -REAL_MAX, -REAL_MAX);
            for(uint32 i = 0; i < 8; ++i)
            {
                XMVECTOR corner = XMVector3TransformCoord(frustumCornersWS[i], lightView);
                mins = XMVectorMin(mins, corner);
                maxes = XMVectorMax(maxes, corner);
            }

            minExtents = mins;
            maxExtents = maxes;
        }

        // Adjust the min/max to accommodate the filtering size
        float scale = (ShadowMapSize + FilterSize) / static_cast<float>(ShadowMapSize);
        minExtents.x *= scale;
        minExtents.y *= scale;
        maxExtents.x *= scale;
        maxExtents.x *= scale;

        Float3 cascadeExtents = maxExtents - minExtents;

        // Get position of the shadow camera
        Float3 shadowCameraPos = frustumCenter + lightDir * -minExtents.z;

        // Come up with a new orthographic camera for the shadow caster
        OrthographicCamera shadowCamera(minExtents.x, minExtents.y, maxExtents.x,
            maxExtents.y, 0.0f, cascadeExtents.z);
        shadowCamera.SetLookAt(shadowCameraPos, frustumCenter, upDir);

        // Draw the mesh with depth only, using the new shadow camera
        RenderDepth(context, shadowCamera, true, false);

        // Apply the scale/offset matrix, which transforms from [-1,1]
        // post-projection space to [0,1] UV space
        XMMATRIX texScaleBias;
        texScaleBias.r[0] = XMVectorSet(0.5f,  0.0f, 0.0f, 0.0f);
        texScaleBias.r[1] = XMVectorSet(0.0f, -0.5f, 0.0f, 0.0f);
        texScaleBias.r[2] = XMVectorSet(0.0f,  0.0f, 1.0f, 0.0f);
        texScaleBias.r[3] = XMVectorSet(0.5f,  0.5f, 0.0f, 1.0f);
        XMMATRIX shadowMatrix = shadowCamera.ViewProjectionMatrix().ToSIMD();
        shadowMatrix = XMMatrixMultiply(shadowMatrix, texScaleBias);

        // Store the split distance in terms of view space depth
        const float clipDist = camera.FarClip() - camera.NearClip();
        shadowConstants.Data.CascadeSplits[cascadeIdx] = camera.NearClip() + splitDist * clipDist;

        if(cascadeIdx == 0)
        {
            c0Extents = cascadeExtents;
            c0Matrix = shadowMatrix;
            shadowConstants.Data.ShadowMatrix = XMMatrixTranspose(shadowMatrix);
            shadowConstants.Data.CascadeOffsets[0] = Float4(0.0f, 0.0f, 0.0f, 0.0f);
            shadowConstants.Data.CascadeScales[0] = Float4(1.0f, 1.0f, 1.0f, 1.0f);
        }
        else
        {
            // Calculate the position of the lower corner of the cascade partition, in the UV space
            // of the first cascade partition
            Float4x4 invCascadeMat = Float4x4::Invert(shadowMatrix);
            Float3 cascadeCorner = Float3::Transform(Float3(0.0f, 0.0f, 0.0f), invCascadeMat);
            cascadeCorner = Float3::Transform(cascadeCorner, c0Matrix);

            // Do the same for the upper corner
            Float3 otherCorner = Float3::Transform(Float3(1.0f, 1.0f, 1.0f), invCascadeMat);
            otherCorner = Float3::Transform(otherCorner, c0Matrix);

            // Calculate the scale and offset
            Float3 cascadeScale = Float3(1.0f, 1.0f, 1.f) / (otherCorner - cascadeCorner);
            shadowConstants.Data.CascadeOffsets[cascadeIdx] = Float4(-cascadeCorner, 0.0f);
            shadowConstants.Data.CascadeScales[cascadeIdx] = Float4(cascadeScale, 1.0f);
        }

        ConvertToEVSM(context, cascadeIdx, shadowConstants.Data.CascadeScales[cascadeIdx].To3D());
    }
}
Exemplo n.º 16
0
//-----------------------------------------------------------------------------
// Compute the intersection of a ray (Origin, Direction) with an axis aligned 
// box using the slabs method.
//-----------------------------------------------------------------------------
BOOL GLibIntersectRayAxisAlignedBox( FXMVECTOR Origin, FXMVECTOR Direction, const XNA::AxisAlignedBox* pVolume, FLOAT* pDist )
{
	XMASSERT( pVolume );
	XMASSERT( pDist );
	//XMASSERT( XMVector3IsUnit( Direction ) );

	static const XMVECTOR Epsilon =
	{
		1e-20f, 1e-20f, 1e-20f, 1e-20f
	};
	static const XMVECTOR FltMin =
	{
		-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX
	};
	static const XMVECTOR FltMax =
	{
		FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX
	};

	// Load the box.
	XMVECTOR Center = XMLoadFloat3( &pVolume->Center );
	XMVECTOR Extents = XMLoadFloat3( &pVolume->Extents );

	// Adjust ray origin to be relative to center of the box.
	XMVECTOR TOrigin = Center - Origin;

	// Compute the dot product againt each axis of the box.
	// Since the axii are (1,0,0), (0,1,0), (0,0,1) no computation is necessary.
	XMVECTOR AxisDotOrigin = TOrigin;
	XMVECTOR AxisDotDirection = Direction;

	// if (fabs(AxisDotDirection) <= Epsilon) the ray is nearly parallel to the slab.
	XMVECTOR IsParallel = XMVectorLessOrEqual( XMVectorAbs( AxisDotDirection ), Epsilon );

	// Test against all three axii simultaneously.
	XMVECTOR InverseAxisDotDirection = XMVectorReciprocal( AxisDotDirection );
	XMVECTOR t1 = ( AxisDotOrigin - Extents ) * InverseAxisDotDirection;
	XMVECTOR t2 = ( AxisDotOrigin + Extents ) * InverseAxisDotDirection;

	// Compute the max of min(t1,t2) and the min of max(t1,t2) ensuring we don't
	// use the results from any directions parallel to the slab.
	XMVECTOR t_min = XMVectorSelect( XMVectorMin( t1, t2 ), FltMin, IsParallel );
	XMVECTOR t_max = XMVectorSelect( XMVectorMax( t1, t2 ), FltMax, IsParallel );

	// t_min.x = maximum( t_min.x, t_min.y, t_min.z );
	// t_max.x = minimum( t_max.x, t_max.y, t_max.z );
	t_min = XMVectorMax( t_min, XMVectorSplatY( t_min ) );  // x = max(x,y)
	t_min = XMVectorMax( t_min, XMVectorSplatZ( t_min ) );  // x = max(max(x,y),z)
	t_max = XMVectorMin( t_max, XMVectorSplatY( t_max ) );  // x = min(x,y)
	t_max = XMVectorMin( t_max, XMVectorSplatZ( t_max ) );  // x = min(min(x,y),z)

	// if ( t_min > t_max ) return FALSE;
	XMVECTOR NoIntersection = XMVectorGreater( XMVectorSplatX( t_min ), XMVectorSplatX( t_max ) );

	// if ( t_max < 0.0f ) return FALSE;
	NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( XMVectorSplatX( t_max ), XMVectorZero() ) );

	// if (IsParallel && (-Extents > AxisDotOrigin || Extents < AxisDotOrigin)) return FALSE;
	XMVECTOR ParallelOverlap = XMVectorInBounds( AxisDotOrigin, Extents );
	NoIntersection = XMVectorOrInt( NoIntersection, XMVectorAndCInt( IsParallel, ParallelOverlap ) );

	if(!GLibXMVector3AnyTrue( NoIntersection ) )
	{
		// Store the x-component to *pDist
		XMStoreFloat( pDist, t_min );
		return TRUE;
	}

	return FALSE;
}