//----------------------------------------------------------------------------
// Determine if the occluddee size is too small and if so avoid drawing it
//----------------------------------------------------------------------------
bool TransformedAABBoxSSE::IsTooSmall(__m128 *pViewMatrix, __m128 *pProjMatrix, ShadowMapCamera *pCamera)
{
	float radius = mBBHalf.lengthSq(); // Use length-squared to avoid sqrt().  Relative comparissons hold.
	float fov = pCamera->GetFov();
	float tanOfHalfFov = tanf(fov * 0.5f);
	mTooSmall = false;

	MatrixMultiply(mWorldMatrix, pViewMatrix, mCumulativeMatrix);
	MatrixMultiply(mCumulativeMatrix, pProjMatrix, mCumulativeMatrix);
	MatrixMultiply(mCumulativeMatrix, mViewPortMatrix, mCumulativeMatrix);

	__m128 center = _mm_set_ps(1.0f, mBBCenter.z, mBBCenter.y, mBBCenter.x);
	__m128 mBBCenterOSxForm = TransformCoords(&center, mCumulativeMatrix);
    float w = mBBCenterOSxForm.m128_f32[3];
	if( w > 1.0f )
	{
		float radiusDivW = radius / w;
		float r2DivW2DivTanFov = radiusDivW / tanOfHalfFov;

		mTooSmall = r2DivW2DivTanFov < (mOccludeeSizeThreshold * mOccludeeSizeThreshold) ?  true : false;
	}
	else
	{
		mTooSmall = false;
	}
	return mTooSmall;
}
Exemple #2
0
bool CSPrimMultiBox::IsInside(const double* Coord, double /*tol*/)
{
	if (Coord==NULL) return false;
	bool in=false;
	double UpVal,DownVal;
	double coords[3]={Coord[0],Coord[1],Coord[2]};
	TransformCoords(coords, true, m_MeshType);
	//fprintf(stderr,"here\n");
	for (unsigned int i=0;i<vCoords.size()/6;++i)
	{
		in=true;
		for (unsigned int n=0;n<3;++n)
		{
			//fprintf(stderr,"%e %e %e \n",vCoords.at(6*i+2*n)->GetValue(),vCoords.at(6*i+2*n+1)->GetValue());
			UpVal=vCoords.at(6*i+2*n+1)->GetValue();
			DownVal=vCoords.at(6*i+2*n)->GetValue();
			if (DownVal<UpVal)
			{
				if (DownVal>coords[n]) {in=false;break;}
				if (UpVal<coords[n]) {in=false;break;}
			}
			else
			{
				if (DownVal<coords[n]) {in=false;break;}
				if (UpVal>coords[n]) {in=false;break;}
			}
		}
		if (in==true) {	return true;}
	}
	return false;
}
Exemple #3
0
bool CSPrimLinPoly::IsInside(const double* Coord, double tol)
{
	if (Coord==NULL) return false;
	double coords[3]={Coord[0],Coord[1],Coord[2]};
	if (m_Transform && Type==LINPOLY)
		TransformCoords(coords,true, m_MeshType);
	return CSPrimPolygon::IsInside(coords, tol);
}
//----------------------------------------------------------------
// Trasforms the AABB vertices to screen space once every frame
//----------------------------------------------------------------
void TransformedAABBoxSSE::TransformAABBox()
{
	for(UINT i = 0; i < AABB_VERTICES; i++)
	{
		mpXformedPos[i] = TransformCoords(&mpBBVertexList[i], mCumulativeMatrix);
		float oneOverW = 1.0f/max(mpXformedPos[i].m128_f32[3], 0.0000001f);
		mpXformedPos[i] = mpXformedPos[i] * oneOverW;
		mpXformedPos[i].m128_f32[3] = oneOverW;
	}
}
//-------------------------------------------------------------------
// Trasforms the occluder vertices to screen space once every frame
//-------------------------------------------------------------------
void TransformedMeshScalar::TransformVertices(const float4x4& cumulativeMatrix, 
										      UINT start, 
										      UINT end)
{
	for(UINT i = start; i <= end; i++)
	{
		mpXformedPos[i] = TransformCoords(mpVertices[i].pos, cumulativeMatrix);
		float oneOverW = 1.0f/max(mpXformedPos[i].w, 0.0000001f);
		mpXformedPos[i] = mpXformedPos[i] * oneOverW;
		mpXformedPos[i].w = oneOverW;
	}
}
Exemple #6
0
bool CSPrimRotPoly::IsInside(const double* inCoord, double /*tol*/)
{
	if (inCoord==NULL) return false;

	double Coord[3];
	//transform incoming coordinates into cartesian coords
	TransformCoordSystem(inCoord,Coord,m_MeshType,CARTESIAN);
	if (m_Transform && Type==ROTPOLY)
		TransformCoords(Coord,true, CARTESIAN);

	double origin[3]={0,0,0};
	double dir[3]={0,0,0};
	dir[m_RotAxisDir] = 1;
	double foot;
	double dist;
	Point_Line_Distance(Coord, origin, dir, foot, dist);

	int raP = (m_RotAxisDir+1)%3;
	int raPP = (m_RotAxisDir+2)%3;
	double alpha = atan2(Coord[raPP],Coord[raP]);
	if (raP == m_NormDir)
		alpha=alpha-M_PI/2;
	if (alpha<0)
		alpha+=2*M_PI;

	origin[0] = dist;origin[1] = dist;origin[2] = dist;
	origin[m_NormDir] = 0;
	origin[m_RotAxisDir] = foot;

	if (alpha<m_StartStopAng[0])
		alpha+=2*M_PI;

	if ((CSPrimPolygon::IsInside(origin)) && (alpha<m_StartStopAng[1]))
		return true;

	dist*=-1;
	alpha=alpha+M_PI;
	if (alpha>2*M_PI)
		alpha-=2*M_PI;

	if (alpha<m_StartStopAng[0])
		alpha+=2*M_PI;

	if (alpha>m_StartStopAng[1])
		return false;

	origin[0] = dist;origin[1] = dist;origin[2] = dist;
	origin[m_NormDir] = 0;
	origin[m_RotAxisDir] = foot;
	return CSPrimPolygon::IsInside(origin);
}
//-------------------------------------------------------------------
// Trasforms the occluder vertices to screen space once every frame
//-------------------------------------------------------------------
void SoftOccluderMeshScalar::TransformVertices(const float4x4 &cumulativeMatrix,
        UINT start,
        UINT end,
        UINT idx)
{
    for(UINT i = start; i <= end; i++)
    {
        float4 xform = TransformCoords(mpVertices[i].pos, cumulativeMatrix);
        float4 projected = xform / xform.w;

        //set to all 0s if clipped by near clip plane
        mpXformedPos[idx][i] = xform.z <= xform.w ? projected : float4(0.0, 0.0, 0.0, 0.0);
    }
}
Exemple #8
0
bool CSPrimBox::IsInside(const double* Coord, double /*tol*/)
{
    if (Coord==NULL) return false;

    const double* start = m_Coords[0].GetCoords(m_PrimCoordSystem);
    const double* stop  = m_Coords[1].GetCoords(m_PrimCoordSystem);
    double pos[3] = {Coord[0],Coord[1],Coord[2]};

    TransformCoords(pos, true, m_MeshType);
    //transform incoming coordinates into the coorindate system of the primitive
    TransformCoordSystem(pos,pos,m_MeshType,m_PrimCoordSystem);

    if (m_PrimCoordSystem!=UNDEFINED_CS)
        return CoordInRange(pos, start, stop, m_PrimCoordSystem);
    else
        return CoordInRange(pos, start, stop, m_MeshType);
}
Exemple #9
0
bool CSPrimPolygon::IsInside(const double* inCoord, double /*tol*/)
{
	if (inCoord==NULL) return false;
	if (vCoords.size()<2) return false;

	double Coord[3];
	//transform incoming coordinates into cartesian coords
	TransformCoordSystem(inCoord,Coord,m_MeshType,CARTESIAN);
	if (m_Transform && Type==POLYGON)
		TransformCoords(Coord,true, CARTESIAN);

	for (unsigned int n=0;n<3;++n)
		if ((m_BoundBox[2*n]>Coord[n]) || (m_BoundBox[2*n+1]<Coord[n])) return false;

	double x=0,y=0;
	int nP = (m_NormDir+1)%3;
	int nPP = (m_NormDir+2)%3;
	x = Coord[nP];
	y = Coord[nPP];

	int wn = 0;

	size_t np = vCoords.size()/2;
	double x1 = vCoords[2*np-2].GetValue();
	double y1 = vCoords[2*np-1].GetValue();
	double x2 = vCoords[0].GetValue();
	double y2 = vCoords[1].GetValue();
	bool startover = y1 >= y ? true : false;
	bool endover;

	for (size_t i=0;i<np;++i)
	{
		x2 = vCoords[2*i].GetValue();
		y2 = vCoords[2*i+1].GetValue();

		//check if coord is on a cartesian edge exactly
		if ((x2==x1) && (x1==x) && ( ((y<y1) && (y>y2)) || ((y>y1) && (y<y2)) ))
			return true;
		if ((y2==y1) && (y1==y) && ( ((x<x1) && (x>x2)) || ((x>x1) && (x<x2)) ))
			return true;

		endover = y2 >= y ? true : false;
		if (startover != endover)
		{
			if ((y2 - y)*(x2 - x1) <= (y2 - y1)*(x2 - x))
			{
				if (endover) wn ++;
			}
			else
			{
				if (!endover) wn --;
			}
		}
		startover = endover;
		y1 = y2;
		x1 = x2;
	}
	// return true if polygon is inside the polygon
	if (wn != 0)
		return true;

	return false;
}