////////////////////////////////////////////////////////////////////////// // findDistanceByAttenuation BcF32 ScnLightComponent::findDistanceByAttenuation( BcF32 Attenuation ) const { // If we want it at a low value, return max distance. if( Attenuation < 0.05f ) { Attenuation = 0.05f; } BcF32 A = AttnQ_; BcF32 B = AttnL_; BcF32 C = AttnC_ - ( 1.0f / Attenuation ); // 0 = Ax2 + Bx + C if( A > 0.0f ) { BcF32 Discriminant = ( ( B * B ) - ( 4.0f * A * C ) ); if( Discriminant < 0.0f ) { return 1e24f; } return BcAbs( ( -B + BcSqrt( Discriminant ) ) / ( 2.0f * A ) ); } // 0 = Bx + C else if( B > 0.0f ) { return BcAbs( -C / B ); } // 0 = C else { return 1e24f; } }
//////////////////////////////////////////////////////////////////////////////// // findPointOnEdge BcBool MaBSPTree::lineIntersection( const MaVec3d& A, const MaVec3d& B, BcBSPPointInfo* pPointInfo, MaBSPNode* pNode /*= NULL*/ ) { // Check if we want the root node. if( pNode == NULL ) { pNode = pRootNode_; if( pPointInfo != NULL ) { pPointInfo->Point_ = B; pPointInfo->Distance_ = 1e12f; } } // Really naive way... BcBool Intersected = BcFalse; // TODO: Handle coincident intersection! MaPlane::eClassify ClassifyA = pNode->Plane_.classify( A, 0.0f ); MaPlane::eClassify ClassifyB = pNode->Plane_.classify( B, 0.0f ); if( ClassifyA == MaPlane::bcPC_FRONT && ClassifyB == MaPlane::bcPC_BACK ) { BcF32 T; MaVec3d Intersection; if( pNode->Plane_.lineIntersection( A, B, T, Intersection ) ) { // Is point in vertices? If so go down front to find nearer intersection. if( pointOnNode( Intersection, pNode ) ) { // If we want point info recurse deeper to get it. if( pPointInfo != NULL ) { BcF32 DistanceSquared = ( A - Intersection ).magnitudeSquared(); // Check the distance, if it's less then go deeper! if( DistanceSquared < ( pPointInfo->Distance_ * pPointInfo->Distance_ ) ) { pPointInfo->Plane_ = pNode->Plane_; pPointInfo->Distance_ = BcSqrt( DistanceSquared ); pPointInfo->Point_ = Intersection; } } Intersected |= BcTrue; } } } // NOTE: ClassifyB shouldn't be required here ...right? if( pNode->pFront_ != NULL ) { if( ClassifyA == MaPlane::bcPC_FRONT || ClassifyB == MaPlane::bcPC_FRONT ) { Intersected |= lineIntersection( A, B, pPointInfo, pNode->pFront_ ); } } if( pNode->pBack_ != NULL ) { if( ClassifyA == MaPlane::bcPC_BACK || ClassifyB == MaPlane::bcPC_BACK ) { Intersected |= lineIntersection( A, B, pPointInfo, pNode->pBack_ ); } } return Intersected; }