//---------------------------------------------------------------------------- // 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(¢er, 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; }
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; }
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; } }
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); } }
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); }
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; }