示例#1
0
XMVECTOR MathHelper::RandHemisphereUnitVec3(XMVECTOR n)
{
	XMVECTOR One  = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
	XMVECTOR Zero = XMVectorZero();

	// Keep trying until we get a point on/in the hemisphere.
	while(true)
	{
		// Generate random point in the cube [-1,1]^3.
		XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);

		// Ignore points outside the unit sphere in order to get an even distribution 
		// over the unit sphere.  Otherwise points will clump more on the sphere near 
		// the corners of the cube.

		if( XMVector3Greater( XMVector3LengthSq(v), One) )
			continue;

		// Ignore points in the bottom hemisphere.
		if( XMVector3Less( XMVector3Dot(n, v), Zero ) )
			continue;

		return XMVector3Normalize(v);
	}
}
示例#2
0
XMVECTOR MathHelper::RandUnitVec3()
{
	XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
	XMVECTOR Zero = XMVectorZero();

	while (true)
	{
		// Generate random point in the cube [-1,1]^3.
		XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);

		// Ignore points outside the unit sphere in order to get an even distribution 
		// over the unit sphere.  Otherwise points will clump more on the sphere near 
		// the corners of the cube.

		if (XMVector3Greater(XMVector3LengthSq(v), One))//知道代码意思,但是代码实际执行看不懂。知其然不知其所以然
			continue;

		return XMVector3Normalize(v);
	}
}
示例#3
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;
}
示例#4
0
BSphere ComputeBoundingSphereFromPoints(const XMFLOAT3* points, uint32 numPoints, uint32 stride, BBox *optionalBBoxOut)
{
	BSphere sphere;

	Assert_(numPoints > 0);
	Assert_(points);

	// Find the points with minimum and maximum x, y, and z
	XMVECTOR MinX, MaxX, MinY, MaxY, MinZ, MaxZ;

	MinX = MaxX = MinY = MaxY = MinZ = MaxZ = XMLoadFloat3(points);
	GetBoundCornersFromPoints(points, numPoints, stride, MinX, MaxX, MinY, MaxY, MinZ, MaxZ);

	/*for (uint32 i = 1; i < numPoints; i++)
	{
		XMVECTOR Point = XMLoadFloat3((XMFLOAT3*)((BYTE*)points + i * stride));

		float px = XMVectorGetX(Point);
		float py = XMVectorGetY(Point);
		float pz = XMVectorGetZ(Point);

		if (px < XMVectorGetX(MinX))
			MinX = Point;

		if (px > XMVectorGetX(MaxX))
			MaxX = Point;

		if (py < XMVectorGetY(MinY))
			MinY = Point;

		if (py > XMVectorGetY(MaxY))
			MaxY = Point;

		if (pz < XMVectorGetZ(MinZ))
			MinZ = Point;

		if (pz > XMVectorGetZ(MaxZ))
			MaxZ = Point;
	}*/

	if (optionalBBoxOut != NULL)
	{
		float maxx = XMVectorGetX(MaxX);
		float maxy = XMVectorGetY(MaxY);
		float maxz = XMVectorGetZ(MaxZ);

		float minx = XMVectorGetX(MinX);
		float miny = XMVectorGetY(MinY);
		float minz = XMVectorGetZ(MinZ);

		optionalBBoxOut->Max.x = maxx;
		optionalBBoxOut->Max.y = maxy;
		optionalBBoxOut->Max.z = maxz;

		optionalBBoxOut->Min.x = minx;
		optionalBBoxOut->Min.y = miny;
		optionalBBoxOut->Min.z = minz;
	}

	// Use the min/max pair that are farthest apart to form the initial sphere.
	XMVECTOR DeltaX = MaxX - MinX;
	XMVECTOR DistX = XMVector3Length(DeltaX);

	XMVECTOR DeltaY = MaxY - MinY;
	XMVECTOR DistY = XMVector3Length(DeltaY);

	XMVECTOR DeltaZ = MaxZ - MinZ;
	XMVECTOR DistZ = XMVector3Length(DeltaZ);

	XMVECTOR Center;
	XMVECTOR Radius;

	if (XMVector3Greater(DistX, DistY))
	{
		if (XMVector3Greater(DistX, DistZ))
		{
			// Use min/max x.
			Center = (MaxX + MinX) * 0.5f;
			Radius = DistX * 0.5f;
		}
		else
		{
			// Use min/max z.
			Center = (MaxZ + MinZ) * 0.5f;
			Radius = DistZ * 0.5f;
		}
	}
	else // Y >= X
	{
		if (XMVector3Greater(DistY, DistZ))
		{
			// Use min/max y.
			Center = (MaxY + MinY) * 0.5f;
			Radius = DistY * 0.5f;
		}
		else
		{
			// Use min/max z.
			Center = (MaxZ + MinZ) * 0.5f;
			Radius = DistZ * 0.5f;
		}
	}

	// Add any points not inside the sphere.
	for (uint32 i = 0; i < numPoints; i++)
	{
		XMVECTOR Point = XMLoadFloat3((XMFLOAT3*)((BYTE*)points + i * stride));

		XMVECTOR Delta = Point - Center;

		XMVECTOR Dist = XMVector3Length(Delta);

		if (XMVector3Greater(Dist, Radius))
		{
			// Adjust sphere to include the new point.
			Radius = (Radius + Dist) * 0.5f;
			Center += (XMVectorReplicate(1.0f) - Radius * XMVectorReciprocal(Dist)) * Delta;
		}
	}

	XMStoreFloat3(&sphere.Center, Center);
	XMStoreFloat(&sphere.Radius, Radius);

	return sphere;
}