int FrustumPlanes::BoxToFrustum2(const BOX &Box) const { D3DXVECTOR3 vmin; for (int i = 0; i < 6; i++) { if (Planes[i].a <= 0.0f) vmin.x = Box.v1.x; else vmin.x = Box.v2.x; if (Planes[i].b <= 0.0f) vmin.y = Box.v1.y; else vmin.y = Box.v2.y; if (Planes[i].c <= 0.0f) vmin.z = Box.v1.z; else vmin.z = Box.v2.z; if (D3DXPlaneDotCoord(&Planes[i], &vmin) < 0.0f) { if(i == 5) return 1; else return 0; } } return 2; }
bool FrustumPlanes::BoxToFrustum(const BOX &Box) const { // Na podstawie ksi¹¿ki "3D Game Engine Programming", Stefan Zerbst with Oliver Duvel D3DXVECTOR3 vmin; for (int i = 0; i < 6; i++) { if (Planes[i].a <= 0.0f) vmin.x = Box.v1.x; else vmin.x = Box.v2.x; if (Planes[i].b <= 0.0f) vmin.y = Box.v1.y; else vmin.y = Box.v2.y; if (Planes[i].c <= 0.0f) vmin.z = Box.v1.z; else vmin.z = Box.v2.z; if (D3DXPlaneDotCoord(&Planes[i], &vmin) < 0.0f) return false; } return true; }
// this function tests if the projection of a bounding sphere along the light direction intersects // the view frustum bool SweptSpherePlaneIntersect( float& t0, float& t1, const SPlane& plane, const SVector3& pos, float radius, const SVector3& sweepDir ) { float b_dot_n = D3DXPlaneDotCoord(&plane, &pos); float d_dot_n = D3DXPlaneDotNormal(&plane, &sweepDir); if (d_dot_n == 0.f) { if (b_dot_n <= radius) { // effectively infinity t0 = 0.f; t1 = 1e32f; return true; } else return false; } else { float tmp0 = ( radius - b_dot_n) / d_dot_n; float tmp1 = (-radius - b_dot_n) / d_dot_n; t0 = min(tmp0, tmp1); t1 = max(tmp0, tmp1); return true; } }
bool CFrustum::CheckSphere(float x, float y, float z, float radius) { for (int i = 0; i < 6; i++) if ( D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x,y,z)) < -radius ) return false; return true; }
bool Frustum::TestSphere( const SVector3& pos, float radius ) const { bool inside = true; for( int i=0; (i<6) && inside; i++ ) inside &= ( (D3DXPlaneDotCoord(&camPlanes[i], &pos) + radius) >= 0.0f ); return inside; }
bool FrustumPlanes::BoxToFrustum(const BOX2D& box) const { D3DXVECTOR3 vmin; for(int i = 0; i < 6; i++) { if(Planes[i].a <= 0.0f) vmin.x = box.v1.x; else vmin.x = box.v2.x; if(Planes[i].b <= 0.0f) vmin.y = 0.f; else vmin.y = 25.f; if(Planes[i].c <= 0.0f) vmin.z = box.v1.y; else vmin.z = box.v2.y; if (D3DXPlaneDotCoord(&Planes[i], &vmin) < 0.0f) return false; } return true; }
bool CFrustum::CheckPoint(float x, float y, float z) { for (int i = 0; i < 6; i++) if ( D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x,y,z)) < 0.0f ) return false; return true; }
//============================================================================== // Brief : 衝突判定押し戻し跳ね返り処理(点と球状地形) // Return : bool : 衝突判定結果(true : 面の裏側) // Arg : D3DXVECTOR3* pPoint : 対象点 // Arg : D3DXVECTOR3* pVel : 対象点速度 // Arg : D3DXPLANE* pPlane : 対象面 //============================================================================== bool CCollision::IsCollidedPushReboundSphereField(D3DXVECTOR3* pPoint, D3DXVECTOR3* pVel, D3DXPLANE* pPlane) { D3DXVECTOR3 m_posPoint = *pPoint + *pVel; // 判定座標 D3DXVECTOR3 vecNormal; // 面の法線 float fDist; // 対象間の距離 // 判定 fDist = D3DXPlaneDotCoord(pPlane, &m_posPoint); if(fDist <= 0.0f) { // 押し戻し m_posPoint = 2.0f * *pPoint; D3DXPlaneIntersectLine(pPoint, pPlane, pPoint, &m_posPoint); // 速度設定 vecNormal.x = pPlane->a; vecNormal.y = pPlane->b; vecNormal.z = pPlane->c; *pVel += -2.0f * D3DXVec3Dot(pVel, &vecNormal) * vecNormal; // 当たっている return true; } // 当たっていない return false; }
// plane 에 잘려지는가 ? bool CheckWinding(RWinding *pWinding, rplane &plane) { SIDE sides[MAX_WINDING_POINTS]; float dists[MAX_WINDING_POINTS]; int nFront=0,nBack=0,i=0; for(i=0;i<pWinding->nCount;i++) { float fDot=D3DXPlaneDotCoord(&plane,&pWinding->pVertices[i]); if(fDot>ON_EPSILON) { sides[i]=SIDE_FRONT; nFront++; } else if(fDot<-ON_EPSILON) { sides[i]=SIDE_BACK; nBack++; } else sides[i]=SIDE_ON; dists[i]=fDot; } sides[i]=sides[0]; dists[i]=dists[0]; if(!nBack) // 전혀 잘려지지 않음. return false; return true; }
TEST( Plane, dotCoord ) { Plane plane; Vector testPt; testPt.set( 3, 2, -1 ); plane.set( Quad_1000, FastFloat::fromFloat( 10.0f ) ); float dxDot = D3DXPlaneDotCoord( ( const D3DXPLANE* )&plane, ( const D3DXVECTOR3* )&testPt ); float tamyDot = plane.dotCoord( testPt ).getFloat(); CPPUNIT_ASSERT_DOUBLES_EQUAL( dxDot, tamyDot, 1e-3f ); testPt.set( 3, 2, -1 ); plane.set( Quad_Neg_0100, FastFloat::fromFloat( -12.0f ) ); dxDot = D3DXPlaneDotCoord( ( const D3DXPLANE* )&plane, ( const D3DXVECTOR3* )&testPt ); tamyDot = plane.dotCoord( testPt ).getFloat(); CPPUNIT_ASSERT_DOUBLES_EQUAL( dxDot, tamyDot, 1e-3f ); }
//----------------------------------------------------------------------------- // Returns true if the given sphere is inside the view frustum. //----------------------------------------------------------------------------- bool ViewFrustum::IsSphereInside( D3DXVECTOR3 translation, float radius ) { for( char p = 0; p < 5; p++ ) if( D3DXPlaneDotCoord( &m_planes[p], &translation ) < -radius ) return false; return true; }
/// 如果一个点 v在平截头体内,就会返回TRUE,反之为FALSE. BOOL ZFrustum::IsIn( D3DXVECTOR3* pv ) { float fDist; // int i; // 现在只使用 left, right, far plane. // for( i = 0 ; i < 6 ; i++ ) { fDist = D3DXPlaneDotCoord( &m_plane[3], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane的 normal向量指向 far,如果为正数,表示在平截头体外部. fDist = D3DXPlaneDotCoord( &m_plane[4], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane的 normal向量指向 left,如果为正数,表示在平截头体的左边. fDist = D3DXPlaneDotCoord( &m_plane[5], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane的 normal向量指向 right,如果为正数,表示在平截头体的右边. } return TRUE; }
// 点pv在平截台体内,返回TRUE,不在平截台体内,返回FALSE bool ZFrustum::IsIn(D3DXVECTOR3* pv) { for (int i=3;i<6;i++) { if (D3DXPlaneDotCoord(&m_plane[i],pv) > m_fEpsilon) return false; } return true; }
// 具有中心圆点(pv)和半径(radius)的边界球体(bounding sphere)在平截台体内,返回TRUE,不在平截台体内,返回FALSE bool ZFrustum::IsInSphere(D3DXVECTOR3* pv,float radius) { for(int i=3;i<6;i++) { if (D3DXPlaneDotCoord(&m_plane[i],pv) > radius + m_fEpsilon) return false; } return true; }
/// 한점 v가 프러스텀안에 있으면 TRUE를 반환, 아니면 FALSE를 반환한다. bool CFrustum::isIn( D3DXVECTOR3* pv ) { float fDist; // int i; // 현재는 left, right, far plane만 적용한다. // for( i = 0 ; i < 6 ; i++ ) { fDist = D3DXPlaneDotCoord( &m_plane[3], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane의 normal벡터가 far로 향하고 있으므로 양수이면 프러스텀의 바깥쪽 fDist = D3DXPlaneDotCoord( &m_plane[4], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane의 normal벡터가 left로 향하고 있으므로 양수이면 프러스텀의 왼쪽 fDist = D3DXPlaneDotCoord( &m_plane[5], pv ); if( fDist > PLANE_EPSILON ) return FALSE; // plane의 normal벡터가 right로 향하고 있으므로 양수이면 프러스텀의 오른쪽 } return true; }
bool Plane::Inside(const Vec3 &point, const float radius) const { float fDistance; // calculate our distances to each of the planes // find the distance to this plane fDistance = D3DXPlaneDotCoord(this, &point); // if this distance is < -radius, we are outside return (fDistance >= -radius); }
bool Frustum::CheckRectangle(float xCenter, float yCenter, float zCenter, float xSize, float ySize, float zSize) { int i; // Check if any of the 6 planes of the rectangle are inside the view frustum. for(i=0; i<6; i++) { if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f) { continue; } return false; } return true; }
bool Frustum::CheckCube(float xCenter, float yCenter, float zCenter, float radius) { int i; // Check if any one point of the cube is in the view frustum. for(i=0; i<6; i++) { if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter - radius), (zCenter - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter - radius), (zCenter - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter + radius), (zCenter - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter + radius), (zCenter - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter - radius), (zCenter + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter - radius), (zCenter + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter - radius), (yCenter + radius), (zCenter + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((xCenter + radius), (yCenter + radius), (zCenter + radius))) >= 0.0f) { continue; } return false; } return true; }
bool AVFrustum::IsIn( D3DXVECTOR3 *v ) { float fDist; for(int i = 0 ; i < 6 ; i++ ) { fDist = D3DXPlaneDotCoord( &m_plane[i], v ); if( fDist > PLANE_EPSILON ) return false; } return TRUE; }
bool CGEFrustum::CheckPoint(float x, float y, float z) { for(int i = 0; i != 6; i++) { if( D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3(x, y, z)) < 0.0f ) { return false; } } return true; }
//============================================================================== // Brief : 衝突判定処理(点と面) // Return : bool : 衝突判定結果(true : 面の裏側) // Arg : D3DXVECTOR3* pPoint : 対象点 // Arg : D3DXPLANE* pPlane : 対象面 //============================================================================== bool CCollision::IsCollided(D3DXVECTOR3* pPoint, D3DXPLANE* pPlane) { // 判定 if(D3DXPlaneDotCoord(pPlane, pPoint) <= 0.0f) { // 当たっている return true; } // 当たっていない return false; }
bool AVFrustum::IsInSphere(D3DXVECTOR3 *v, float radius) { float fDist; for(int i=0; i<6; i++) { fDist = D3DXPlaneDotCoord( &m_plane[i], v ); if( fDist > (radius + PLANE_EPSILON) ) return false; } return TRUE; }
bool CGEFrustum::CheckSphere(float x, float y, float z, float radius) { for(int i = 0; i != 6; i++) { if( D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3(x, y, z)) < -radius) { return false; } } return true; }
bool Frustum::CheckPoint(float x, float y, float z) { int i; // Check if the point is inside all six planes of the view frustum. for(i=0; i<6; i++) { if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3(x, y, z)) < 0.0f) { return false; } } return true; }
bool Frustum::CheckSphere(float x, float y, float z, float radius) { int i; // Check if the radius of the sphere is inside the view frustum. for(i=0; i<6; i++) { if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3(x, y, z)) < -radius) { return false; } } return true; }
bool CGEFrustum::CheckBox(float xCenter, float yCenter, float zCenter, float xSize, float ySize, float zSize) { for(int i = 0; i != 6; i++) { if( D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter - zSize))) > 0.0f ) { continue; } if( D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter - zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter - ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter - xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&this->m_planes[i], &D3DXVECTOR3((xCenter + xSize), (yCenter + ySize), (zCenter + zSize))) >= 0.0f) { continue; } } return true; }
bool CFrustum::CheckCube(float x, float y, float z, float radius) { for (int i = 0; i < 6; i++) { if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-radius, y-radius, z-radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+radius, y-radius, z-radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-radius, y+radius, z-radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+radius, y+radius, z-radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-radius, y-radius, z+radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+radius, y-radius, z+radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-radius, y+radius, z+radius)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+radius, y+radius, z+radius)) >= 0.0f) continue; return false; } return true; }
bool CFrustum::CheckBox(float x, float y, float z, float sizeX, float sizeY, float sizeZ) { for (int i = 0; i < 6; i++) { if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-sizeX, y-sizeY, z-sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+sizeX, y-sizeY, z-sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-sizeX, y+sizeY, z-sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+sizeX, y+sizeY, z-sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-sizeX, y-sizeY, z+sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+sizeX, y-sizeY, z+sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x-sizeX, y+sizeY, z+sizeZ)) >= 0.0f) continue; if (D3DXPlaneDotCoord(&planes[i], &D3DXVECTOR3(x+sizeX, y+sizeY, z+sizeZ)) >= 0.0f) continue; return false; } return true; }
bool CGEFrustum::CheckBox(float x, float y, float z, float radius) { for(int i = 0; i != 6; i++) { if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x - radius), (y - radius), (z - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x + radius), (y - radius), (z - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x - radius), (y + radius), (z - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x + radius), (y + radius), (z - radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x - radius), (y - radius), (z + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x + radius), (y - radius), (z + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x - radius), (y + radius), (z + radius))) >= 0.0f) { continue; } if(D3DXPlaneDotCoord(&m_planes[i], &D3DXVECTOR3((x + radius), (y + radius), (z + radius))) >= 0.0f) { continue; } } return true; }
bool ViewFrustum::sphereInside(Vector3D position, unsigned int radius) { //test all 6 planes for(int i=0; i<6; ++i) { if ( D3DXPlaneDotCoord(&this->m_planes[i], &position) + radius < 0 ) { //outside return false; } } //inside return true; }