Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

TRACE.H File Reference

#include <Assert.h>
#include <Windows.h>
#include "Genesis.h"
#include "BaseType.h"
#include "Vec3d.h"
#include "World.h"

Go to the source code of this file.

Defines

#define PSIDE_FRONT   1
#define PSIDE_BACK   2
#define PSIDE_BOTH   (PSIDE_FRONT|PSIDE_BACK)
#define PSIDE_FACING   4

Functions

int32 Trace_BoxOnPlaneSide (const geVec3d *Mins, const geVec3d *Maxs, GFX_Plane *Plane)
geBoolean Trace_BBoxInVisibleLeaf (geWorld *World, geVec3d *Mins, geVec3d *Maxs)
geBoolean Trace_GEWorldCollision (geWorld *World, const geVec3d *Mins, const geVec3d *Maxs, const geVec3d *Front, const geVec3d *Back, uint32 Contents, uint32 CollideFlags, uint32 UserFlags, GE_CollisionCB *CollisionCB, void *Context, GE_Collision *Col)
geBoolean Trace_WorldCollisionBNode (geWorld *World, geVec3d *Front, geVec3d *Back, int32 *ModelNum, geVec3d *Impact, int32 *Node, int32 *Plane, int32 *Side)
geBoolean Trace_WorldCollisionExact (geWorld *World, const geVec3d *Front, const geVec3d *Back, uint32 Flags, geVec3d *Impact, GFX_Plane *Plane, geWorld_Model **Model, Mesh_RenderQ **Mesh, geActor **Actor, uint32 UserFlags, GE_CollisionCB *CollisionCB, void *Context)
geBoolean Trace_WorldCollisionExact2 (geWorld *World, const geVec3d *Front, const geVec3d *Back, geVec3d *Impact, int32 *Node, int32 *Plane, int32 *Side)
geBoolean Trace_MiscCollision (GFX_BNode *BNodes, GFX_Plane *Planes, const geVec3d *Mins, const geVec3d *Maxs, const geVec3d *Front, const geVec3d *Back, geXForm3d *XForm, geVec3d *I, GFX_Plane *P)
geBoolean Trace_MiscCollision2 (GFX_BNode *BNodes, GFX_Plane *Planes, const geVec3d *Front, const geVec3d *Back, geVec3d *I, int32 *P)
geBoolean Trace_WorldCollisionBBox (geWorld *World, const geVec3d *Mins, const geVec3d *Maxs, const geVec3d *Front, const geVec3d *Back, uint32 Flags, geVec3d *I, GFX_Plane *P, geWorld_Model **Model, Mesh_RenderQ **Mesh, geActor **Actor, uint32 UserFlags, GE_CollisionCB *CollisionCB, void *Context)
geBoolean Trace_TestModelMove (geWorld *World, geWorld_Model *Model, const geXForm3d *DXForm, const geVec3d *Mins, const geVec3d *Maxs, const geVec3d *In, geVec3d *Out)
geBoolean Trace_ModelCollision (geWorld *World, geWorld_Model *Model, const geXForm3d *DXForm, GE_Collision *Collision, geVec3d *ImpactPoint)
geBoolean Trace_InverseTreeFromBox (geVec3d *Mins, geVec3d *Maxs, GFX_BNode *BNodes, GFX_Plane *Planes)
geBoolean Trace_GetContents (geWorld *World, const geVec3d *Pos, const geVec3d *Mins, const geVec3d *Maxs, uint32 Flags, uint32 UserFlags, GE_CollisionCB *CollisionCB, void *Context, GE_Contents *Contents)
geBoolean Trace_GetTexureName (geWorld *World, const geVec3d *Pos, const geVec3d *Mins, const geVec3d *Maxs, char *TexName)
void Trace_GetMoveBox (const geVec3d *Mins, const geVec3d *Maxs, const geVec3d *Front, const geVec3d *Back, geVec3d *OMins, geVec3d *OMaxs)
void Trace_SetupIntersect (geWorld *World)
geBoolean Trace_IntersectWorldBSP (geVec3d *Front, geVec3d *Back, int32 Node)


Define Documentation

#define PSIDE_BACK   2
 

Definition at line 42 of file TRACE.H.

Referenced by BBoxInVisibleLeaf_r(), FillContents_r(), FillContents_tr(), FindClosestLeafIntersection_r(), gePuppet_RenderThroughFrustum(), and Trace_BoxOnPlaneSide().

#define PSIDE_BOTH   (PSIDE_FRONT|PSIDE_BACK)
 

Definition at line 43 of file TRACE.H.

#define PSIDE_FACING   4
 

Definition at line 44 of file TRACE.H.

#define PSIDE_FRONT   1
 

Definition at line 41 of file TRACE.H.

Referenced by BBoxInVisibleLeaf_r(), FillContents_r(), FillContents_tr(), FindClosestLeafIntersection_r(), gePuppet_RenderThroughFrustum(), and Trace_BoxOnPlaneSide().


Function Documentation

geBoolean Trace_BBoxInVisibleLeaf geWorld World,
geVec3d Mins,
geVec3d Maxs
 

Definition at line 1532 of file Trace.c.

References BBoxInVisibleLeaf_r(), World_BSP::BSPData, geWorld::CurrentBSP, FALSE, geBoolean, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, MiscNodes, MiscPlanes, and VisibleLeaf.

Referenced by ModelVisible().

01533 {
01534         VisibleLeaf = FALSE;
01535 
01536         MiscNodes = World->CurrentBSP->BSPData.GFXNodes;
01537         MiscPlanes = World->CurrentBSP->BSPData.GFXPlanes;
01538         
01539         BBoxInVisibleLeaf_r(World, Mins, Maxs, 0);
01540 
01541         return VisibleLeaf;
01542 }

int32 Trace_BoxOnPlaneSide const geVec3d Mins,
const geVec3d Maxs,
GFX_Plane Plane
 

Definition at line 755 of file Trace.c.

References GFX_Plane::Dist, geFloat, geVec3d_DotProduct(), int32, GFX_Plane::Normal, PLANE_ANYX, PSIDE_BACK, PSIDE_FRONT, GFX_Plane::Type, and VectorToSUB.

Referenced by BBoxInVisibleLeaf_r(), FillContents_r(), FillContents_tr(), FindClosestLeafIntersection_r(), and gePuppet_RenderThroughFrustum().

00756 {
00757         int32   Side;
00758         int32   i;
00759         geVec3d Corners[2];
00760         geFloat Dist1, Dist2;
00761 
00762         // Axial planes are easy
00763         if (Plane->Type < PLANE_ANYX)
00764         {
00765                 Side = 0;
00766                 if (VectorToSUB(*Maxs, Plane->Type) >= Plane->Dist)
00767                         Side |= PSIDE_FRONT;
00768                 if (VectorToSUB(*Mins, Plane->Type) < Plane->Dist)
00769                         Side |= PSIDE_BACK;
00770                 return Side;
00771         }
00772 
00773         // Create the proper leading and trailing verts for the box
00774         for (i=0 ; i<3 ; i++)
00775         {
00776                 if (VectorToSUB(Plane->Normal, i) < 0)
00777                 {
00778                         VectorToSUB(Corners[0], i) = VectorToSUB(*Mins, i);
00779                         VectorToSUB(Corners[1], i) = VectorToSUB(*Maxs, i);
00780                 }
00781                 else
00782                 {
00783                         VectorToSUB(Corners[1], i) = VectorToSUB(*Mins, i);
00784                         VectorToSUB(Corners[0], i) = VectorToSUB(*Maxs, i);
00785                 }
00786         }
00787 
00788         Dist1 = geVec3d_DotProduct(&Plane->Normal, &Corners[0]) - Plane->Dist;
00789         Dist2 = geVec3d_DotProduct(&Plane->Normal, &Corners[1]) - Plane->Dist;
00790         
00791         Side = 0;
00792         if (Dist1 >= 0)
00793                 Side = PSIDE_FRONT;
00794         if (Dist2 < 0)
00795                 Side |= PSIDE_BACK;
00796 
00797         return Side;
00798 }

geBoolean Trace_GetContents geWorld World,
const geVec3d Pos,
const geVec3d Mins,
const geVec3d Maxs,
uint32  Flags,
uint32  UserFlags,
GE_CollisionCB CollisionCB,
void *  Context,
GE_Contents Contents
 

Definition at line 1659 of file Trace.c.

References GE_Contents::Actor, World_Actor::Actor, geWorld::ActorArray, geWorld::ActorCount, World_BSP::BSPData, BSPData, GE_Contents::Contents, geWorld::CurrentBSP, FillContents_r(), World_Actor::Flags, GE_ACTOR_COLLIDE, GE_COLLIDE_ACTORS, GE_COLLIDE_MODELS, GE_COLLIDE_NO_SUB_MODELS, GE_CONTENTS_SOLID_CLIP, GE_FALSE, GE_TRUE, geActor_GetExtBox(), geBoolean, geMesh, geVec3d_Add(), geVec3d_GetElement(), geVec3d_Subtract(), geXForm3d_TransposeTransform(), GBSP_BSPData::GFXLeafs, GBSP_BSPData::GFXLeafSides, GBSP_BSPData::GFXModels, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, GMaxs1, GMaxs2, GMins1, GMins2, int32, geExtBox::Max, GE_Contents::Mesh, Mesh_RenderQ, geExtBox::Min, MiscLeafs, MiscNodes, MiscPlanes, MiscSides, GE_Contents::Model, World_BSP::Models, NULL, NumGetContents, GBSP_BSPData::NumGFXModels, geWorld_Model::RealCenter, GFX_Model::RootNode, geWorld_Model::TMaxs, geWorld_Model::TMins, uint32, World_Actor::UserFlags, VectorToSUB, and geWorld_Model::XForm.

Referenced by geWorld_GetContents().

01660 {
01661         Mesh_RenderQ                            *MeshHit;
01662         geActor                                         *ActorHit;
01663         geExtBox                                        MeshExtBox;
01664         geVec3d                                         TMins, TMaxs;
01665         geBoolean                                       Hit;
01666         int32                                           i, k;
01667         uint32                                          NewContents, FinalContents;
01668         geWorld_Model                           *Models, *ModelHit;
01669         GFX_Model                                       *GFXModels;
01670 
01671         assert(World);
01672         assert(Contents);
01673         
01674         MeshHit = NULL;
01675         ModelHit = NULL;
01676         FinalContents = 0;
01677         Hit = GE_FALSE;
01678 
01679         BSPData = &World->CurrentBSP->BSPData;
01680 
01681         // Get the translated box from the input pos...
01682         geVec3d_Add(Mins, Pos, &TMins);
01683         geVec3d_Add(Maxs, Pos, &TMaxs);
01684 
01685         NumGetContents++;
01686 
01687         if (Flags & GE_COLLIDE_ACTORS)
01688         {
01689                 int32 Count;
01690                 World_Actor *WA;
01691                         
01692                 Count = World->ActorCount;
01693                 WA = &(World->ActorArray[0]);
01694 
01695                 for (i=0; i<Count; i++, WA++)
01696                 {
01697                                 
01698                         // Reject if not active or if userflags don't accept...
01699                         if (!(WA->Flags & GE_ACTOR_COLLIDE) || !(WA->UserFlags & UserFlags) )
01700                                 continue;
01701 
01702                         if (CollisionCB && !CollisionCB(NULL, WA->Actor, Context))
01703                                 continue;
01704 
01705                                 
01706                         if (geActor_GetExtBox(WA->Actor,&MeshExtBox)==GE_FALSE)
01707                                 continue;
01708 
01709                         for (k=0; k<3; k++)
01710                         {
01711                                 if (geVec3d_GetElement(&TMaxs,k) < geVec3d_GetElement(&(MeshExtBox.Min),k)-1)
01712                                         break;
01713                                 if (geVec3d_GetElement(&TMins,k) > geVec3d_GetElement(&(MeshExtBox.Max),k)+1)
01714                                         break;
01715                         }
01716                                 
01717                         if (k != 3)
01718                                 continue;
01719 
01720                         ActorHit = WA->Actor;
01721                         Hit = GE_TRUE;
01722                         break;                          // Just return the first actor
01723                 }
01724         }
01725 
01726         if (!(Flags & GE_COLLIDE_MODELS))
01727                 goto NoModels;
01728         
01729         MiscNodes = World->CurrentBSP->BSPData.GFXNodes;
01730         MiscPlanes = World->CurrentBSP->BSPData.GFXPlanes;
01731         MiscLeafs = World->CurrentBSP->BSPData.GFXLeafs;
01732         MiscSides = BSPData->GFXLeafSides;
01733 
01734         Models = World->CurrentBSP->Models;
01735         GFXModels = World->CurrentBSP->BSPData.GFXModels;
01736 
01737         GMins1 = *Mins;
01738         GMaxs1 = *Maxs;
01739 
01740         GMins2 = TMins;
01741         GMaxs2 = TMaxs;
01742 
01743         for (i = 0; i < BSPData->NumGFXModels; i++, Models++, GFXModels++)
01744         {
01745                 geVec3d TPos;
01746 
01747                 if (CollisionCB && !CollisionCB(Models, NULL, Context))
01748                         continue;
01749 
01750                 if (i > 0)              // Ignore model 0 box (main world, we should always try to collide with world)
01751                 {
01752                         for (k=0; k<3; k++)
01753                         {
01754                                 if (VectorToSUB(TMaxs, k) < VectorToSUB(Models->TMins, k))
01755                                         break;
01756                                 if (VectorToSUB(TMins, k) > VectorToSUB(Models->TMaxs, k))
01757                                         break;
01758                         }
01759 
01760                         if (k != 3)                     // Couldn't possibly hit if box's don't hit...
01761                                 continue;
01762                 }
01763 
01764                 geVec3d_Subtract(Pos, &Models->RealCenter, &TPos);
01765 
01766                 // InverseTransform the point about models center of rotation
01767                 geXForm3d_TransposeTransform(&Models->XForm, &TPos, &TPos);
01768 
01769                 // push back into world
01770 
01771                 geVec3d_Add(&TPos, &Models->RealCenter, &TPos);
01772 
01773                 // Reset contents
01774                 NewContents = 0;
01775 
01776                 FillContents_r(GFXModels->RootNode[0], &TPos, &NewContents);
01777 
01778                 if (NewContents && !ModelHit)
01779                 {
01780                         ModelHit = Models;                                              // First model hit for any arbritrary contents
01781                         Hit = GE_TRUE;
01782                 }
01783 
01784                 if (NewContents & GE_CONTENTS_SOLID_CLIP)       // Solid has precedence
01785                 {
01786                         ModelHit = Models;
01787                 }
01788 
01789                 // Or final contents with this new contents
01790                 FinalContents |= NewContents;
01791 
01792                 if ((Flags & GE_COLLIDE_NO_SUB_MODELS))
01793                         goto NoModels;
01794         }
01795 
01796         NoModels:
01797 
01798         if (Hit)
01799         {
01800                 Contents->Contents = FinalContents;
01801                 Contents->Mesh = (geMesh*)MeshHit;
01802                 Contents->Model = ModelHit;
01803                 Contents->Actor = ActorHit;
01804                 return GE_TRUE;
01805         }
01806 
01807         // If nothing occupied, then make sure the return structure is cleared for cleanness
01808         memset(Contents, 0, sizeof(GE_Contents));
01809 
01810         return GE_FALSE;
01811 }

void Trace_GetMoveBox const geVec3d Mins,
const geVec3d Maxs,
const geVec3d Front,
const geVec3d Back,
geVec3d OMins,
geVec3d OMaxs
 

Definition at line 1476 of file Trace.c.

References int32, and VectorToSUB.

Referenced by Trace_ActorCollide(), Trace_ModelCollisionBBox(), Trace_TestModelMove(), Trace_WorldCollisionBBox(), and Trace_WorldCollisionExact().

01477 {
01478         int32           i;
01479 
01480         assert(Mins);
01481         assert(Maxs);
01482         assert(Front);
01483         assert(Back);
01484         
01485         for (i=0 ; i<3 ; i++)
01486         {
01487                 if (VectorToSUB(*Back, i) > VectorToSUB(*Front, i))
01488                 {
01489                         VectorToSUB(*OMins, i) = VectorToSUB(*Front, i) + VectorToSUB(*Mins, i) - 1.0f;
01490                         VectorToSUB(*OMaxs, i) = VectorToSUB(*Back, i) + VectorToSUB(*Maxs, i) + 1.0f;
01491                 }
01492                 else
01493                 {
01494                         VectorToSUB(*OMins, i) = VectorToSUB(*Back, i) + VectorToSUB(*Mins, i) - 1.0f;
01495                         VectorToSUB(*OMaxs, i) = VectorToSUB(*Front, i) + VectorToSUB(*Maxs, i) + 1.0f;
01496                 }
01497         }
01498 }

geBoolean Trace_GetTexureName geWorld World,
const geVec3d Pos,
const geVec3d Mins,
const geVec3d Maxs,
char *  TexName
 

Definition at line 2282 of file Trace.c.

References World_BSP::BSPData, BSPData, geWorld::CurrentBSP, FillContents_tr(), GE_FALSE, GE_TRUE, geBoolean, geVec3d_Add(), geVec3d_Subtract(), geXForm3d_TransposeTransform(), GBSP_BSPData::GFXLeafs, GBSP_BSPData::GFXLeafSides, GBSP_BSPData::GFXModels, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, GMaxs1, GMaxs2, GMins1, GMins2, int32, MiscLeafs, MiscNodes, MiscPlanes, MiscSides, World_BSP::Models, NULL, GBSP_BSPData::NumGFXModels, geWorld_Model::RealCenter, GFX_Model::RootNode, geWorld_Model::TMaxs, geWorld_Model::TMins, VectorToSUB, and geWorld_Model::XForm.

Referenced by geWorld_GetTextureName().

02283 {
02284         geVec3d                                         TMins, TMaxs;
02285         geBoolean                                       Hit;
02286         int32                                           i, k;
02287         geWorld_Model                           *Models, *ModelHit;
02288         GFX_Model                                       *GFXModels;
02289 
02290         assert(World);
02291         
02292         ModelHit = NULL;
02293         Hit = GE_FALSE;
02294 
02295         BSPData = &World->CurrentBSP->BSPData;
02296 
02297         // Get the translated box from the input pos...
02298         geVec3d_Add(Mins, Pos, &TMins);
02299         geVec3d_Add(Maxs, Pos, &TMaxs);
02300 
02301         MiscNodes = World->CurrentBSP->BSPData.GFXNodes;
02302         MiscPlanes = World->CurrentBSP->BSPData.GFXPlanes;
02303         MiscLeafs = World->CurrentBSP->BSPData.GFXLeafs;
02304         MiscSides = BSPData->GFXLeafSides;
02305 
02306         Models = World->CurrentBSP->Models;
02307         GFXModels = World->CurrentBSP->BSPData.GFXModels;
02308 
02309         GMins1 = *Mins;
02310         GMaxs1 = *Maxs;
02311 
02312         GMins2 = TMins;
02313         GMaxs2 = TMaxs;
02314 
02315         for (i = 0; i < BSPData->NumGFXModels; i++, Models++, GFXModels++)
02316         {
02317                 geVec3d TPos;
02318 
02319                 if (i > 0)              // Ignore model 0 box (main world, we should always try to collide with world)
02320                 {
02321                         for (k=0; k<3; k++)
02322                         {
02323                                 if (VectorToSUB(TMaxs, k) < VectorToSUB(Models->TMins, k))
02324                                         break;
02325                                 if (VectorToSUB(TMins, k) > VectorToSUB(Models->TMaxs, k))
02326                                         break;
02327                         }
02328 
02329                         if (k != 3)                     // Couldn't possibly hit if box's don't hit...
02330                                 continue;
02331                 }
02332 
02333                 geVec3d_Subtract(Pos, &Models->RealCenter, &TPos);
02334 
02335                 // InverseTransform the point about models center of rotation
02336                 geXForm3d_TransposeTransform(&Models->XForm, &TPos, &TPos);
02337 
02338                 // push back into world
02339 
02340                 geVec3d_Add(&TPos, &Models->RealCenter, &TPos);
02341 
02342                 FillContents_tr(World, GFXModels->RootNode[0], &TPos, TexName);
02343 
02344                 if (!ModelHit)
02345                 {
02346                         ModelHit = Models;                                              // First model hit for any arbritrary contents
02347                         Hit = GE_TRUE;
02348                 }
02349         }
02350 
02351         if (Hit)
02352         {
02353                 return GE_TRUE;
02354         }
02355 
02356         return GE_FALSE;
02357 }

geBoolean Trace_GEWorldCollision geWorld World,
const geVec3d Mins,
const geVec3d Maxs,
const geVec3d Front,
const geVec3d Back,
uint32  Contents,
uint32  CollideFlags,
uint32  UserFlags,
GE_CollisionCB CollisionCB,
void *  Context,
GE_Collision Col
 

Definition at line 165 of file Trace.c.

References GE_Collision::Actor, World_BSP::BSPData, BSPData, geWorld::CurrentBSP, GFX_Plane::Dist, GE_Plane::Dist, gContents, GE_FALSE, GE_TRUE, geBoolean, geMesh, GRatio, GE_Collision::Impact, GE_Collision::Mesh, Mesh_RenderQ, GE_Collision::Model, GFX_Plane::Normal, GE_Plane::Normal, NULL, NumBBoxCast, NumExactCast, GE_Collision::Plane, GE_Collision::Ratio, Trace_WorldCollisionBBox(), and Trace_WorldCollisionExact().

Referenced by gePuppet_DrawShadow(), geSound3D_GetConfig(), geWorld_Collision(), and Trace_TestModelMove().

00166 {
00167         geVec3d         I;
00168         GFX_Plane       Plane;
00169         geWorld_Model   *Model;
00170         Mesh_RenderQ    *Mesh;
00171         geActor     *Actor;
00172 
00173         assert(World != NULL);
00174         assert(World->CurrentBSP != NULL);
00175         assert(Front != NULL);
00176         assert(Back!= NULL);
00177         assert(Contents);                       // It does not make sense to collide with nothing!!!
00178         
00179         // Set the global contents to collide with
00180         gContents = Contents;
00181 
00182         BSPData = &World->CurrentBSP->BSPData;
00183 
00184         // Reset all the collision feedback pointers
00185         Model = NULL;
00186         Mesh = NULL;
00187         Actor = NULL;
00188 
00189         Col->Model = NULL;
00190         Col->Mesh = NULL;
00191         Col->Actor = NULL;
00192 
00193         if (Mins && Maxs)
00194         {
00195                 NumBBoxCast++;
00196                 if (Trace_WorldCollisionBBox(World, Mins, Maxs, Front, Back, CollideFlags, &I, &Plane, &Model, &Mesh, &Actor, UserFlags, CollisionCB, Context))
00197                 {
00198                         
00199                         Col->Impact = I;
00200                         Col->Plane.Normal =     Plane.Normal;
00201                         Col->Plane.Dist = Plane.Dist;
00202                         
00203                         Col->Model = Model;
00204                         Col->Mesh = (geMesh*)Mesh;
00205                         Col->Actor = Actor;
00206 
00207                         Col->Ratio = GRatio;
00208                         return GE_TRUE;
00209                 }
00210         }
00211         else 
00212         {
00213                 NumExactCast++;
00214 
00215                 if (Trace_WorldCollisionExact(World, Front, Back, CollideFlags, &I, &Plane, &Model, &Mesh, &Actor, UserFlags, CollisionCB, Context))
00216                 {
00217                         Col->Impact = I;
00218                         Col->Plane.Normal = Plane.Normal;
00219                         Col->Plane.Dist = Plane.Dist;
00220 
00221                         Col->Model = Model;
00222                         Col->Mesh = (geMesh*)Mesh;
00223                         Col->Actor = Actor;
00224 
00225                         Col->Ratio = GRatio;
00226 
00227                         return GE_TRUE;
00228                 }
00229         }
00230         return GE_FALSE;
00231 }

geBoolean Trace_IntersectWorldBSP geVec3d Front,
geVec3d Back,
int32  Node
 

Definition at line 1835 of file Trace.c.

References BSPIntersect(), GFX_Leaf::Contents, gContents, GE_CONTENTS_SOLID_CLIP, GE_FALSE, GE_TRUE, geBoolean, geFloat, int32, Plane_PlaneDistanceFast(), GFX_Node::PlaneNum, TreeLeafs, TreeNodes, TreePlanes, geVec3d::X, geVec3d::Y, and geVec3d::Z.

Referenced by CombineDLightWithRGBMapWithShadow().

01836 {
01837     geFloat             Fd, Bd, Dist;
01838     int32               Side;
01839     geVec3d             I;
01840         GFX_Plane       *Plane;
01841         int32           Contents;
01842 
01843         gContents = GE_CONTENTS_SOLID_CLIP;
01844 
01845         if (Node < 0)
01846         {
01847                 Contents = TreeLeafs[-(Node+1)].Contents;
01848 
01849                 if (Contents & gContents)
01850                     return GE_TRUE;                                             // Ray collided with solid space
01851                 return GE_FALSE;
01852         }
01853 
01854         Plane = &TreePlanes[TreeNodes[Node].PlaneNum];
01855 
01856     Fd = Plane_PlaneDistanceFast(Plane, Front);
01857     Bd = Plane_PlaneDistanceFast(Plane, Back);
01858 
01859     if (Fd >= 0 && Bd >= 0) 
01860         return(BSPIntersect(Front, Back, TreeNodes[Node].Children[0]));
01861     if (Fd < 0 && Bd < 0)
01862         return(BSPIntersect(Front, Back, TreeNodes[Node].Children[1]));
01863 
01864     Side = Fd < 0;
01865     Dist = Fd / (Fd - Bd);
01866 
01867     I.X = Front->X + Dist * (Back->X - Front->X);
01868     I.Y = Front->Y + Dist * (Back->Y - Front->Y);
01869     I.Z = Front->Z + Dist * (Back->Z - Front->Z);
01870 
01871     // Work our way to the front, from the back side.  As soon as there
01872         // is no more collisions, we can assume that we have the front portion of the
01873         // ray that is in empty space.  Once we find this, and see that the back half is in
01874         // solid space, then we found the front intersection point...
01875         if (BSPIntersect(Front, &I, TreeNodes[Node].Children[Side]))
01876         return GE_TRUE;
01877     else if (BSPIntersect(&I, Back, TreeNodes[Node].Children[!Side]))
01878         {
01879                 return GE_TRUE;
01880         }
01881 
01882         return GE_FALSE;
01883 }

geBoolean Trace_InverseTreeFromBox geVec3d Mins,
geVec3d Maxs,
GFX_BNode BNodes,
GFX_Plane Planes
 

Definition at line 1548 of file Trace.c.

References BSP_CONTENTS_EMPTY, BSP_CONTENTS_SOLID, GFX_BNode::Children, GFX_Plane::Dist, GE_TRUE, geBoolean, geFloat, int32, GFX_Plane::Normal, PLANE_ANY, GFX_BNode::PlaneNum, GFX_Plane::Type, and VectorToSUB.

01549 {
01550         int32           i,j,n;
01551         geFloat         Bounds[2][3];
01552         GFX_Plane       *Plane;
01553 
01554         for (i=0; i< 3; i++)
01555         {
01556                 Bounds[0][i] = VectorToSUB(*Mins, i);
01557                 Bounds[1][i] = VectorToSUB(*Maxs, i);
01558         }
01559 
01560         // Build the boxs planes
01561         for (i=0; i< 3; i++)
01562         {
01563                 for (j=0; j< 2; j++)
01564                 {
01565                         n = j*3 + i;
01566                         
01567                         Plane = &Planes[n];
01568 
01569                         memset(Plane, 0, sizeof(GFX_Plane));
01570 
01571                         if (!j)         // Inside out
01572                         {
01573                                 VectorToSUB(Plane->Normal, i) = 1.0f;
01574                                 Plane->Dist = Bounds[j][i];
01575                         }
01576                         else
01577                         {
01578                                 VectorToSUB(Plane->Normal, i) = -1.0f;
01579                                 Plane->Dist = -Bounds[j][i];
01580                         }
01581 
01582                         Plane->Type = PLANE_ANY;
01583 
01584                         //
01585                         // Build the tree
01586                         //
01587                         BNodes[n].PlaneNum = n;
01588 
01589                         BNodes[n].Children[1] = BSP_CONTENTS_SOLID;
01590                         
01591                         if (n == 5)             
01592                                 BNodes[n].Children[0] = BSP_CONTENTS_EMPTY;
01593                         else            
01594                                 BNodes[n].Children[0] = n+1;
01595                 }
01596         }
01597         
01598         return GE_TRUE;
01599 }

geBoolean Trace_MiscCollision GFX_BNode BNodes,
GFX_Plane Planes,
const geVec3d Mins,
const geVec3d Maxs,
const geVec3d Front,
const geVec3d Back,
geXForm3d XForm,
geVec3d I,
GFX_Plane P
 

Definition at line 614 of file Trace.c.

References BSPIntersectMisc(), GFX_Plane::Dist, FALSE, GE_FALSE, GE_TRUE, geBoolean, geVec3d_Add(), geVec3d_DotProduct(), geVec3d_Subtract(), GlobalI, GlobalPlane, GMaxs1, GMins1, GPlaneNum, HitSet, MiscBNodes, MiscPlanes, GFX_Plane::Normal, geXForm3d::Translation, TRUE, UseMinsMaxs, geVec3d::X, geVec3d::Y, and geVec3d::Z.

00615 {
00616         geVec3d NewFront, NewBack;
00617         geVec3d Trans;
00618 
00619         GPlaneNum       =       -1;             //Safeguard to prevent a bad index 
00620 
00621         // Set Global misc vars
00622         MiscBNodes = BNodes;
00623         MiscPlanes = Planes;
00624 
00625         if (Mins && Maxs)
00626         {
00627                 GMins1 = *Mins;
00628                 GMaxs1 = *Maxs;
00629                 UseMinsMaxs = TRUE;
00630         }
00631         else
00632                 UseMinsMaxs = FALSE;
00633         
00634         // Move ray into tree space
00635         Trans.X = XForm->Translation.X;
00636         Trans.Y = XForm->Translation.Y;
00637         Trans.Z = XForm->Translation.Z;
00638 
00639         geVec3d_Subtract(Front, &Trans, &NewFront);
00640         geVec3d_Subtract(Back, &Trans, &NewBack);
00641         
00642         HitSet = FALSE;
00643         
00644         if (BSPIntersectMisc(&NewFront, &NewBack, 0))
00645         {
00646                 if (!HitSet)                                    // Was in solid, but did not cross any planes...
00647                         return GE_FALSE;                        // So just return false...
00648 
00649                 geVec3d_Add(&GlobalI, &Trans, &GlobalI);
00650 
00651                 if (I) *I = GlobalI;                    // Set the intersection point
00652                 if (P)
00653                 { 
00654                         *P = GlobalPlane;
00655                         // Adjust so plane is at impact point
00656                         P->Dist += geVec3d_DotProduct(&Trans, &P->Normal);
00657                 }
00658 
00659                 return GE_TRUE;
00660         }
00661 
00662         return GE_FALSE;
00663 }

geBoolean Trace_MiscCollision2 GFX_BNode BNodes,
GFX_Plane Planes,
const geVec3d Front,
const geVec3d Back,
geVec3d I,
int32 P
 

Definition at line 724 of file Trace.c.

References BSPIntersectMisc2(), FALSE, GE_FALSE, GE_TRUE, geBoolean, GlobalI, GPlaneNum, HitSet, MiscBNodes, and MiscPlanes.

00725 {
00726         GPlaneNum       =       -1;             //Safeguard to prevent a bad index 
00727 
00728         // Set Global misc vars
00729         MiscBNodes = BNodes;
00730         MiscPlanes = Planes;
00731 
00732         HitSet = FALSE;
00733         
00734         if (BSPIntersectMisc2(Front, Back, 0))
00735         {
00736                 if (!HitSet || GPlaneNum == -1) // Was in solid, but did not cross any planes...
00737                         return GE_FALSE;                        // So just return false...
00738 
00739                 if (I) 
00740                         *I = GlobalI;                           // Set the intersection point
00741                 if (P)
00742                         *P = GPlaneNum;
00743 
00744                 return GE_TRUE;
00745         }
00746 
00747         return GE_FALSE;
00748 }

geBoolean Trace_ModelCollision geWorld World,
geWorld_Model Model,
const geXForm3d DXForm,
GE_Collision Collision,
geVec3d ImpactPoint
 

Definition at line 1383 of file Trace.c.

References GE_Collision::Actor, World_Actor::Actor, geWorld::ActorArray, geWorld::ActorCount, GE_Plane::Dist, GFX_Plane::Dist, World_Actor::Flags, gContents, GE_ACTOR_COLLIDE, GE_CONTENTS_SOLID_CLIP, GE_FALSE, GE_TRUE, geActor_GetBoneTransform(), geActor_GetNonWorldExtBox(), geActor_GetPosition(), geBoolean, geFloat, geMesh, geVec3d_Copy(), geVec3d_DistanceBetween(), geVec3d_Subtract(), GlobalPlane, geExtBox::Max, GE_Collision::Mesh, Mesh_RenderQ, geExtBox::Min, GFX_Plane::Normal, GE_Plane::Normal, NULL, GE_Collision::Plane, GE_Collision::Ratio, Trace_ModelCollisionBBox(), geXForm3d::Translation, and geWorld_Model::XForm.

Referenced by geWorld_ModelCollision().

01388 {
01389         geExtBox ExtBox;
01390         geVec3d Pos;
01391         geXForm3d myXForm;
01392 #ifdef MESHES
01393         Mesh_RenderQ * CollidableMesh;
01394         Mesh_CollidableMeshIterator Iter;
01395 #endif
01396   gContents = GE_CONTENTS_SOLID_CLIP;           // eaa3 from G3D BBS posting 01/29/2001
01397         memset(Collision, 0, sizeof(GE_Collision));
01398         // Fixed bug that mike pointed out. I was using 0, instead of 0xffffffff
01399 #ifdef MESHES
01400         CollidableMesh = Mesh_FirstCollidableMesh(World, &Iter, 0xffffffff);
01401         while (CollidableMesh)
01402         {
01403                 Mesh_MeshGetBox(World, CollidableMesh->MeshDef, &Mins, &Maxs);
01404                 Mesh_MeshGetPosition(CollidableMesh, &Pos);
01405                 if (Trace_ModelCollisionBBox(World, Model, DXForm, &Mins, &Maxs, &Pos, ImpactPoint))
01406                 {
01407                         Collision->Mesh = (geMesh *)CollidableMesh;
01408                         return GE_TRUE;
01409                 }
01410                 CollidableMesh = Mesh_NextCollidableMesh(&Iter, 0xffffffff);
01411         }
01412 #endif
01413         {
01414                 int i,Count;
01415                 World_Actor *WA;
01416                 //MRB BEGIN
01417                 geActor *BestActor;
01418                 geFloat BestActorDist;
01419                 geVec3d PossibleImpactPoint;
01420                 BestActor = NULL;
01421                 BestActorDist = 9999.0f;
01422                 //MRB END
01423                 
01424                 Count = World->ActorCount;
01425                 WA = &(World->ActorArray[0]);
01426                 for (i=0; i < Count; i++, WA++)
01427                 {
01428                         // if it's active (ignore userflags?)
01429                         if ( (WA->Flags & GE_ACTOR_COLLIDE) ) 
01430                         {
01431                                 //MRB BEGIN
01432                                 // if (geActor_GetExtBox(WA->Actor,&ExtBox)!=GE_FALSE)
01433                                 // {
01434                                 geActor_GetNonWorldExtBox(WA->Actor,&ExtBox);
01435                                 geActor_GetPosition(WA->Actor, &Pos);
01436                                 // eaa3 from posting on G3D message board 01/29/2001
01437                                 geActor_GetBoneTransform(WA->Actor, NULL, &myXForm);
01438                                 geVec3d_Copy(&myXForm.Translation, &Pos);
01439                                 geVec3d_Subtract(&ExtBox.Min, &Pos, &ExtBox.Min);
01440                                 geVec3d_Subtract(&ExtBox.Max, &Pos, &ExtBox.Max);
01441                                 // end eaa3 01/29/2001
01442                                 // if (Trace_ModelCollisionBBox(World, Model, DXForm, &(ExtBox.Min), &(ExtBox.Max), &Pos, ImpactPoint))
01443                                 if (Trace_ModelCollisionBBox(World, Model, DXForm, &(ExtBox.Min), &(ExtBox.Max), &Pos, &PossibleImpactPoint))
01444                                 {
01445                                         // Collision->Actor = WA->Actor;
01446                                         if (GlobalPlane.Dist < BestActorDist)
01447                                         {
01448                                                 BestActorDist = GlobalPlane.Dist;
01449                                                 BestActor = WA->Actor;
01450                                                 (*ImpactPoint) = PossibleImpactPoint;
01451                                                 Collision->Plane.Normal = GlobalPlane.Normal;
01452                                                 Collision->Plane.Dist = GlobalPlane.Dist;
01453                                                 Collision->Ratio = geVec3d_DistanceBetween(&DXForm->Translation, &Model->XForm.Translation);
01454                                         }
01455                                         // return GE_TRUE;
01456                                 }
01457                                 // }
01458                                 //MRB END
01459                         }
01460                 }
01461                 //MRB BEGIN
01462                 if (BestActor) {
01463                         Collision->Actor = BestActor;
01464                         return GE_TRUE;
01465                 }
01466                 //MRB END
01467         }
01468         return GE_FALSE;
01469 }

void Trace_SetupIntersect geWorld World  ) 
 

Definition at line 1822 of file Trace.c.

References World_BSP::BSPData, BSPData, geWorld::CurrentBSP, GBSP_BSPData::GFXLeafs, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, TreeLeafs, TreeNodes, and TreePlanes.

Referenced by CombineDLightWithRGBMapWithShadow().

01823 {
01824         BSPData = &World->CurrentBSP->BSPData;
01825 
01826         TreePlanes = BSPData->GFXPlanes;
01827         TreeNodes = BSPData->GFXNodes;
01828         TreeLeafs = BSPData->GFXLeafs;
01829 }

geBoolean Trace_TestModelMove geWorld World,
geWorld_Model Model,
const geXForm3d DXForm,
const geVec3d Mins,
const geVec3d Maxs,
const geVec3d In,
geVec3d Out
 

Definition at line 1225 of file Trace.c.

References BestDist, World_BSP::BSPData, BSPData, geWorld::CurrentBSP, GFX_Plane::Dist, FALSE, FindClosestLeafIntersection_r(), GBack, GE_COLLIDE_ALL, GE_CONTENTS_SOLID_CLIP, GE_FALSE, GE_TRUE, geBoolean, geVec3d_Add(), geVec3d_DotProduct(), geVec3d_MA(), geVec3d_Subtract(), geXForm3d_Rotate(), geXForm3d_Transform(), geXForm3d_TransposeTransform(), GFront, GBSP_BSPData::GFXLeafs, GBSP_BSPData::GFXLeafSides, geWorld_Model::GFXModelNum, GBSP_BSPData::GFXModels, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, GlobalI, GlobalPlane, GMaxs1, GMaxs2, GMins1, GMins2, LeafHit, MiscLeafs, MiscNodes, MiscPlanes, MiscSides, GFX_Plane::Normal, NULL, ON_EPSILON, geWorld_Model::Pivot, Trace_GetMoveBox(), Trace_GEWorldCollision(), and geWorld_Model::XForm.

Referenced by geWorld_TestModelMove().

01230 {
01231         geVec3d         NewFront, NewBack, Original;
01232 
01233         assert(World != NULL);
01234         assert(Model != NULL);
01235 
01236         BSPData = &World->CurrentBSP->BSPData;
01237 
01238         MiscNodes = BSPData->GFXNodes;
01239         MiscPlanes = BSPData->GFXPlanes;
01240         MiscLeafs = BSPData->GFXLeafs;
01241         MiscSides = BSPData->GFXLeafSides;
01242 
01243         assert(MiscNodes != NULL);
01244         assert(MiscPlanes != NULL);
01245         assert(MiscLeafs != NULL);
01246         assert(MiscSides != NULL);
01247 
01248         Original = *In;         // Save original
01249 
01250         GMins1 = *Mins;
01251         GMaxs1 = *Maxs;
01252         
01253         // Put point about models origin
01254         geVec3d_Subtract(In, &Model->Pivot, &GFront);
01255         GBack = GFront;
01256 
01257         // InverseTransform the points about models center of rotation
01258         geXForm3d_TransposeTransform(&Model->XForm, &GFront, &NewFront);
01259         // The back gets applied by the dest XForm
01260         geXForm3d_TransposeTransform(DXForm, &GBack, &NewBack);
01261 
01262         // push back into world
01263         geVec3d_Add(&NewFront, &Model->Pivot, &GFront);
01264         geVec3d_Add(&NewBack , &Model->Pivot, &GBack);
01265 
01266         // Make out box out of this move so we only check the leafs it intersected with...
01267         Trace_GetMoveBox(Mins, Maxs, &GFront, &GBack, &GMins2, &GMaxs2);
01268         
01269         BestDist = 9999.0f;
01270         LeafHit = FALSE;
01271 
01272         FindClosestLeafIntersection_r(BSPData->GFXModels[Model->GFXModelNum].RootNode[0]);
01273 
01274         if (LeafHit)
01275         {
01276                 GE_Collision    Collision;
01277 
01278                 // Rotate the impact plane
01279                 geXForm3d_Rotate(DXForm, &GlobalPlane.Normal, &GlobalPlane.Normal);
01280                         
01281                 // Rotate the impact point
01282                 geVec3d_Subtract(&GlobalI, &Model->Pivot, &NewFront);
01283                 geXForm3d_Transform(DXForm, &NewFront, &GlobalI);
01284                 geVec3d_Add(&GlobalI, &Model->Pivot, &NewFront);
01285                 GlobalI = NewFront;
01286 
01287                 // Find the new plane distance based on the new impact point with the new plane
01288                 GlobalPlane.Dist = geVec3d_DotProduct(&GlobalPlane.Normal, &GlobalI);
01289 
01290                 geVec3d_MA(&GlobalI, ON_EPSILON, &GlobalPlane.Normal, &GlobalI);
01291                 
01292                 // If the point gets pushed into the world as a result of the move, then cancel it out...
01293                 if (Trace_GEWorldCollision(World, Mins, Maxs, In, &GlobalI, GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_ALL, 0xffffffff, NULL, NULL, &Collision))
01294                 {
01295                         *Out = Original;
01296                         return GE_FALSE;
01297                 }
01298 
01299                 *Out = GlobalI;
01300 
01301                 return GE_TRUE;
01302         }
01303 
01304         *Out = Original;
01305 
01306         return GE_TRUE;
01307 }

geBoolean Trace_WorldCollisionBBox geWorld World,
const geVec3d Mins,
const geVec3d Maxs,
const geVec3d Front,
const geVec3d Back,
uint32  Flags,
geVec3d I,
GFX_Plane P,
geWorld_Model **  Model,
Mesh_RenderQ **  Mesh,
geActor **  Actor,
uint32  UserFlags,
GE_CollisionCB CollisionCB,
void *  Context
 

Definition at line 1028 of file Trace.c.

References BestDist, World_BSP::BSPData, BSPData, geWorld::CurrentBSP, GFX_Plane::Dist, FALSE, FindClosestLeafIntersection_r(), GBack, GE_COLLIDE_ACTORS, GE_COLLIDE_MESHES, GE_COLLIDE_MODELS, GE_COLLIDE_NO_SUB_MODELS, GE_FALSE, GE_TRUE, geBoolean, geFloat, geVec3d_Add(), geVec3d_DotProduct(), geVec3d_Length(), geVec3d_Subtract(), geXForm3d_Rotate(), geXForm3d_Transform(), geXForm3d_TransposeTransform(), GFront, GBSP_BSPData::GFXLeafs, GBSP_BSPData::GFXLeafSides, GBSP_BSPData::GFXModels, GBSP_BSPData::GFXNodes, GBSP_BSPData::GFXPlanes, GlobalI, GlobalPlane, GMaxs1, GMaxs2, GMins1, GMins2, int32, LeafHit, Mesh_RenderQ, MiscLeafs, MiscNodes, MiscPlanes, MiscSides, World_BSP::Models, GFX_Plane::Normal, NULL, GBSP_BSPData::NumGFXModels, geWorld_Model::Pivot, GFX_Model::RootNode, geWorld_Model::TMaxs, geWorld_Model::TMins, Trace_ActorCollide(), Trace_GetMoveBox(), VectorToSUB, and geWorld_Model::XForm.

Referenced by Trace_GEWorldCollision().

01039 {
01040         geWorld_Model   *Models;
01041         geVec3d                 NewFront, NewBack, OMins, OMaxs, BestI, Vect;
01042         geVec3d                 Impact;
01043         int32                   i, b;
01044         geFloat                 Dist, BestD;
01045         Mesh_RenderQ    *BestMesh;
01046         #ifdef MESHES
01047         Mesh_RenderQ    *Mesh2;
01048         #endif
01049         geActor                 *BestActor;
01050         geWorld_Model   *BestModel;
01051         GFX_Plane               BestPlane, Plane2;
01052         geBoolean               Hit;
01053 
01054         if (Model)
01055                 *Model = NULL;
01056         if (Mesh)
01057                 *Mesh = NULL;
01058         if (Actor)
01059                 *Actor = NULL;
01060 
01061         BestD = 99999.0f;
01062         BestMesh = NULL;
01063         BestModel = NULL;
01064         BestActor = NULL;
01065         Hit = GE_FALSE;                         // Have not hit nothing yet...
01066         
01067         // Test meshes first... (record the closest collision)
01068         if (Flags & GE_COLLIDE_MESHES)
01069         {
01070 #ifdef  MESHES
01071                 if (Mesh_MeshCollisionAll(World, Mins, Maxs, Front, Back, &Impact, &Plane2, &Mesh2, UserFlags))
01072                 {
01073                         geVec3d_Subtract(&Impact, Front, &Vect);
01074                         Dist = geVec3d_Length(&Vect);
01075                         if (Dist < BestD)
01076                         {
01077                                 BestD = Dist;
01078                                 BestI = Impact;
01079                                 BestMesh = Mesh2;
01080                                 BestPlane = Plane2;
01081                                 Hit = GE_TRUE;                  // We hit somthing
01082                         }
01083                 }
01084 #endif
01085         }
01086 
01087         
01088         if (Flags & GE_COLLIDE_ACTORS)
01089                 {
01090                         BestActor = Trace_ActorCollide(World, Mins,Maxs, Front,Back,&Impact,&Plane2,UserFlags, CollisionCB, Context, &BestD);
01091                         if (BestActor != NULL)
01092                                 {
01093                                         BestI = Impact;
01094                                         BestPlane = Plane2;
01095                                         Hit = GE_TRUE;
01096                                 }
01097                 }
01098 
01099         
01100         // GMins1/GMaxs1 is what is used to exapand the plane out with
01101         GMins1 = *Mins;
01102         GMaxs1 = *Maxs;
01103         
01104         GFront = *Front;
01105         GBack = *Back;
01106 
01107         BSPData = &World->CurrentBSP->BSPData;
01108         Models = World->CurrentBSP->Models;
01109 
01110         MiscNodes = BSPData->GFXNodes;
01111         MiscPlanes = BSPData->GFXPlanes;
01112         MiscLeafs = BSPData->GFXLeafs;
01113         MiscSides = BSPData->GFXLeafSides;
01114 
01115         assert(MiscNodes != NULL);
01116         assert(MiscPlanes != NULL);
01117         assert(MiscLeafs != NULL);
01118         assert(MiscSides != NULL);
01119 
01120         if (!(Flags & GE_COLLIDE_MODELS))
01121                 goto NoModels;
01122         
01123         Trace_GetMoveBox(Mins, Maxs, Front, Back, &OMins, &OMaxs);
01124 
01125         // Then test the world bsp(all models are the world bsp)
01126         // Go through each model, and find out what leafs we hit, keeping the closest intersection
01127         for (i = 0; i < BSPData->NumGFXModels; i++, Models++)
01128         {
01129                 
01130                 // First, see if the user wants to reject it...
01131                 if (CollisionCB && !CollisionCB(Models, NULL, Context))
01132                         continue;
01133 
01134                 for (b=0; b<3; b++)
01135                 {
01136                         if (VectorToSUB(OMaxs, b) < VectorToSUB(Models->TMins, b))
01137                                 break;
01138                         if (VectorToSUB(OMins, b) > VectorToSUB(Models->TMaxs, b))
01139                                 break;
01140                 }
01141 
01142                 if (b != 3)
01143                         continue;
01144                 
01145 
01146                 // Reset flags
01147                 BestDist = 9999.0f;
01148                 LeafHit = FALSE;
01149                 
01150                 geVec3d_Subtract(Front, &Models->Pivot, &GFront);
01151                 geVec3d_Subtract(Back , &Models->Pivot, &GBack);
01152 
01153                 // InverseTransform the point about models center of rotation
01154                 geXForm3d_TransposeTransform(&Models->XForm, &GFront, &NewFront);
01155                 geXForm3d_TransposeTransform(&Models->XForm, &GBack , &NewBack);
01156 
01157                 // push back into world
01158                 geVec3d_Add(&NewFront, &Models->Pivot, &GFront);
01159                 geVec3d_Add(&NewBack , &Models->Pivot, &GBack);
01160                 
01161                 // Make out box out of this move so we only check the leafs it intersected with...
01162 
01163                 Trace_GetMoveBox(Mins, Maxs, &GFront, &GBack, &GMins2, &GMaxs2);
01164 
01165                 FindClosestLeafIntersection_r(BSPData->GFXModels[i].RootNode[0]);
01166 
01167                 if (LeafHit)
01168                 {
01169                         
01170                         // Rotate the impact plane
01171                         geXForm3d_Rotate(&Models->XForm, &GlobalPlane.Normal, &GlobalPlane.Normal);
01172                         
01173                         // Rotate the impact point
01174                         geVec3d_Subtract(&GlobalI, &Models->Pivot, &GlobalI);
01175                         geXForm3d_Transform(&Models->XForm, &GlobalI, &NewFront);
01176                         //geXForm3d_Rotate(&Models->XForm, &GlobalI, &NewFront);
01177                         geVec3d_Add(&NewFront, &Models->Pivot, &GlobalI);
01178                         
01179                         // Find the new plane distance based on the new impact point with the new plane
01180                         GlobalPlane.Dist = geVec3d_DotProduct(&GlobalPlane.Normal, &GlobalI);
01181 
01182                         geVec3d_Subtract(&GlobalI, Front, &Vect);
01183 
01184                         Dist = geVec3d_Length(&Vect);
01185                         if (Dist < BestD)
01186                         {
01187                                 BestD = Dist;
01188                                 BestI = GlobalI;
01189                                 BestPlane = GlobalPlane;
01190                                 BestModel = Models;
01191                                 BestMesh = NULL;                        // Reset the mesh flag...
01192                                 BestActor = NULL;
01193                                 Hit = GE_TRUE;
01194                         }
01195                 }
01196 
01197                 if ((Flags & GE_COLLIDE_NO_SUB_MODELS))
01198                         goto NoModels;
01199 
01200         }
01201 
01202         NoModels:
01203 
01204         if (Hit)
01205         {
01206                 if (I) 
01207                         *I = BestI;
01208                 if (P) 
01209                         *P = BestPlane;
01210                 if (Mesh) 
01211                         *Mesh = BestMesh;
01212                 if (Model) 
01213                         *Model = BestModel;
01214                 if (Actor)
01215                         *Actor = BestActor;
01216                 return GE_TRUE;
01217         }
01218 
01219         return GE_FALSE;
01220 }

geBoolean Trace_WorldCollisionBNode geWorld World,
geVec3d Front,
geVec3d Back,
int32 ModelNum,
geVec3d Impact,
int32 Node,
int32 Plane,
int32 Side
 

geBoolean Trace_WorldCollisionExact geWorld World,
const geVec3d Front,
const geVec3d Back,
uint32  Flags,
geVec3d Impact,
GFX_Plane Plane,
geWorld_Model **  Model,
Mesh_RenderQ **  Mesh,
geActor **  Actor,
uint32  UserFlags,
GE_CollisionCB CollisionCB,
void *  Context
 

Definition at line 236 of file Trace.c.

References World_BSP::BSPData, BSPData, BSPIntersect(), geWorld::CurrentBSP, GFX_Plane::Dist, FALSE, GE_COLLIDE_ACTORS, GE_COLLIDE_MODELS, GE_COLLIDE_NO_SUB_MODELS, GE_FALSE, GE_TRUE, geBoolean, geFloat, geVec3d_Add(), geVec3d_DotProduct(), geVec3d_Inverse(), geVec3d_Length(), geVec3d_Subtract(), geXForm3d_Rotate(), geXForm3d_Transform(), geXForm3d_TransposeTransform(), GBSP_BSPData::GFXModels, GlobalI, GlobalPlane, GlobalSide, HitSet, int32, Mesh_RenderQ, World_BSP::Models, GFX_Plane::Normal, NULL, GBSP_BSPData::NumGFXModels, geWorld_Model::Pivot, PLANE_ANY, GFX_Model::RootNode, geWorld_Model::TMaxs, geWorld_Model::TMins, Trace_ActorCollide(), Trace_GetMoveBox(), GFX_Plane::Type, VectorToSUB, and geWorld_Model::XForm.

Referenced by Trace_GEWorldCollision().

00248 {
00249         int32                   i, b;
00250         geVec3d                 NewFront1, NewBack1;
00251         geVec3d                 NewFront2, NewBack2;
00252         geWorld_Model   *Models, *BestModel;
00253         GFX_Plane               BestPlane, Plane2;
00254         Mesh_RenderQ    *BestMesh=NULL;
00255         geActor                 *BestActor=NULL;
00256         geVec3d                 OMins, OMaxs, Vect, Impact2, BestI;
00257         static geVec3d  MMins = {-1.0f, -1.0f, -1.0f};
00258         static geVec3d  MMaxs = { 1.0f,  1.0f,  1.0f};
00259         geBoolean               Hit;
00260         geFloat                 Dist, BestD;
00261 
00262         assert(World != NULL);
00263         assert(World->CurrentBSP != NULL);
00264         assert(Front != NULL);
00265         assert(Back!= NULL);
00266         
00267         BSPData = &World->CurrentBSP->BSPData;
00268         Models = World->CurrentBSP->Models;
00269         
00270         // Clear mesh/model collision pointers
00271         if (Model)
00272                 *Model = NULL;
00273         if (Mesh)
00274                 *Mesh = NULL;
00275         if (Actor)
00276                 *Actor = NULL;
00277 
00278         BestD = 99999.0f;
00279         BestModel = NULL;
00280         BestMesh = NULL;
00281         Hit = GE_FALSE;
00282 
00283         if (Flags & GE_COLLIDE_ACTORS)
00284         {
00285                 BestActor = Trace_ActorCollide(World,NULL, NULL, Front,Back,&Impact2, &Plane2, UserFlags, CollisionCB, Context, &BestD);
00286                 if (BestActor != NULL)
00287                 {
00288                         BestI = Impact2;
00289                         BestPlane = Plane2;
00290                         Hit = GE_TRUE;
00291                 }
00292         }
00293 
00294         if (!(Flags & GE_COLLIDE_MODELS))
00295                 goto NoModels;
00296 
00297         Trace_GetMoveBox(&MMins, &MMaxs, Front, Back, &OMins, &OMaxs);
00298 
00299         for (i = 0; i < BSPData->NumGFXModels; i++, Models++)
00300         {
00301                 // First, give the caller a chance to reject the model
00302                 if (CollisionCB && !CollisionCB(Models, NULL, Context))
00303                         continue;
00304 
00305                 for (b=0; b<3; b++)
00306                 {
00307                         if (VectorToSUB(OMaxs, b) < VectorToSUB(Models->TMins, b))
00308                                 break;
00309                         if (VectorToSUB(OMins, b) > VectorToSUB(Models->TMaxs, b))
00310                                 break;
00311                 }
00312 
00313                 if (b != 3)
00314                         continue;
00315 
00316                 // Move to models center of rotation
00317                 geVec3d_Subtract(Front, &Models->Pivot, &NewFront1);
00318                 geVec3d_Subtract(Back , &Models->Pivot, &NewBack1);
00319 
00320                 // InverseTransform the point about models center of rotation
00321                 geXForm3d_TransposeTransform(&Models->XForm, &NewFront1, &NewFront2);
00322                 geXForm3d_TransposeTransform(&Models->XForm, &NewBack1 , &NewBack2);
00323 
00324                 // push back into world
00325                 geVec3d_Add(&NewFront2, &Models->Pivot, &NewFront1);
00326                 geVec3d_Add(&NewBack2 , &Models->Pivot, &NewBack1);
00327                 
00328                 HitSet = FALSE;
00329 
00330                 if (BSPIntersect(&NewFront1, &NewBack1, BSPData->GFXModels[i].RootNode[0]))
00331                 {
00332                         // Rotate the impact plane
00333                         geXForm3d_Rotate(&Models->XForm, &GlobalPlane.Normal, &GlobalPlane.Normal);
00334                         
00335                         // Rotate the impact point
00336                         geVec3d_Subtract(&GlobalI, &Models->Pivot, &GlobalI);
00337                         geXForm3d_Transform(&Models->XForm, &GlobalI, &GlobalI);
00338                         geVec3d_Add(&GlobalI, &Models->Pivot, &GlobalI);
00339                         
00340                         // Find the new plane distance based on the new impact point with the new plane
00341                         GlobalPlane.Dist = geVec3d_DotProduct(&GlobalPlane.Normal, &GlobalI);
00342 
00343                         geVec3d_Subtract(&GlobalI, Front, &Vect);
00344                         Dist = geVec3d_Length(&Vect);
00345 
00346                         if (Dist < BestD)
00347                         {
00348                                 BestD = Dist;
00349                                 BestI = GlobalI;
00350                         
00351                                 BestPlane = GlobalPlane;
00352                                 if (GlobalSide)
00353                                 {
00354                                         geVec3d_Inverse(&BestPlane.Normal);
00355                                         BestPlane.Dist = -BestPlane.Dist;
00356                                         BestPlane.Type = PLANE_ANY;
00357                                 }
00358 
00359                                 BestMesh = NULL;                // Clear hit mesh
00360                                 BestActor = NULL;
00361                                 BestModel = Models;
00362                                 Hit = GE_TRUE;
00363                         }
00364                 }
00365 
00366                 if ((Flags & GE_COLLIDE_NO_SUB_MODELS))
00367                         goto NoModels;
00368         }
00369 
00370         NoModels:
00371 
00372         if (Hit)
00373         {
00374                 if (Impact)
00375                         *Impact = BestI;
00376                 if (Plane)
00377                         *Plane = BestPlane;
00378                 if (Model)
00379                         *Model = BestModel;
00380                 if (Mesh)
00381                         *Mesh = BestMesh;
00382                 if (Actor)
00383                         *Actor = BestActor;
00384                 return GE_TRUE;
00385         }
00386 
00387         return GE_FALSE;
00388 }

geBoolean Trace_WorldCollisionExact2 geWorld World,
const geVec3d Front,
const geVec3d Back,
geVec3d Impact,
int32 Node,
int32 Plane,
int32 Side
 

Definition at line 396 of file Trace.c.

References World_BSP::BSPData, BSPData, BSPIntersect(), geWorld::CurrentBSP, FALSE, gContents, GE_CONTENTS_SOLID_CLIP, GE_FALSE, GE_TRUE, geBoolean, geVec3d_Add(), geVec3d_Subtract(), geXForm3d_TransposeTransform(), GBSP_BSPData::GFXModels, GlobalI, GlobalNode, GlobalSide, GPlaneNum, HitSet, int32, World_BSP::Models, NULL, GBSP_BSPData::NumGFXModels, and GFX_Model::RootNode.

Referenced by gePuppet_ComputeAmbientLight(), and geSprite_UpdateLighting().

00403 {
00404         int32                   i;
00405         geVec3d                 NewFront1, NewBack1;
00406         geVec3d                 NewFront2, NewBack2;
00407         geWorld_Model           *Models;
00408 
00409         assert(World != NULL);
00410         assert(World->CurrentBSP != NULL);
00411         assert(Front != NULL);
00412         assert(Back!= NULL);
00413         
00414         BSPData = &World->CurrentBSP->BSPData;
00415         Models = World->CurrentBSP->Models;
00416         
00417         GPlaneNum = -1;
00418 
00419         gContents = GE_CONTENTS_SOLID_CLIP;
00420 
00421         for (i = 0; i < BSPData->NumGFXModels; i++)
00422         {
00423                 
00424                 // Move to models center of rotation
00425                 geVec3d_Subtract(Front, &Models[i].Pivot, &NewFront1);
00426                 geVec3d_Subtract(Back , &Models[i].Pivot, &NewBack1);
00427 
00428                 // InverseTransform the point about models center of rotation
00429                 geXForm3d_TransposeTransform(&Models[i].XForm, &NewFront1, &NewFront2);
00430                 geXForm3d_TransposeTransform(&Models[i].XForm, &NewBack1 , &NewBack2);
00431 
00432                 // push back into world
00433                 geVec3d_Add(&NewFront2, &Models[i].Pivot, &NewFront1);
00434                 geVec3d_Add(&NewBack2 , &Models[i].Pivot, &NewBack1);
00435                 
00436                 HitSet = FALSE;
00437                 
00438                 if (BSPIntersect(&NewFront1, &NewBack1, BSPData->GFXModels[i].RootNode[0]))
00439                 {
00440                         if (GPlaneNum == -1)
00441                                 return FALSE;
00442 
00443                         if (Impact) *Impact = GlobalI;
00444                         if (Node) *Node = GlobalNode;
00445                         if (Plane) *Plane = GPlaneNum;
00446                         if (Side) *Side = GlobalSide;
00447 
00448                         return GE_TRUE;
00449                 }
00450         }
00451 
00452         return GE_FALSE;
00453 }


Generated on Tue Sep 30 12:38:18 2003 for GTestAndEngine by doxygen 1.3.2