D:/Zythum/DinoKod/Bsp/Bsp.cpp

00001 //---------------------------------------------------------------------------------------------
00002 //      This file is a part of "DinoKod".
00003 //      Copyright © 2003 Dino Productions. All Rights Reserved.
00004 //      
00005 //      File                    : Bsp.cpp
00006 //      Author                  : Sebastien LEIX        sebastien.leix@wanadoo.fr
00007 //      Date                    : 07/09/2002
00008 //      Modification    :
00009 //
00010 //---------------------------------------------------------------------------------------------
00011 #include <conio.h>
00012 
00013 #include "Common/Assert.h"
00014 #include "Common/Error.h"
00015 #include "Common/Console.h"
00016 #include "Common/Directory.h"
00017 #include "Common/Plane.h"
00018 //#include "Common/Math3D.h"
00019 #include "Common/Vertex.h"
00020 #include "Physics/PhysicsCollision.h"
00021 
00022 #include "Bsp/BezierPatch.h"
00023 
00024 #include "Bsp/Bsp.h"
00025 
00026 #define EPSILON 0.03125f        // 1/32 float
00027 
00028 //---------------------------------------------------------------------------------------------------------------------
00029 KBsp::KBsp()
00030 : KBspLoader()
00031 {
00032         m_pBezierPatches                = 0;
00033         m_pComputedVertices             = NULL;
00034 }
00035 
00036 //---------------------------------------------------------------------------------------------------------------------
00037 KBsp::~KBsp()
00038 {
00039 }
00040 
00041 //---------------------------------------------------------------------------------------------------------------------
00042 s32 KBsp::LoadBSP( const char* pFileName )
00043 {
00044         
00045         s32                     Result;
00046 //      char            pFullName[1024];
00047 //      const char*     pPath;
00048 
00049 //      pPath = g_Directory.GetPath( "Datas" );
00050 
00051 //      strcpy( pFullName, pPath );
00052 //      strcat( pFullName, pFileName );
00053 
00054         // Charge le BSP
00055         g_Console << "Loading map [" << (char*)pFileName << "]...";
00056 
00057         Result = KBspLoader::LoadBSP( pFileName );
00058 
00059         switch( Result )
00060         {
00061         case BSP_OK:
00062                 g_Console << "OK" << KENDL;
00063                 g_Console << "Nb Vertices  : " << (int)m_nVertices << KENDL;
00064                 g_Console << "Nb Faces     : " << (int)m_nFaces << KENDL;
00065                 g_Console << "Nb Shaders   : " << (int)m_nShaders << KENDL;
00066                 g_Console << "Nb Lightmaps : " << (int)m_nLightMaps << KENDL;
00067                 break;
00068         case BSP_ERROR_OPENFILE:
00069                 g_Console << "Cannot open file." << KENDL;
00070                 return Result;
00071         case BSP_ERROR_BADVERSION:
00072                 g_Console << "Bad version." << KENDL;
00073                 return Result;
00074         }
00075 
00076         m_pBezierPatches        = new KBezierPatch[m_nFaces];
00077         m_pComputedVertices     = new KLVertex2[m_nVertices];
00078 
00079         ComputeVertices();
00080         ComputeBezier();
00081 
00082         return BSP_OK;
00083 }
00084 
00085 //---------------------------------------------------------------------------------------------------------------------
00086 s32 KBsp::CloseBSP()
00087 {
00088         if( m_pBezierPatches )
00089                 Deletev( m_pBezierPatches );
00090         
00091         if( m_pComputedVertices )
00092                 Deletev( m_pComputedVertices );
00093 
00094         return KBspLoader::CloseBSP();
00095 }
00096 
00097 //---------------------------------------------------------------------------------------------------------------------
00098 u32 KBsp::FindLeaf( u32 NodeId, KVector& Position )
00099 {
00100         if( KVector::DotProduct( m_pPlanes[m_pNodes[NodeId].m_PlaneId].m_Normal, Position ) -  m_pPlanes[m_pNodes[NodeId].m_PlaneId].m_Distance >= 0 )
00101         {
00102                 // Devant
00103                 if( m_pNodes[NodeId].m_Front & 0x8000 )
00104                 {
00105                         // Leaf trouvé
00106                         return (u16)-( m_pNodes[NodeId].m_Front + 1);
00107                 }
00108                 else
00109                         return FindLeaf( m_pNodes[NodeId].m_Front, Position );
00110         }
00111 
00112         // Derriere
00113         if( m_pNodes[NodeId].m_Back & 0x8000 )
00114         {
00115                 // Leaf trouvé
00116                 return (u16)-( m_pNodes[NodeId].m_Back + 1);
00117         }
00118         else
00119                 return FindLeaf( m_pNodes[NodeId].m_Back, Position );           
00120 }
00121 
00122 //---------------------------------------------------------------------------------------------------------------------
00123 void KBsp::ComputeVertices()
00124 {
00125         u32     v;
00126 
00127         for( v = 0; v < m_nVertices; v ++ )
00128         {
00129                 KRgba   Color = KRgba( 255, 255, 255, 255 );
00130                 
00131 /*              if( !m_bUseLightMaps )
00132                 {
00133                         Color = m_pVertices[v].m_Color;
00134                         if( m_bSwapRgb )
00135                                 Color.Swap();
00136                 }
00137 */
00138                 m_pComputedVertices[v].Position         = m_pVertices[v].m_Position;
00139                 m_pComputedVertices[v].Color            = KRGBA2INT( Color );
00140                 m_pComputedVertices[v].tu1                      = m_pVertices[v].m_UV[0].x;
00141                 m_pComputedVertices[v].tv1                      = m_pVertices[v].m_UV[0].y;
00142                 m_pComputedVertices[v].tu2                      = m_pVertices[v].m_UV[1].x;
00143                 m_pComputedVertices[v].tv2                      = m_pVertices[v].m_UV[1].y;
00144         }
00145 }
00146 
00147 //---------------------------------------------------------------------------------------------------------------------
00148 void KBsp::ComputeBezier()
00149 {
00150         KASSERT( m_pBezierPatches );
00151 
00152         for( u32 i = 0; i < m_nFaces; i ++ )
00153         {
00154                 if( m_pFaces[i].m_Type == KBFT_PATCH )
00155                 {
00156                         m_pBezierPatches[i].GenerateVertices( &m_pComputedVertices[m_pFaces[i].m_FirstVertexId], KPt( m_pFaces[i].m_Size ) );
00157                 }
00158         }
00159 }
00160 
00161 //---------------------------------------------------------------------------------------------------------------------
00162 //-- COLLISION
00163 //---------------------------------------------------------------------------------------------------------------------
00164 void KBsp::CheckSphereCollision( u32 NodeId, KPhysicsCollisionData* pData )
00165 {
00166         float   Radius;
00167 
00168         Radius = MAX( MAX( pData->m_eRadius.x, pData->m_eRadius.y ), pData->m_eRadius.z );
00169         Radius += pData->m_R3Velocity.Magnitude();
00170 
00171         float   fDist   = KVector::DotProduct( m_pPlanes[m_pNodes[NodeId].m_PlaneId].m_Normal, pData->m_R3Position ) - m_pPlanes[m_pNodes[NodeId].m_PlaneId].m_Distance;
00172 
00173         if( fDist >= -Radius )
00174         {
00175                 // Devant
00176                 if( m_pNodes[NodeId].m_Front & 0x8000 )
00177                 {
00178                         // Leaf trouvé
00179                         CheckLeafSphereCollision( (u16)-( m_pNodes[NodeId].m_Front + 1), pData );
00180                 }
00181                 else
00182                         CheckSphereCollision( m_pNodes[NodeId].m_Front, pData );
00183         }
00184 
00185         if( fDist <= Radius )
00186         {
00187                 // Derriere
00188                 if( m_pNodes[NodeId].m_Back & 0x8000 )
00189                 {
00190                         // Leaf trouvé
00191                         CheckLeafSphereCollision( (u16)-( m_pNodes[NodeId].m_Back + 1), pData );
00192                 }
00193                 else
00194                         CheckSphereCollision( m_pNodes[NodeId].m_Back, pData );
00195         }
00196 }
00197 
00198 //---------------------------------------------------------------------------------------------------------------------
00199 bool KBsp::CheckLeafSphereCollision( u32 LeafId, KPhysicsCollisionData* pData )
00200 {
00201         s32             FaceId;
00202         u32             Face;
00203         s32             MeshVertId;
00204         KVector pVertex[3];
00205 
00206         if( !LeafId )
00207                 return false;
00208 
00209 //      DrawLeaf( LeafId );
00210 
00211         for(    FaceId = m_pLeaves[LeafId].m_FirstFaceId;
00212                         FaceId < m_pLeaves[LeafId].m_FirstFaceId + m_pLeaves[LeafId].m_NumFaces;
00213                         FaceId ++ )
00214 
00215         {
00216                 Face = m_pFaceList[FaceId].m_Face;
00217                 
00218                 //
00219                 //      POLYGON
00220                 //
00221                 if( m_pFaces[Face].m_Type == KBFT_POLYGON )
00222                 {
00223                         for(    MeshVertId = m_pFaces[Face].m_FirstMeshVert;
00224                                         MeshVertId < m_pFaces[Face].m_FirstMeshVert + m_pFaces[Face].m_NumMeshVerts;
00225                                         MeshVertId += 3 )
00226                         {
00227                                 pVertex[0] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 0].m_FirstVertexId].m_Position;
00228                                 pVertex[1] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 2].m_FirstVertexId].m_Position;
00229                                 pVertex[2] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 1].m_FirstVertexId].m_Position;
00230 
00231 #if _DEBUG
00232         m_DebugCollFace ++;
00233 #endif _DEBUG
00234                                 KPhysicsCollision::CheckSphereCollision( pData, pVertex[0], pVertex[1], pVertex[2] );
00235                         }
00236                 }
00237 
00238                 
00239                 //
00240                 //      MESH
00241                 //
00242                 if( m_pFaces[Face].m_Type == KBFT_MESH )
00243                 {
00244                         for(    MeshVertId = m_pFaces[Face].m_FirstMeshVert;
00245                                         MeshVertId < m_pFaces[Face].m_FirstMeshVert + m_pFaces[Face].m_NumMeshVerts;
00246                                         MeshVertId += 3 )
00247                         {
00248                                 pVertex[0] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 0].m_FirstVertexId].m_Position;
00249                                 pVertex[1] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 2].m_FirstVertexId].m_Position;
00250                                 pVertex[2] = m_pVertices[m_pFaces[Face].m_FirstVertexId + m_pMeshVerts[MeshVertId + 1].m_FirstVertexId].m_Position;
00251 
00252 #if _DEBUG
00253         m_DebugCollFace ++;
00254 #endif _DEBUG
00255                                 KPhysicsCollision::CheckSphereCollision( pData, pVertex[0], pVertex[1], pVertex[2] );
00256                         }
00257                 }
00258 
00259                 //
00260                 //      PATCH
00261                 //
00262                 if( m_pFaces[Face].m_Type == KBFT_PATCH )
00263                 {
00264                         for(    MeshVertId = 0;
00265                                         MeshVertId < m_pBezierPatches[Face].GetnIndices();
00266                                         MeshVertId += 3 )
00267                         {
00268                                 pVertex[0] = m_pBezierPatches[Face].GetpVertices()[m_pBezierPatches[Face].GetpIndices()[MeshVertId + 0]].Position;
00269                                 pVertex[1] = m_pBezierPatches[Face].GetpVertices()[m_pBezierPatches[Face].GetpIndices()[MeshVertId + 2]].Position;
00270                                 pVertex[2] = m_pBezierPatches[Face].GetpVertices()[m_pBezierPatches[Face].GetpIndices()[MeshVertId + 1]].Position;
00271 
00272 #if _DEBUG
00273         m_DebugCollFace ++;
00274 #endif _DEBUG
00275                                 KPhysicsCollision::CheckSphereCollision( pData, pVertex[0], pVertex[1], pVertex[2] );
00276                         }
00277                 }
00278         }
00279 
00280         return true;
00281 }
00282 
00284 // Here comes the Hard Stuff. First read the Collision.html to get a fully 
00285 // explanation of how this work
00286 // This function take an Star location and a target and see if the ray collide with 
00287 // something. All the information need to handle the collision is returned in the
00288 // sMoveData.
00289 //---------------------------------------------------------------------------------------------------------------------
00290 KBspCollisionData KBsp::CheckRayMove( KVector& vStart, KVector& vEnd )
00291 {
00292         KBspCollisionData       CollisionData;
00293 
00294         // Initializations, This will change if the traversal detect it was wrong
00295         CollisionData.m_StartOut        = true;    
00296         CollisionData.m_AllSolid        = false;
00297         CollisionData.m_Fraction        = 1.0f;
00298         // Necessary info to collide with brushes
00299         CollisionData.m_Start           = vStart;
00300         CollisionData.m_End                     = vEnd;
00301         CollisionData.m_ObjectType      = BSP_COLL_RAY;
00302         CollisionData.m_MoveOffset      = 0.0f;
00303 
00304         // walk through the BSP tree
00305         CheckMoveByNode( 0, 0.0f, 1.0f, vStart, vEnd, CollisionData );
00306 
00307         if( CollisionData.m_Fraction == 1.0f)
00308         {       // nothing blocked the trace
00309                 CollisionData.m_EndPoint = vEnd;
00310         }
00311         else
00312         {       // collided with something 
00313                 CollisionData.m_EndPoint = vStart + ( vEnd - vStart ) * CollisionData.m_Fraction;
00314         }
00315         return CollisionData;
00316 }
00317 
00319 // Here comes the Hard Stuff. First read the Collision.html to get a fully 
00320 // explanation of how this work
00321 //---------------------------------------------------------------------------------------------------------------------
00322 KBspCollisionData KBsp::CheckSphereMove( KVector& vStart, KVector& vEnd, float Radius )
00323 {
00324         KBspCollisionData       CollisionData;
00325 
00326         // Initializations, This will change if the traversal detect it was wrong
00327         CollisionData.m_StartOut                = true;    
00328         CollisionData.m_AllSolid                = false;
00329         CollisionData.m_Fraction                = 1.0f;
00330         // Necessary info to collide with brushes
00331         CollisionData.m_Start                   = vStart;
00332         CollisionData.m_End                             = vEnd;
00333         CollisionData.m_ObjectType              = BSP_COLL_SPHERE;
00334         CollisionData.m_MoveOffset              = Radius;
00335 
00336         // walk through the BSP tree
00337         CheckMoveByNode( 0, 0.0f, 1.0f, vStart, vEnd, CollisionData );
00338 
00339         if( CollisionData.m_Fraction == 1.0f )
00340         {       // nothing blocked the trace
00341                 CollisionData.m_EndPoint = vEnd;
00342         }
00343         else
00344         {       // collided with something 
00345                 CollisionData.m_EndPoint = vStart + ( vEnd - vStart ) * CollisionData.m_Fraction;
00346         }
00347         return CollisionData;
00348 }
00349 
00350 // Check if we collide with something of this node ( including children and leafs
00351 //---------------------------------------------------------------------------------------------------------------------
00352 void KBsp::CheckMoveByNode( s32 NodeId, float StartFraction, float EndFraction, KVector& vStart, KVector vEnd, KBspCollisionData& CollisionData )
00353 {
00354         // If the path was blocked by a nearer obstacle, don't bother checking
00355         if( CollisionData.m_Fraction <= StartFraction) 
00356                 return;
00357 
00358         if( NodeId < 0 )
00359         {       // this is a leaf
00360                 KBspLeaf* pLeaf = &m_pLeaves[~NodeId];  // Get a pointer from the m_pLeafs Array. 
00361                                                                                                 // Remember that NodeIndex is negative so the corresponding leafs is
00362                                                                                                 // ~nodeIndex which is same of saying -(NodeIndex+1) but faster!
00363                                                                                                 // Loop by all the brushes 
00364                 for( s32 i = 0; i < pLeaf->m_NumBrushes; i++ )
00365                 {
00366                         //Take a point to the i-th brush in the leaf
00367                         KBspBrush* pBrush = &m_pBrushes[m_pBrushList[pLeaf->m_FirstBrushId + i].m_Brush];
00368 
00369                         // If the brush has sides (is a convex volume) and is SOLID then check it out!
00370                         if( pBrush->m_NumBrushSides > 0 && ( m_pShaders[pBrush->m_TextureId].m_Contents & 1 ) )
00371                         {
00372                                 CheckTouchBrush( pBrush, CollisionData );
00373                         }
00374                 }
00375         
00376                 // don't have to do anything else for leaves
00377                 return;
00378         }
00379 
00380         // this is a node.
00381         // Get pointer to the Node it self and to the splitter plane
00382         KBspNode*       pNode   = &m_pNodes[NodeId];
00383         KBspPlane*      pPlane  = &m_pPlanes[pNode->m_PlaneId];
00384 
00385         // Get the distance from the start and end point to the plane. This is done with the Plane formula:
00386         float StartDistance =   pPlane->m_Normal.x * vStart.x + 
00387                                                         pPlane->m_Normal.y * vStart.y + 
00388                                                         pPlane->m_Normal.z * vStart.z - 
00389                                                         pPlane->m_Distance;
00390         float EndDistance   =   pPlane->m_Normal.x * vEnd.x + 
00391                                                         pPlane->m_Normal.y * vEnd.y + 
00392                                                         pPlane->m_Normal.z * vEnd.z - 
00393                                                         pPlane->m_Distance;
00394 
00395         // If both points are in front of the plane (the positive side) pass the ray to the front 
00396         // child as the ray comes.
00397         
00398         if( ( StartDistance >= CollisionData.m_MoveOffset ) && ( EndDistance >= CollisionData.m_MoveOffset ) )
00399         {       
00400                 CheckMoveByNode( pNode->m_Front, StartFraction, EndFraction, vStart, vEnd, CollisionData );
00401         }
00402 
00403         // If both points are in behind the plane (the negative side) pass the ray to the back 
00404         // child as the ray comes.
00405 
00406         else if( ( StartDistance < -CollisionData.m_MoveOffset ) && ( EndDistance < -CollisionData.m_MoveOffset ) )
00407         {
00408                 CheckMoveByNode( pNode->m_Back, StartFraction, EndFraction, vStart, vEnd, CollisionData );
00409         }
00410 
00411         else
00412         {       // the line spans the splitting plane
00413                 s32                     Side1, Side2;                           // Variables to hold which side to traverse first and which second
00414                 float           Fraction1, Fraction2;           // Used to know compute the Smiddle and Emiddle. 
00415                 KVector         vMiddle;                                        // middle point (Smiddle and Emiddle)
00416 
00417                 // split the segment into two
00418 
00419                 // If we know that one is positive and the other is negative, and startDistance < endDistance, so 
00420                 // startDistance is negative and endDistance is positive (front and back correspondingly)
00421                 if( StartDistance < EndDistance )
00422                 {
00423                         Side1 = pNode->m_Back;    // the back side contains the start point so the back will be the first
00424                         Side2 = pNode->m_Front;    
00425                         float InverseDistance = 1.0f / ( StartDistance - EndDistance ); // optimization
00426                         Fraction1 = ( StartDistance - EPSILON - CollisionData.m_MoveOffset ) * InverseDistance;   // compute fraction for the start-middle
00427                         Fraction2 = ( StartDistance + EPSILON + CollisionData.m_MoveOffset ) * InverseDistance;   // compute fraction for the middle-end
00428                 }
00429                 // On the other hand if endDistance is negative and startDistance is positive
00430                 else if ( EndDistance < StartDistance )
00431                 {
00432                         Side1 = pNode->m_Front;   // the front side contains the start point so the front will be the first
00433                         Side2 = pNode->m_Back;
00434                         float InverseDistance = 1.0f / ( StartDistance - EndDistance );
00435                         Fraction1 = ( StartDistance + EPSILON + CollisionData.m_MoveOffset ) * InverseDistance;
00436                         Fraction2 = ( StartDistance - EPSILON - CollisionData.m_MoveOffset ) * InverseDistance;
00437                 }
00438                 else
00439                 {
00440                         Side1 = pNode->m_Front;
00441                         Side2 = pNode->m_Back;
00442                         Fraction1 = 1.0f;
00443                         Fraction2 = 0.0f;
00444                 }
00445 
00446                 // make sure the numbers are valid
00447                 if( Fraction1 < 0.0f ) Fraction1 = 0.0f;
00448                 else if ( Fraction1 > 1.0f ) Fraction1 = 1.0f;
00449                 if ( Fraction2 < 0.0f ) Fraction2 = 0.0f;
00450                 else if ( Fraction2 > 1.0f ) Fraction2 = 1.0f;
00451 
00452                 // calculate the middle point for the first side
00453                 vMiddle            = vStart + ( vEnd - vStart ) * Fraction1;
00454 
00455                 // get the Smiddle fraction (not just the point)
00456                 float MiddleFraction = StartFraction + ( EndFraction - StartFraction) * Fraction1;
00457 
00458                 // check the first side
00459                 CheckMoveByNode( Side1, StartFraction, MiddleFraction, vStart, vMiddle, CollisionData );
00460 
00461                 // calculate the middle point for the second side
00462                 vMiddle = vStart + ( vEnd - vStart ) * Fraction2;
00463 
00464                 // get the Emiddle fraction (not just the point)
00465                 MiddleFraction = StartFraction + ( EndFraction - StartFraction ) * Fraction2;
00466 
00467                 // check the second side
00468                 CheckMoveByNode( Side2, MiddleFraction, EndFraction, vMiddle, vEnd, CollisionData );
00469         }
00470 }
00471 
00472 //---------------------------------------------------------------------------------------------------------------------
00473 void KBsp::CheckTouchBrush( KBspBrush* pBrush, KBspCollisionData& CollisionData )
00474 {
00475         float   StartFraction   = -1.0f;        // The S in the pictures
00476         float   EndFraction             = 1.0f;         // The E in the pictures
00477         bool    StartsOut               = false;        // If not plane change this value then the ray start IN
00478         bool    EndsOut                 = false;        // If not plane change this value then the ray end IN
00479 
00480         KVector         CandidateToHitNormal;
00481 
00482         // Go for every brush side 
00483         for( s32 i = 0; i < pBrush->m_NumBrushSides; i ++ )
00484         {
00485                 // take a pointer to the brush side and the plane it represent
00486                 KBspBrushSide*  pBrushSide      = &m_pBrushSides[pBrush->m_FirstBrushSideId + i];
00487                 KBspPlane*              pPlane          = &m_pPlanes[pBrushSide->m_PlaneId];
00488 
00489                 // Compute distances from the plane to the MStart and MEnd (the values enter at the begging of the trace
00490                 float StartDistance =   pPlane->m_Normal.x * CollisionData.m_Start.x + 
00491                                                                 pPlane->m_Normal.y * CollisionData.m_Start.y + 
00492                                                                 pPlane->m_Normal.z * CollisionData.m_Start.z - 
00493                                                                 pPlane->m_Distance - CollisionData.m_MoveOffset;
00494                 float EndDistance   =   pPlane->m_Normal.x * CollisionData.m_End.x + 
00495                                                                 pPlane->m_Normal.y * CollisionData.m_End.y + 
00496                                                                 pPlane->m_Normal.z * CollisionData.m_End.z - 
00497                                                                 pPlane->m_Distance - CollisionData.m_MoveOffset;
00498 
00499                 // if the start point is in front this plane, then it can be IN the brush so it’s OUT
00500                 if( StartDistance > 0 )
00501                         StartsOut = true;
00502 
00503                 // if the end point is in front this plane, then it can be IN the brush so it’s OUT
00504                 if( EndDistance > 0 )
00505                         EndsOut = true;
00506 
00507                 // make sure the trace isn't completely on one side of the brush
00508                 if( StartDistance > 0 && EndDistance > 0 )
00509                 {   // both are in front of the plane, its outside of this brush
00510                         return;
00511                 }
00512 
00513                 if( StartDistance <= 0 && EndDistance <= 0 )
00514                 {   // both are behind this plane, it will get clipped by another one
00515                         continue;
00516                 }
00517 
00518 
00519                 // The line is Red so is entering the brush. 
00520                 // Compute the new S   (fraction)
00521                 // if (the new S) > S    move S  and update CandidateToHitNormal                
00522                                 
00523                 if( StartDistance > EndDistance )
00524                 {  
00525                         float Fraction = ( StartDistance - EPSILON ) / ( StartDistance - EndDistance );
00526                         if( Fraction > StartFraction)
00527                         {
00528                                 StartFraction = Fraction;
00529                                 CandidateToHitNormal = pPlane->m_Normal;
00530                         }
00531                 }
00532                 else
00533                         // The line is Black so is leaving the brush. 
00534                         // Compute the new E   (fraction)
00535                         // if (the new E) < E    move E
00536                 {   
00537                         float Fraction = ( StartDistance + EPSILON ) / ( StartDistance - EndDistance );
00538                         if( Fraction < EndFraction )
00539                                 EndFraction = Fraction;
00540                 }
00541         }
00542 
00543         // After checking all sides if startOut remain false, then the Start Point is complete in the brush
00544                 
00545         if( StartsOut == false )
00546         {
00547                 CollisionData.m_StartOut = false;
00548 
00549         // if also the EndPoint is in this brush, then the ray is complete in this brush
00550                 if( EndsOut == false )
00551                         CollisionData.m_AllSolid = true;
00552                 return;
00553         }
00554 
00555         // if there was collision against the brush (S < E)
00556         if( StartFraction < EndFraction )
00557         {
00558                 // And of course if we move S (if we don’t then we don’t enter the brush 
00559                 // and we don’t collide with some nearest brush
00560                 if( StartFraction > -1 && StartFraction < CollisionData.m_Fraction )
00561                 {
00562                         // UpDate OutPut values
00563 
00564                         if( StartFraction < 0 )
00565                                 StartFraction = 0;
00566 
00567                         CollisionData.m_Fraction                = StartFraction;
00568                         CollisionData.m_CollisionNormal = CandidateToHitNormal; // The candidate gets postulate!
00569                 }
00570         }
00571 }

Generated on Sun Mar 25 20:02:10 2007 for Zythum Project by  doxygen 1.5.1-p1