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

puppet.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  PUPPET.C                                                                                                                                                    */
00003 /*                                                                                      */
00004 /*  Author: Mike Sandige                                                                    */
00005 /*  Description: Puppet implementation.                                                                 .                               */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 //#define CIRCULAR_SHADOW
00023 #define SHADOW_MAP
00024 //#define PROJECTED_SHADOW
00025 
00026 #include <math.h>  //fabs()
00027 #include <assert.h>
00028 
00029 #include "light.h"
00030 #include "world.h"
00031 #include "trace.h"              //Trace_WorldCollisionExact2()
00032 #include "surface.h"    // Surf_InSurfBoundingBox()
00033 
00034 #include "xfarray.h"
00035 #include "puppet.h"
00036 #include "pose.h"
00037 #include "ErrorLog.h"
00038 #include "ram.h"
00039 #include "tclip.h"
00040 
00041 #include "Frustum.h"
00042 #include "ExtBox.h"
00043 #include "bodyinst.h"
00044 
00045 #ifdef PROFILE
00046 #include "rdtsc.h"
00047 #endif
00048 
00049 #include "bitmap.h"
00050 #include "bitmap._h"
00051 
00052 #define PUPPET_DEFAULT_MAX_DYNAMIC_LIGHTS 3
00053 
00054 typedef struct gePuppet_Color
00055 {
00056         geFloat                         Red,Green,Blue;
00057 } gePuppet_Color;
00058 
00059 typedef struct gePuppet_Material
00060 {
00061         gePuppet_Color           Color;
00062         geBoolean                        UseTexture;
00063         geBitmap                        *Bitmap;
00064         const char                      *TextureName;
00065         const char                      *MaterialName;
00066         const char                      *AlphaName;
00067 } gePuppet_Material;
00068 
00069 typedef struct gePuppet
00070 {
00071         geVFile *                        TextureFileContext;
00072         geBodyInst                      *BodyInstance;
00073         int                                      MaterialCount;
00074         gePuppet_Material       *MaterialArray;
00075         int                                      MaxDynamicLightsToUse;
00076         int                                      LightReferenceBoneIndex;
00077                 
00078         geVec3d                          FillLightNormal;
00079         gePuppet_Color           FillLightColor;                        // 0..255
00080         geBoolean                        UseFillLight;                          // use fill light normal
00081         //Environment mapping...
00082         geEnvironmentOptions     internal_env;
00083         gePuppet_Color           AmbientLightIntensity;         // 0..1
00084         geBoolean                        AmbientLightFromFloor;         // use local lighting from floor
00085 
00086         geBoolean                        PerBoneLighting;
00087 
00088         geBoolean                        DoShadow;
00089         geFloat                          ShadowScale;
00090         const geBitmap          *ShadowMap;
00091         int                                      ShadowBoneIndex;
00092 
00093     // LWM_ACTOR_RENDERING:
00094         geFloat                          OverallAlpha ;
00095 
00096                 #pragma message ("this goes away!: World")
00097         geWorld                         *World;
00098         geBoolean                        AmbientLightFromStaticLights;  // use static lights from map   
00099         geBoolean                        DoTestRayCollision;                    //test static light in shadow   
00100         int                                      MaxStaticLightsToUse;                  //max number of light to use
00101 } gePuppet;
00102 
00103 typedef struct
00104 {
00105         geVec3d                 Normal;
00106         gePuppet_Color  Color;
00107         geFloat                 Distance;
00108         geFloat                 Radius;
00109 } gePuppet_Light;
00110 
00111 typedef struct
00112 {
00113         geBoolean               UseFillLight;
00114         geVec3d                 FillLightNormal;
00115         gePuppet_Color  MaterialColor;
00116         gePuppet_Color  FillLightColor;
00117         gePuppet_Color  Ambient;
00118         geVec3d                 SurfaceNormal;
00119         gePuppet_Light StaticLights[MAX_DYNAMIC_LIGHTS];
00120         int StaticLightCount;
00121         gePuppet_Light  Lights[MAX_DYNAMIC_LIGHTS];
00122         int                             LightCount;
00123         geBoolean               PerBoneLighting;
00124 } gePuppet_LightParamGroup;
00125 
00126 typedef struct
00127 {
00128         gePuppet_Light Lights[MAX_DYNAMIC_LIGHTS];
00129         int LightCount;
00130 } gePuppet_BoneLight;
00131 
00132 // Local info stored across multiple puppets to avoid resource waste.
00133 gePuppet_LightParamGroup  gePuppet_StaticLightGrp;
00134 gePuppet_BoneLight               *gePuppet_StaticBoneLightArray=NULL;
00135 int                                               gePuppet_StaticBoneLightArraySize=0;
00136 int                                               gePuppet_StaticPuppetCount=0;
00137 int                                               gePuppet_StaticFlags[2]={1768710981,560296816};
00138 
00139 static geBoolean GENESISCC gePuppet_FetchTextures(gePuppet *P, const geBody *B)
00140 {
00141         int i;
00142         assert( P );
00143         
00144         P->MaterialCount = geBody_GetMaterialCount(B);
00145         if (P->MaterialCount <= 0)
00146         {
00147                 return GE_TRUE;
00148         }
00149         
00150         P->MaterialArray = GE_RAM_ALLOCATE_ARRAY(gePuppet_Material, P->MaterialCount);
00151         if (P->MaterialArray == NULL)
00152         {
00153                 geErrorLog_Add(ERR_PUPPET_ENOMEM, NULL);
00154                 return GE_FALSE;
00155         }
00156         
00157         for (i=0; i<P->MaterialCount; i++)
00158         {
00159                 const char *Name;
00160                 geBitmap *Bitmap;
00161                 gePuppet_Material *M = &(P->MaterialArray[i]);
00162                 geBody_GetMaterial( B, i, &(Name), &(Bitmap),
00163                                                 &(M->Color.Red),&(M->Color.Green),&(M->Color.Blue));
00164 
00165                 if (Bitmap == NULL )
00166                 {
00167                         M->Bitmap     = NULL;
00168                         M->UseTexture = GE_FALSE;
00169                 }
00170                 else
00171                 {
00172                         M->UseTexture = GE_TRUE;
00173                         assert( P->World );
00174 
00175                         M->Bitmap = Bitmap;
00176                         geBitmap_CreateRef(Bitmap);
00177 
00178                         if ( ! geWorld_AddBitmap(P->World,Bitmap) )
00179                         {
00180                                 geErrorLog_AddString(-1,"Puppet_FetchTextures : World_AddBitmap", NULL);
00181                                 geRam_Free(P->MaterialArray);
00182                                 P->MaterialArray = NULL;
00183                                 P->MaterialCount = 0;
00184                                 return GE_FALSE;
00185                         }
00186                 }
00187                 M->MaterialName = Name;
00188         }
00189 
00190         return GE_TRUE;
00191 }       
00192 
00193 int GENESISCC gePuppet_GetMaterialCount( gePuppet *P )
00194 {
00195         assert( P );
00196         return P->MaterialCount;
00197 }
00198 
00199 geBoolean GENESISCC gePuppet_GetMaterial( gePuppet *P, int MaterialIndex,
00200                                                                         geBitmap **Bitmap, 
00201                                                                         geFloat *Red, geFloat *Green, geFloat *Blue)
00202 {
00203         assert( P      );
00204         assert( Red    );
00205         assert( Green  );
00206         assert( Blue   );
00207         assert( Bitmap );
00208         assert( MaterialIndex >= 0 );
00209         assert( MaterialIndex < P->MaterialCount );
00210 
00211         {
00212                 gePuppet_Material *M = &(P->MaterialArray[MaterialIndex]);
00213                 *Bitmap = M->Bitmap;
00214                 *Red    = M->Color.Red;
00215                 *Green  = M->Color.Green;
00216                 *Blue   = M->Color.Blue;
00217         }
00218         return GE_TRUE;
00219 }
00220 
00221 
00222 geBoolean GENESISCC gePuppet_SetMaterial(gePuppet *P, int MaterialIndex, geBitmap *Bitmap, 
00223                                                                                 geFloat Red, geFloat Green, geFloat Blue)
00224 {
00225         assert( P );
00226         assert( MaterialIndex >= 0 );
00227         assert( MaterialIndex < P->MaterialCount );
00228 
00229         {
00230         geBitmap * OldBitmap;
00231         gePuppet_Material *M = P->MaterialArray + MaterialIndex;
00232 
00233                 OldBitmap = M->Bitmap;
00234 
00235                 M->Bitmap               = Bitmap;
00236                 M->Color.Red    = Red;
00237                 M->Color.Green  = Green;
00238                 M->Color.Blue   = Blue;
00239 
00240                 if ( OldBitmap != Bitmap ) 
00241                 {               
00242                         if ( OldBitmap )
00243                         {
00244                                 assert( M->UseTexture );                
00245                                 geWorld_RemoveBitmap( P->World, OldBitmap );
00246                                 geBitmap_Destroy( &(OldBitmap) );
00247                         }
00248                         
00249                         M->UseTexture = GE_FALSE;
00250 
00251                         if ( Bitmap )
00252                         {
00253                                 geBitmap_CreateRef(Bitmap);
00254                                                 
00255                                 M->UseTexture = GE_TRUE;
00256 
00257                                 if ( ! geWorld_AddBitmap(P->World,Bitmap) )
00258                                 {
00259                                         geErrorLog_AddString(-1,"Puppet_SetMaterial : World_AddBitmap", NULL);
00260                                         return GE_FALSE;
00261                                 }
00262                         }
00263                 }
00264         }
00265 
00266         return GE_TRUE;
00267 }
00268         
00269 
00270 gePuppet *GENESISCC gePuppet_Create(geVFile *TextureFS, const geBody *B, geWorld *World)
00271 {
00272         gePuppet *P;
00273 
00274         assert( geBody_IsValid(B)!=GE_FALSE );
00275         #pragma message ("Need geWorld_IsValid()")
00276         
00277         P = GE_RAM_ALLOCATE_STRUCT(gePuppet);
00278         if (P==NULL)
00279         {
00280                 geErrorLog_Add(ERR_PUPPET_ENOMEM, NULL);
00281                 return NULL;
00282         }
00283         
00284         memset(P,0,sizeof(*P)); 
00285 
00286         P->BodyInstance = NULL;
00287         P->MaxDynamicLightsToUse = PUPPET_DEFAULT_MAX_DYNAMIC_LIGHTS;
00288         P->LightReferenceBoneIndex = GE_POSE_ROOT_JOINT;
00289 
00290         P->FillLightNormal.X = -0.2f;
00291         P->FillLightNormal.Y = 1.0f;
00292         P->FillLightNormal.Z = 0.4f;
00293         geVec3d_Normalize(&(P->FillLightNormal));
00294         P->FillLightColor.Red    = 0.25f;
00295         P->FillLightColor.Green  = 0.25f;
00296         P->FillLightColor.Blue   = 0.25f;
00297         P->UseFillLight = GE_TRUE;
00298         // LWM_ACTOR_RENDERING:
00299         P->OverallAlpha = 255.0f ;
00300 
00301         P->AmbientLightIntensity.Red   = 0.1f;
00302         P->AmbientLightIntensity.Green = 0.1f;
00303         P->AmbientLightIntensity.Blue  = 0.1f;
00304         P->AmbientLightFromFloor = GE_TRUE;
00305 
00306         P->DoShadow = GE_FALSE;
00307         P->ShadowScale = 0.0f;
00308         P->ShadowBoneIndex =  GE_POSE_ROOT_JOINT;
00309         P->TextureFileContext = TextureFS;
00310 
00311         P->World = World;
00312         
00313         P->AmbientLightFromStaticLights = GE_FALSE;     //BY DEFAULT DO NOTHING 
00314         P->DoTestRayCollision = GE_FALSE; 
00315         P->MaxStaticLightsToUse = PUPPET_DEFAULT_MAX_DYNAMIC_LIGHTS;
00316  
00317         //Set default environment options
00318         P->internal_env.PercentEnvironment = 0.0f;
00319         P->internal_env.PercentPuppet = 1.0f;
00320         P->internal_env.PercentMaterial = 1.0f;
00321         P->internal_env.UseEnvironmentMapping = GE_FALSE;
00322         P->internal_env.Supercede = GE_TRUE;
00323 
00324         if (gePuppet_FetchTextures(P,B)==GE_FALSE)
00325         {
00326                 geRam_Free(P);
00327                 return NULL;
00328         }
00329 
00330         P->BodyInstance = geBodyInst_Create(B);
00331         if (P->BodyInstance == NULL)
00332         {
00333                 geErrorLog_Add(ERR_PUPPET_ENOMEM, NULL);
00334                 gePuppet_Destroy( &P );
00335                 return NULL;
00336         }
00337         gePuppet_StaticPuppetCount++;
00338         return P;
00339 }
00340 
00341 
00342 void GENESISCC gePuppet_Destroy(gePuppet **P)
00343 {
00344         assert( P  );
00345         assert( *P );
00346         if ( (*P)->BodyInstance )
00347         {
00348                 geBodyInst_Destroy( &((*P)->BodyInstance) );
00349                 (*P)->BodyInstance = NULL;
00350         }
00351         if ( (*P)->MaterialArray )
00352         {
00353                 gePuppet_Material *M;
00354                 int i;
00355 
00356                 for (i=0; i<(*P)->MaterialCount; i++)
00357                 {
00358                         M = &((*P)->MaterialArray[i]);
00359                         if (M->UseTexture )
00360                         {                                       
00361                                 assert( M->Bitmap );
00362                                 geWorld_RemoveBitmap( (*P)->World, M->Bitmap );
00363                                 geBitmap_Destroy( &(M->Bitmap) );
00364                                 M->UseTexture = GE_FALSE;
00365                         }
00366                 }
00367 
00368 
00369                 geRam_Free( (*P)->MaterialArray );
00370                 (*P)->BodyInstance = NULL;
00371         }
00372         if ( (*P)->ShadowMap )
00373         {
00374                 geBitmap_Destroy((geBitmap **)&((*P)->ShadowMap));
00375                 (*P)->ShadowMap = NULL;
00376         }
00377 
00378         geRam_Free( (*P) );
00379         *P = NULL;
00380         
00381         // clean up any shared resources.
00382         gePuppet_StaticPuppetCount--;
00383         if (gePuppet_StaticPuppetCount==0)
00384                 {
00385                         if (gePuppet_StaticBoneLightArray!=NULL)
00386                                 geRam_Free(gePuppet_StaticBoneLightArray);
00387                         gePuppet_StaticBoneLightArray=NULL;
00388                         gePuppet_StaticBoneLightArraySize = 0;
00389                 }       
00390 }
00391 
00392 void GENESISCC gePuppet_GetStaticLightingOptions(const gePuppet *P,     geBoolean *UseAmbientLightFromStaticLights,     geBoolean *TestRayCollision, int *MaxStaticLightsToUse  )
00393 {       assert( P != NULL);
00394         assert( UseAmbientLightFromStaticLights );
00395         assert( MaxStaticLightsToUse );
00396         *UseAmbientLightFromStaticLights = P->AmbientLightFromStaticLights;
00397         *TestRayCollision = P->DoTestRayCollision;
00398         *MaxStaticLightsToUse = P->MaxStaticLightsToUse;
00399 }       
00400 
00401 void GENESISCC gePuppet_SetStaticLightingOptions(gePuppet *P, geBoolean UseAmbientLightFromStaticLights, geBoolean TestRayCollision, int MaxStaticLightsToUse   )
00402 {       assert( P!= NULL);
00403         P->AmbientLightFromStaticLights = UseAmbientLightFromStaticLights;
00404         P->DoTestRayCollision = TestRayCollision;
00405         P->MaxStaticLightsToUse = MaxStaticLightsToUse;
00406 }       
00407 
00408 void GENESISCC gePuppet_GetLightingOptions(const gePuppet *P,
00409         geBoolean *UseFillLight,
00410         geVec3d *FillLightNormal,
00411         geFloat *FillLightRed,                          
00412         geFloat *FillLightGreen,                                
00413         geFloat *FillLightBlue,                         
00414         geFloat *AmbientLightRed,                       
00415         geFloat *AmbientLightGreen,                     
00416         geFloat *AmbientLightBlue,                      
00417         geBoolean *UseAmbientLightFromFloor,
00418         int *MaximumDynamicLightsToUse,         
00419         int *LightReferenceBoneIndex,
00420         geBoolean *PerBoneLighting
00421         )
00422 {
00423         geFloat Scaler;
00424         assert( P != NULL);
00425         assert( UseFillLight );
00426         assert( FillLightNormal );
00427         assert( FillLightRed ); 
00428         assert( FillLightGreen );       
00429         assert( FillLightBlue );        
00430         assert( AmbientLightRed );
00431         assert( AmbientLightGreen );                    
00432         assert( AmbientLightBlue );                     
00433         assert( UseAmbientLightFromFloor );
00434         assert( MaximumDynamicLightsToUse );    
00435         assert( LightReferenceBoneIndex );
00436                 
00437         *UseFillLight = P->UseFillLight;
00438 
00439         *FillLightNormal = P->FillLightNormal;
00440         
00441         Scaler = 255.0f;
00442         *FillLightRed   = P->FillLightColor.Red * Scaler;
00443         *FillLightGreen = P->FillLightColor.Green * Scaler;
00444         *FillLightBlue  = P->FillLightColor.Blue * Scaler;
00445         
00446         *AmbientLightRed    = P->AmbientLightIntensity.Red * Scaler;
00447         *AmbientLightGreen  = P->AmbientLightIntensity.Green * Scaler;
00448         *AmbientLightBlue   = P->AmbientLightIntensity.Blue * Scaler;
00449         
00450         *UseAmbientLightFromFloor  = P->AmbientLightFromFloor;
00451         *MaximumDynamicLightsToUse = P->MaxDynamicLightsToUse;
00452         *LightReferenceBoneIndex   = P->LightReferenceBoneIndex;
00453         *PerBoneLighting                   = P->PerBoneLighting;
00454 }       
00455 
00456 void GENESISCC gePuppet_SetLightingOptions(gePuppet *P,
00457         geBoolean UseFillLight,
00458         const geVec3d *FillLightNormal,
00459         geFloat FillLightRed,                           // 0 .. 255
00460         geFloat FillLightGreen,                         // 0 .. 255
00461         geFloat FillLightBlue,                          // 0 .. 255
00462         geFloat AmbientLightRed,                        // 0 .. 255
00463         geFloat AmbientLightGreen,                      // 0 .. 255
00464         geFloat AmbientLightBlue,                       // 0 .. 255
00465         geBoolean UseAmbientLightFromFloor,
00466         int MaximumDynamicLightsToUse,          // 0 for none
00467         int LightReferenceBoneIndex,
00468         geBoolean PerBoneLighting
00469         )
00470 {
00471         geFloat Scaler;
00472         assert( P!= NULL);
00473         assert( FillLightNormal );
00474         assert( geVec3d_IsNormalized(FillLightNormal) );
00475         assert( MaximumDynamicLightsToUse >= 0 );
00476         assert( (LightReferenceBoneIndex >=0) || (LightReferenceBoneIndex==GE_POSE_ROOT_JOINT));
00477                 
00478         P->UseFillLight = UseFillLight;
00479 
00480         P->FillLightNormal = *FillLightNormal;
00481         
00482         Scaler = 1.0f/255.0f;
00483 
00484         P->FillLightColor.Red   = FillLightRed   * Scaler;
00485         P->FillLightColor.Green = FillLightGreen * Scaler;
00486         P->FillLightColor.Blue  = FillLightBlue  * Scaler;
00487         
00488         P->AmbientLightIntensity.Red   = AmbientLightRed   * Scaler;
00489         P->AmbientLightIntensity.Green = AmbientLightGreen * Scaler;
00490         P->AmbientLightIntensity.Blue  = AmbientLightBlue  * Scaler;
00491         
00492         P->AmbientLightFromFloor =UseAmbientLightFromFloor;
00493         P->MaxDynamicLightsToUse = MaximumDynamicLightsToUse;
00494         P->LightReferenceBoneIndex = LightReferenceBoneIndex;
00495         P->PerBoneLighting               =      PerBoneLighting;
00496 }       
00497 
00498 
00499 static int GENESISCC gePuppet_PrepLights(const gePuppet *P, 
00500         geWorld *World,
00501         gePuppet_Light *LP,
00502         const geVec3d *ReferencePoint)
00503 {
00504         int i,j,cnt;
00505 
00506         Light_LightInfo *L;
00507         assert( P );
00508         assert( LP );
00509 
00510         L = (World->LightInfo);
00511         for (i=0,cnt=0; i<MAX_DYNAMIC_LIGHTS; i++)
00512                 {
00513                         if (L->DynamicLights[i].Active)
00514                                 {
00515                                         geVec3d *Position = &(L->DynamicLights[i].Pos);
00516                                         geVec3d Normal;
00517 
00518                                         geVec3d_Subtract(Position,ReferencePoint,&Normal);
00519 
00520                                         LP[cnt].Distance =      Normal.X * Normal.X + 
00521                                                                                 Normal.Y * Normal.Y +
00522                                                                                 Normal.Z * Normal.Z;
00523                                         if (LP[cnt].Distance < L->DynamicLights[i].Radius*L->DynamicLights[i].Radius)
00524                                                 {
00525                                                         LP[cnt].Color.Red = L->DynamicLights[i].Color.r;
00526                                                         LP[cnt].Color.Green = L->DynamicLights[i].Color.g;
00527                                                         LP[cnt].Color.Blue = L->DynamicLights[i].Color.b;
00528                                                         LP[cnt].Radius = L->DynamicLights[i].Radius;
00529                                                         LP[cnt].Normal = Normal;
00530                                                         cnt++;
00531                                                 }
00532                                 }
00533                 }
00534 
00535         // sort dynamic lights by distance (squared)
00536         for(i=0; i<P->MaxDynamicLightsToUse && i<cnt; i++) //rush out    when enough lights sorted
00537      for(j=i+1; j<cnt; j++)
00538      {
00539        if (LP[i].Distance > LP[j].Distance)
00540        {
00541          gePuppet_Light Swap = LP[j];
00542          LP[j] = LP[i];
00543          LP[i] = Swap;
00544        }
00545      }
00546 
00547         // go back and finish setting up closest lights
00548         for (i=0; i<cnt; i++)
00549                 {
00550                         geFloat Distance = (geFloat)sqrt(LP[i].Distance);
00551                         geFloat OneOverDistance;
00552                         geFloat Scale;
00553                         if (Distance < 1.0f)
00554                                 Distance = 1.0f;
00555                         OneOverDistance = 1.0f / Distance;
00556                         LP[i].Normal.X *= OneOverDistance;
00557                         LP[i].Normal.Y *= OneOverDistance;
00558                         LP[i].Normal.Z *= OneOverDistance;
00559 
00560                         LP[i].Distance = Distance;
00561 
00562                         //assert( Distance  < LP[i].Radius );
00563 
00564                         Scale = 1.0f - Distance / LP[i].Radius ;
00565                         Scale *= (1.0f/255.0f);
00566                         LP[i].Color.Red *= Scale;
00567                         LP[i].Color.Green *= Scale;
00568                         LP[i].Color.Blue *= Scale;
00569                 }
00570                         
00571         return cnt;                     
00572 }
00573         
00574 static int  GENESISCC gePuppet_ComputeAmbientLight(
00575                 const gePuppet *P, 
00576                 const geWorld *World, 
00577                 gePuppet_Color *Ambient,
00578                 gePuppet_Light *LP, //Xing studios
00579                 const geVec3d *ReferencePoint)
00580 {
00581         assert( P );
00582         assert( World );
00583         assert( Ambient );
00584         
00585         if (P->AmbientLightFromFloor != GE_FALSE)
00586         {
00587 #define GE_PUPPET_MAX_AMBIENT (0.3f)
00588                 int32                   Node, Plane, i;
00589                 geVec3d                 Pos1, Pos2, Impact;
00590                 GFX_Node                *GFXNodes;
00591                 Surf_SurfInfo   *Surf;
00592                 GE_RGBA                 RGBA;
00593                 //geBoolean             Col1, Col2;
00594                 
00595                 GFXNodes = World->CurrentBSP->BSPData.GFXNodes;
00596                 
00597                 Pos1 = *ReferencePoint;
00598                 
00599                 Pos2 = Pos1;
00600                 
00601                 Pos2.Y -= 30000.0f;
00602                 
00603                 if(!Trace_WorldCollisionExact2((geWorld*)World, &Pos1, &Pos1, &Impact,    &Node, &Plane, NULL))         //just save one test    //xing studios
00604                 {
00605                         // Now find the color of the mesh by getting the lightmap point he is standing    on...
00606                         if (Trace_WorldCollisionExact2((geWorld*)World, &Pos1, &Pos2, &Impact,    &Node, &Plane, NULL))
00607                         {
00608                                 Surf = &(World)->CurrentBSP->SurfInfo[GFXNodes[Node].FirstFace];
00609                                 if (Surf->LInfo.Face<0)
00610                                 { // FIXME? surface has no light...
00611                                         Ambient->Red = Ambient->Green = Ambient->Blue = 0.0f;
00612                                 }
00613                                 else 
00614                                 {
00615                                         for (i=0; i< GFXNodes[Node].NumFaces; i++)
00616                                         {
00617                                                 if (Surf_InSurfBoundingBox(Surf, &Impact, 20.0f))
00618                                                 {
00619                                                         Light_SetupLightmap(&Surf->LInfo, NULL); 
00620                                                         
00621                                                         if (Light_GetLightmapRGB(Surf, &Impact, &RGBA))
00622                                                         {
00623                                                                 geFloat Scale = 1.0f / 255.0f;
00624                                                                 Ambient->Red = RGBA.r * Scale;
00625                                                                 Ambient->Green = RGBA.g * Scale;
00626                                                                 Ambient->Blue = RGBA.b * Scale;
00627                                                                 if (Ambient->Red > GE_PUPPET_MAX_AMBIENT) 
00628                                                                 {
00629                                                                         Ambient->Red = GE_PUPPET_MAX_AMBIENT;
00630                                                                 }
00631                                                                 if (Ambient->Green > GE_PUPPET_MAX_AMBIENT) 
00632                                                                 {
00633                                                                         Ambient->Green = GE_PUPPET_MAX_AMBIENT;
00634                                                                 }
00635                                                                 if (Ambient->Blue > GE_PUPPET_MAX_AMBIENT) 
00636                                                                 {
00637                                                                         Ambient->Blue = GE_PUPPET_MAX_AMBIENT;
00638                                                                 }
00639                                                                 break;
00640                                                         }
00641                                                 }
00642                                                 Surf++;
00643                                         }
00644                                 }
00645                         }
00646                 }
00647         }
00648         
00649         if(P->AmbientLightFromStaticLights != GE_FALSE) 
00650         {
00651                 int i,j,cnt;
00652                 geEntity_EntitySet * entitySet = NULL;
00653                 geEntity * entity = NULL;
00654                 light * aLight;
00655                 entitySet = geWorld_GetEntitySet(World, "light");
00656                 if (entitySet != NULL)
00657                         entity = geEntity_EntitySetGetNextEntity(entitySet, entity);
00658                 
00659                 //loop through all static lights and select the ones that touch the actor, with    a max limit of MAX_DYNAMIC_LIGHTS
00660                 for (i=0,cnt=0; entity != NULL && cnt<MAX_DYNAMIC_LIGHTS; i++)
00661                 {
00662                         geVec3d *Position;
00663                         geVec3d Normal;
00664                         geBoolean keepLight = GE_TRUE;
00665                         aLight = (light*)geEntity_GetUserData(entity);
00666                         Position = &(aLight->origin);
00667                         geVec3d_Subtract(Position,ReferencePoint,&Normal);
00668                         LP[cnt].Distance = Normal.X * Normal.X    + 
00669                                 Normal.Y * Normal.Y +
00670                                 Normal.Z * Normal.Z;
00671                         if (LP[cnt].Distance < aLight->light * aLight->light)
00672                         {
00673                                 if (P->DoTestRayCollision == GE_TRUE)
00674                                 {
00675                                         if (!Trace_WorldCollisionExact2((geWorld*)World, ReferencePoint, Position, NULL,    NULL, NULL, NULL))
00676                                         {
00677                                                 LP[cnt].Color.Red = aLight->color.r;
00678                                                 LP[cnt].Color.Green = aLight->color.g;
00679                                                 LP[cnt].Color.Blue = aLight->color.b;
00680                                                 LP[cnt].Radius = (float)aLight->light;
00681                                                 LP[cnt].Normal = Normal;
00682                                                 cnt++;
00683                                         }
00684                                 }
00685                                 else 
00686                                 {
00687                                         LP[cnt].Color.Red = aLight->color.r;
00688                                         LP[cnt].Color.Green = aLight->color.g;
00689                                         LP[cnt].Color.Blue = aLight->color.b;
00690                                         LP[cnt].Radius = (float)aLight->light;
00691                                         LP[cnt].Normal = Normal;
00692                                         cnt++;
00693                                 }
00694                         }
00695                         entity = geEntity_EntitySetGetNextEntity(entitySet,    entity);
00696                 }
00697                 // sort static lights by distance    (squared)
00698                 // for(i=0; i<cnt; i++)
00699                 for(i=0; i<P->MaxDynamicLightsToUse && i<cnt; i++) //rush out    when enough lights sorted
00700                         for(j=i+1; j<cnt; j++)
00701                         {
00702                                 if (LP[i].Distance > LP[j].Distance)
00703                                 {
00704                                         gePuppet_Light Swap = LP[j];
00705                                         LP[j] = LP[i];
00706                                         LP[i] = Swap;
00707                                 }
00708                         }
00709                         // go back and finish setting up    closest lights
00710                         for (i=0; i<cnt; i++)
00711                         {
00712                                 geFloat Distance = (geFloat)sqrt(LP[i].Distance);
00713                                 geFloat OneOverDistance;
00714                                 geFloat Scale;
00715                                 if (Distance < 1.0f)
00716                                         Distance = 1.0f;
00717                                 OneOverDistance = 1.0f / Distance;
00718                                 LP[i].Normal.X *= OneOverDistance;
00719                                 LP[i].Normal.Y *= OneOverDistance;
00720                                 LP[i].Normal.Z *= OneOverDistance;
00721                                 LP[i].Distance = Distance;
00722                                 Scale = 1.0f - Distance / LP[i].Radius    ;
00723                                 Scale *= (1.0f/255.0f);
00724                                 LP[i].Color.Red *= Scale;
00725                                 LP[i].Color.Green *= Scale;
00726                                 LP[i].Color.Blue *= Scale;
00727                         }
00728                         return cnt;
00729         } 
00730         //if ambient light is static
00731         if (P->AmbientLightFromFloor == GE_FALSE && P->AmbientLightFromStaticLights    == GE_FALSE)
00732         {
00733                 *Ambient = P->AmbientLightIntensity;
00734         }
00735         return 0;
00736 }
00737 
00738 static void GENESISCC gePuppet_SetVertexColor(
00739         GE_LVertex *v,int BoneIndex)
00740 {
00741         geFloat RedIntensity,GreenIntensity,BlueIntensity;
00742         geFloat Color;                                          
00743         int l;
00744 
00745         assert( v );
00746         
00747         RedIntensity   = gePuppet_StaticLightGrp.Ambient.Red;
00748         GreenIntensity = gePuppet_StaticLightGrp.Ambient.Green;
00749         BlueIntensity  = gePuppet_StaticLightGrp.Ambient.Blue;
00750 
00751         if (gePuppet_StaticLightGrp.UseFillLight)
00752                 {
00753                         geFloat Intensity;
00754                         Intensity = gePuppet_StaticLightGrp.FillLightNormal.X * gePuppet_StaticLightGrp.SurfaceNormal.X + 
00755                                                 gePuppet_StaticLightGrp.FillLightNormal.Y * gePuppet_StaticLightGrp.SurfaceNormal.Y + 
00756                                                 gePuppet_StaticLightGrp.FillLightNormal.Z * gePuppet_StaticLightGrp.SurfaceNormal.Z;
00757                         if (Intensity > 0.0)
00758                                 {
00759                                         RedIntensity   += Intensity * gePuppet_StaticLightGrp.FillLightColor.Red;
00760                                         GreenIntensity += Intensity * gePuppet_StaticLightGrp.FillLightColor.Green;
00761                                         BlueIntensity  += Intensity * gePuppet_StaticLightGrp.FillLightColor.Blue;
00762                                 }
00763                 }
00764 
00765         if (gePuppet_StaticLightGrp.PerBoneLighting)
00766                 {
00767                         gePuppet_BoneLight *L;
00768                         L=&(gePuppet_StaticBoneLightArray[BoneIndex]);
00769 
00770                         for (l=0; l<L->LightCount; l++)
00771                                 {
00772                                         geVec3d *LightNormal;
00773                                         geFloat Intensity;
00774                                 
00775                                         LightNormal = &(L->Lights[l].Normal);
00776 
00777                                         Intensity=      LightNormal->X * gePuppet_StaticLightGrp.SurfaceNormal.X + 
00778                                                                 LightNormal->Y * gePuppet_StaticLightGrp.SurfaceNormal.Y + 
00779                                                                 LightNormal->Z * gePuppet_StaticLightGrp.SurfaceNormal.Z;
00780                                         if (Intensity > 0.0f)
00781                                                 {
00782                                                         RedIntensity   += Intensity * L->Lights[l].Color.Red;
00783                                                         GreenIntensity += Intensity * L->Lights[l].Color.Green;
00784                                                         BlueIntensity  += Intensity * L->Lights[l].Color.Blue;
00785                                                 }
00786                                 }
00787                 }
00788         else
00789                 {
00790                         for (l=0; l<gePuppet_StaticLightGrp.LightCount; l++)
00791                                 {
00792                                         geVec3d *LightNormal;
00793                                         geFloat Intensity;
00794                                 
00795                                         LightNormal = &(gePuppet_StaticLightGrp.Lights[l].Normal);
00796 
00797                                         Intensity=      LightNormal->X * gePuppet_StaticLightGrp.SurfaceNormal.X + 
00798                                                                 LightNormal->Y * gePuppet_StaticLightGrp.SurfaceNormal.Y + 
00799                                                                 LightNormal->Z * gePuppet_StaticLightGrp.SurfaceNormal.Z;
00800                                         if (Intensity > 0.0f)
00801                                                 {
00802                                                         RedIntensity   += Intensity * gePuppet_StaticLightGrp.Lights[l].Color.Red;
00803                                                         GreenIntensity += Intensity * gePuppet_StaticLightGrp.Lights[l].Color.Green;
00804                                                         BlueIntensity  += Intensity * gePuppet_StaticLightGrp.Lights[l].Color.Blue;
00805                                                 }
00806                                 }
00807                 }
00808         for (l=0; l<gePuppet_StaticLightGrp.StaticLightCount; l++)
00809         {
00810                 geVec3d *LightNormal;
00811                 float Intensity;
00812                 
00813                 LightNormal = &(gePuppet_StaticLightGrp.StaticLights[l].Normal);
00814                 Intensity= LightNormal->X * gePuppet_StaticLightGrp.SurfaceNormal.X + 
00815                         LightNormal->Y * gePuppet_StaticLightGrp.SurfaceNormal.Y + 
00816                         LightNormal->Z * gePuppet_StaticLightGrp.SurfaceNormal.Z;
00817                 if (Intensity > 0.0f)
00818                 {
00819                         RedIntensity += Intensity * gePuppet_StaticLightGrp.StaticLights[l].Color.Red;
00820                         GreenIntensity += Intensity * gePuppet_StaticLightGrp.StaticLights[l].Color.Green;
00821                         BlueIntensity += Intensity * gePuppet_StaticLightGrp.StaticLights[l].Color.Blue;
00822                 }
00823         }
00824         
00825         Color = gePuppet_StaticLightGrp.MaterialColor.Red * RedIntensity;
00826         if (Color > 255.0f)
00827                 Color = 255.0f;
00828         if (Color < 0.0f)
00829                 Color = 0.0f;
00830         v->r = Color;
00831 
00832         Color = gePuppet_StaticLightGrp.MaterialColor.Green * GreenIntensity;
00833         if (Color > 255.0f)
00834                 Color = 255.0f;
00835         if (Color < 0.0f)
00836                 Color = 0.0f;
00837         v->g = Color;
00838 
00839         Color = gePuppet_StaticLightGrp.MaterialColor.Blue * BlueIntensity;
00840         if (Color > 255.0f)
00841                 Color = 255.0f;
00842         if (Color < 0.0f)
00843                 Color = 0.0f;
00844         v->b = Color;
00845 
00846 }
00847 
00848 
00849 static void GENESISCC gePuppet_DrawShadow(const gePuppet *P, 
00850                                                 const gePose *Joints, 
00851                                                 geEngine *Engine, 
00852                                                 geWorld *World, 
00853                                                 const geCamera *Camera)
00854 {
00855         GE_LVertex v[3];
00856         
00857         geVec3d Impact;
00858         geBoolean GoodImpact;
00859         GFX_Plane               Plane;
00860         geXForm3d RootTransform;
00861         
00862         assert( P );
00863         assert( World );
00864         assert( Camera );
00865         assert( Joints );
00866 
00867         assert( (P->ShadowBoneIndex < gePose_GetJointCount(Joints)) || (P->ShadowBoneIndex ==GE_POSE_ROOT_JOINT));
00868         assert( (P->ShadowBoneIndex >=0)                                                || (P->ShadowBoneIndex ==GE_POSE_ROOT_JOINT));
00869 
00870         gePose_GetJointTransform(Joints,P->ShadowBoneIndex,&RootTransform);
00871         
00872         {
00873                 geVec3d                 Pos1, Pos2;
00874                 GE_Collision    Collision;
00875 
00876                 Pos1 = RootTransform.Translation;
00877                         
00878                 Pos2 = Pos1;
00879 
00880                 Pos2.Y -= 30000.0f;
00881 
00882                 // Get shadow hit plane impact point
00883                 GoodImpact = Trace_GEWorldCollision(World,
00884                                 NULL,
00885                                 NULL,
00886                                 &Pos1,  
00887                                 &Pos2, 
00888                                 GE_CONTENTS_SOLID_CLIP,  
00889                                 GE_COLLIDE_MODELS,
00890                                 0,
00891                                 NULL,
00892                                 NULL,
00893                                 &Collision);
00894 
00895                 //if(GoodImpact) 
00896                         Impact = Collision.Impact;
00897                 //else
00898                         //return;
00899         }
00900 
00901         Impact.Y += 1.0f;
00902 
00903         v[0].r = v[0].b = v[0].g = 0.0f;
00904         v[1].r = v[1].b = v[1].g = 0.0f;
00905         v[2].r = v[2].b = v[2].g = 0.0f;
00906 
00907 #ifdef SHADOW_MAP
00908         {
00909                 int i;
00910                 GE_LVertex s[4];
00911                 geVec3d ws[4];
00912                 geVec3d In,Left;
00913                 geVec3d Up;
00914                 geVec3d Zero = {0.0f,0.0f,0.0f};
00915                 
00916                 geVec3d_Subtract(&Impact,&(RootTransform.Translation),&Up);
00917                 geVec3d_Normalize(&Up);
00918                 geVec3d_CrossProduct(&(Plane.Normal),&Up,&Left);
00919                 if (geVec3d_Compare(&Left,&Zero,0.001f)!=GE_FALSE)
00920                         {
00921                                 geXForm3d_GetLeft(&(RootTransform),&Left);
00922                         }
00923                 geVec3d_CrossProduct(&Left,&(Plane.Normal),&In);
00924 
00925                 geVec3d_Normalize(&Left);
00926                 geVec3d_Normalize(&In);
00927 
00928                 s[0].r = s[0].b = s[0].g = 0.0f;
00929                 s[1].r = s[1].b = s[1].g = 0.0f;
00930                 s[2].r = s[2].b = s[2].g = 0.0f;
00931                 s[3].r = s[3].b = s[3].g = 0.0f;
00932 
00933                 geVec3d_Scale(&In  ,P->ShadowScale,&In);
00934                 geVec3d_Scale(&Left,P->ShadowScale,&Left);
00935 
00936                 s[0].a = s[1].a = s[2].a = s[3].a  = 160.0f;
00937 
00938                 s[0].u = 0.0f; s[0].v = 0.0f;
00939                 s[1].u = 1.0f; s[1].v = 0.0f;
00940                 s[2].u = 1.0f; s[2].v = 1.0f;
00941                 s[3].u = 0.0f; s[3].v = 1.0f;
00942                 ws[0].Y = ws[1].Y = ws[2].Y = ws[3].Y = Impact.Y;
00943 
00944                 ws[0].X = RootTransform.Translation.X + Left.X - In.X;
00945                 ws[0].Z = RootTransform.Translation.Z + Left.Z - In.Z;
00946 
00947                 ws[1].X = RootTransform.Translation.X - Left.X - In.X;
00948                 ws[1].Z = RootTransform.Translation.Z - Left.Z - In.Z;
00949 
00950                 ws[2].X = RootTransform.Translation.X - Left.X + In.X;
00951                 ws[2].Z = RootTransform.Translation.Z - Left.Z + In.Z;
00952                 
00953                 ws[3].X = RootTransform.Translation.X + Left.X + In.X;
00954                 ws[3].Z = RootTransform.Translation.Z + Left.Z + In.Z;
00955 
00956                 for (i=0; i<4; i++)
00957                         {
00958                                 geCamera_Transform(Camera,&ws[i],&ws[i]);
00959                                 geCamera_Project(Camera,&ws[i],&ws[i]);
00960                         }
00961 
00962                 
00963                 s[0].X = ws[0].X; s[0].Y = ws[0].Y; s[0].Z = ws[0].Z;
00964                 s[1].X = ws[1].X; s[1].Y = ws[1].Y; s[1].Z = ws[1].Z;
00965                 s[2].X = ws[2].X; s[2].Y = ws[2].Y; s[2].Z = ws[2].Z;
00966                 s[3].X = ws[3].X; s[3].Y = ws[3].Y; s[3].Z = ws[3].Z;
00967                 
00968                 geTClip_SetTexture(P->ShadowMap);
00969 
00970                 geTClip_Triangle(s);
00971                 s[1] = s[2];
00972                 s[2] = s[3];
00973 
00974                 geTClip_Triangle(s);
00975         }
00976 #endif
00977         
00978 #ifdef CIRCULAR_SHADOW
00979         v[0].a = v[1].a = v[2].a = 160.0f;
00980         v[0].u = v[1].u = v[2].u = 0.5f;
00981         v[0].v = v[1].v = v[2].v = 0.5f;
00982         
00983         v[0].X = Impact.X;
00984         v[0].Y = v[1].Y = v[2].Y = Impact.Y;
00985         v[0].Z = Impact.Z;
00986         
00987         {
00988                 int steps = 30;
00989                 int i;
00990                 geVec3d V;
00991                 geFloat Angle = 0.0f;
00992                 geFloat DAngleDStep = -(2.0f * 3.14159f / (geFloat)steps);
00993                 geFloat Radius = P->ShadowScale/2.0f;
00994 
00995                 V = Impact;
00996                 geCamera_Transform(Camera,&V,&V);
00997                 geCamera_Project(Camera,&V,&V);
00998                 v[0].X = V.X;
00999                 v[0].Y = V.Y;
01000                 v[0].Z = V.Z;
01001 
01002                 //geTClip_SetTexture(NULL);
01003                 geTClip_SetTexture(P->ShadowMap);
01004 
01005                 V = Impact;
01006                 V.Z += Radius;
01007                 geCamera_Transform(Camera,&V,&V);
01008                 geCamera_Project(Camera,&V,&V);
01009                 v[1].X = V.X;
01010                 v[1].Y = V.Y;
01011                 v[1].Z = V.Z;
01012                 for (i=0; i<steps+1; i++)
01013                         {
01014                                 v[2] = v[1];
01015 
01016                                 V = Impact;
01017                                 V.X += (geFloat)(sin( Angle ) * Radius);
01018                                 V.Z += (geFloat)(cos( Angle ) * Radius);
01019                                 geCamera_Transform(Camera,&V,&V);
01020                                 geCamera_Project(Camera,&V,&V);
01021                                 v[1].X = V.X;
01022                                 v[1].Y = V.Y;
01023                                 v[1].Z = V.Z;
01024 
01025                                 Angle = Angle + DAngleDStep;
01026                                 geEngine_RenderPoly(Engine, (GE_TLVertex *)v, 3, P->ShadowMap, 0 );
01027                                 //geTClip_Triangle(v);
01028                         }
01029         }
01030 #endif
01031 
01032 #ifdef PROJECTED_SHADOW                 
01033         {
01034                 int i,j,Count;
01035                 geBodyInst_Index *List;
01036                 geBodyInst_Index Command;
01037                 geBody_SkinVertex *SV;
01038                 
01039                 G = geBodyInst_GetShadowGeometry(P->BodyInstance,
01040                                                 gePose_GetAllJointTransforms(Joints),0,Camera,&Impact);
01041 
01042                 if ( G == NULL )
01043                         {
01044                                 geErrorLog_Add(ERR_PUPPET_RENDER, NULL);
01045                                 return GE_FALSE;
01046                         }
01047 
01048                 geTClip_SetTexture(NULL);
01049 
01050                 Count = G->FaceCount;
01051                 List  = G->FaceList;
01052 
01053                 for (i=0; i<Count; i++)
01054                         {       
01055                                 Command = *List;
01056                                 List ++;
01057                                 //Material = *List;
01058                                 List ++;
01059 
01060                                 assert( Command == GE_BODY_FACE_TRIANGLE );
01061 
01062                                 {
01063                                         geFloat AX,AY,BXMinusAX,BYMinusAY,CYMinusAY,CXMinusAX;
01064                                         geBodyInst_Index *List2;
01065                                         
01066                                         List2 = List;
01067                                         SV = &(G->SkinVertexArray[ *List2 ]);
01068                                         AX = SV->SVPoint.X;
01069                                         AY = SV->SVPoint.Y;
01070                                         List2++;
01071                                         List2++;
01072                                         
01073                                         SV = &(G->SkinVertexArray[ *List2 ]);
01074                                         BXMinusAX = SV->SVPoint.X - AX;
01075                                         BYMinusAY = SV->SVPoint.Y - AY;
01076                                         List2++;
01077                                         List2++;
01078 
01079                                         SV = &(G->SkinVertexArray[ *List2 ]);
01080                                         CXMinusAX = SV->SVPoint.X - AX;
01081                                         CYMinusAY = SV->SVPoint.Y - AY;
01082                                         List2++;
01083                                         List2++;
01084 
01085                                         // ZCROSS is z the component of a 2d vector cross product of ABxAC
01086                                         //#define ZCROSS(Ax,Ay,Bx,By,Cx,Cy)  ((((Bx)-(Ax))*((Cy)-(Ay))) - (((By)-(Ay))*((Cx)-(Ax))))
01087 
01088                                         // 2d cross product of AB cross AC   (A is vtx[0], B is vtx[1], C is vtx[2]
01089                                         if ( ((BXMinusAX * CYMinusAY) - (BYMinusAY * CXMinusAX)) > 0.0f )
01090                                                 {
01091                                                         List = List2;
01092                                                         continue;
01093                                                 }
01094                                 }                                               
01095 
01096                         #define SOME_SCALE (  255.0f / 40.0f )
01097                                 for (j=0; j<3; j++)
01098                                         {
01099                                                 SV = &(G->SkinVertexArray[ *List ]);
01100                                                 List++;
01101 
01102                                                 v[j].X = SV->SVPoint.X;
01103                                                 v[j].Y = SV->SVPoint.Y;
01104                                                 
01105                                                 v[j].Z = SV->SVPoint.Z;
01106                                                 //Environment mapping code
01107                                                 if( P->internal_env.UseEnvironmentMapping )
01108                                                 {
01109                                                         v[j].u = ( SV->SVU * P->internal_env.PercentPuppet );
01110                                                         v[j].v = ( SV->SVV * P->internal_env.PercentPuppet );
01111                                                         
01112                                                         if( P->internal_env.Supercede && PM->MaterialName[0] == 'g' )
01113                                                         {
01114                                                                 v[j].u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentMaterial);
01115                                                                 v[j].v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentMaterial);
01116                                                         }
01117                                                         else
01118                                                         {
01119                                                                 v[j].u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentEnvironment);
01120                                                                 v[j].v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentEnvironment);
01121                                                         }
01122                                                 }
01123                                                 else
01124                                                 {
01125                                                         v[j].u = SV->SVU;
01126                                                         v[j].v = SV->SVV;
01127                                                         
01128                                                         if( P->internal_env.Supercede && PM->MaterialName[0] == 'g' )
01129                                                         {
01130                                                                 v[j].u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentMaterial);
01131                                                                 v[j].v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentMaterial);
01132                                                         }
01133                                                 }
01134                                                 
01135                                                 List++;
01136                                                 v[j].a = (255.0f- (SV->SVU * SOME_SCALE));
01137                                         }
01138                         
01139                                 if ((v[0].a > 0) && (v[1].a > 0) && (v[2].a > 0))
01140                                         {
01141                                                 geTClip_Triangle(v);
01142                                         }
01143                         }
01144                 assert( ((uint32)List) - ((uint32)G->FaceList) == (uint32)(G->FaceListSize) );
01145         }
01146 #endif
01147 }
01148 
01149 //Environment mapping code...
01150 void GENESISCC gePuppet_SetEnvironmentOptions( gePuppet *P, geEnvironmentOptions *envop )
01151 {
01152         assert ( P );
01153         assert ( (envop->UseEnvironmentMapping == GE_TRUE) || (envop->UseEnvironmentMapping == GE_FALSE ) );
01154         assert ( (envop->Supercede == GE_TRUE) || (envop->Supercede == GE_FALSE) );
01155         assert ( (envop->PercentEnvironment >= 0.0f) && (envop->PercentEnvironment <= 1.0f) );
01156         assert ( (envop->PercentMaterial >= 0.0f) && (envop->PercentMaterial <= 1.0f) );
01157         assert ( (envop->PercentPuppet >= 0.0f) && (envop->PercentPuppet <= 1.0f) );
01158 
01159         P->internal_env.UseEnvironmentMapping = envop->UseEnvironmentMapping;
01160         P->internal_env.Supercede = envop->Supercede;
01161         P->internal_env.PercentEnvironment = envop->PercentEnvironment;
01162         P->internal_env.PercentMaterial = envop->PercentEnvironment;
01163         P->internal_env.PercentPuppet = envop->PercentPuppet;
01164 }
01165 
01166 geEnvironmentOptions GENESISCC gePuppet_GetEnvironmentOptions( gePuppet *P )
01167 {
01168         assert ( P );
01169         return P->internal_env;
01170 }
01171 
01172 int32           NumClips;
01173 
01174 // LWM_ACTOR_RENDERING
01175 geFloat GENESISCC gePuppet_GetAlpha( const gePuppet *P )
01176 {
01177         assert( P ) ;
01178         return P->OverallAlpha ;
01179 }
01180 
01181 // LWM_ACTOR_RENDERING
01182 void GENESISCC gePuppet_SetAlpha( gePuppet *P, geFloat Alpha )
01183 {
01184         assert( P ) ;
01185         P->OverallAlpha = Alpha ;
01186 }
01187 
01188 // LWM_ACTOR_RENDERING
01189 geBoolean GENESISCC gePuppet_RenderThroughFrustum(const gePuppet *P, 
01190                                                 const gePose *Joints, 
01191                                                 const geExtBox *Box, 
01192                                                 geEngine *Engine, 
01193                                                 geWorld *World, 
01194                                                 const geCamera *Camera, 
01195                                                 Frustum_Info *FInfo)
01196 {
01197         int32           ClipFlags;
01198         geVec3d     Scale;
01199         const geXFArray *JointTransforms;
01200 
01201         const geBodyInst_Geometry *G;
01202         assert( P      );
01203         assert( Engine );
01204         assert( World  );
01205         assert( Camera );
01206         assert( Joints );
01207 
01208         JointTransforms = gePose_GetAllJointTransforms(Joints);
01209 
01210         #pragma message ("Level of detail hacked:")
01211 
01212         gePose_GetScale(Joints,&Scale);
01213         G = geBodyInst_GetGeometry(P->BodyInstance, &Scale, JointTransforms, 0, NULL);
01214 
01215         // Setup clip flags...
01216         ClipFlags = 0xffff;
01217 
01218         {
01219                 geExtBox        MinMaxs;
01220                 //geVec3d               d1, d2, d3;
01221                 GFX_Plane       *Planes;
01222                 int32           k;
01223                 geVec3d         Expand = {150.0f, 150.f, 150.0f};
01224                 int32           OriginalClips;
01225 
01226                 OriginalClips = NumClips;
01227 
01228                 MinMaxs = *Box;
01229 
01230                 Planes = FInfo->Planes;
01231 
01232                 for (k=0; k< FInfo->NumPlanes; k++, Planes++)
01233                 {
01234                         int32           Side;
01235                         
01236                         Planes->Type = PLANE_ANY;
01237                         
01238                         Side = Trace_BoxOnPlaneSide(&MinMaxs.Min, &MinMaxs.Max, Planes);
01239 
01240                         if (Side == PSIDE_BACK)
01241                         {
01242                                 NumClips = OriginalClips;
01243                                 return GE_TRUE;
01244                         }
01245                         
01246                         if (Side == PSIDE_FRONT)
01247                         {
01248                                 ClipFlags &= ~(1<<k);
01249                         }
01250                         else
01251                                 NumClips++;
01252                         
01253                 }
01254         }
01255 
01256         if (G == NULL)
01257         {
01258                 geErrorLog_Add(ERR_PUPPET_RENDER, NULL);
01259                 return GE_FALSE;
01260         }
01261 
01262         {
01263                 int32                   NumFaces;
01264                 int32                   i;
01265                 geBodyInst_Index        *List;
01266                 geXForm3d               RootTransform;
01267 
01268                 gePuppet_StaticLightGrp.UseFillLight             = P->UseFillLight;
01269                 gePuppet_StaticLightGrp.FillLightNormal          = P->FillLightNormal;
01270                 gePuppet_StaticLightGrp.FillLightColor.Red       = P->FillLightColor.Red;
01271                 gePuppet_StaticLightGrp.FillLightColor.Green = P->FillLightColor.Green;
01272                 gePuppet_StaticLightGrp.FillLightColor.Blue  = P->FillLightColor.Blue;
01273                 gePuppet_StaticLightGrp.PerBoneLighting      = P->PerBoneLighting;
01274 
01275                 gePose_GetJointTransform(Joints,P->LightReferenceBoneIndex,&(RootTransform));
01276 
01277                 // LWM_OPTIMIZATION: It seems that if you know that there are 
01278                 // no dynamic lights anywhere you could skip this test easily
01279                 if (P->MaxDynamicLightsToUse > 0)
01280                 {
01281                         if (P->PerBoneLighting)
01282                                 {
01283                                         int BoneCount;
01284                                         const geXForm3d *XFA = geXFArray_GetElements(JointTransforms, &BoneCount);
01285                                         if (BoneCount>0)
01286                                                 {
01287                                                         if (gePuppet_StaticBoneLightArraySize < BoneCount)
01288                                                                 {
01289                                                                         gePuppet_BoneLight *LG;
01290                                                         
01291                                                                         LG = geRam_Realloc(gePuppet_StaticBoneLightArray, sizeof(gePuppet_BoneLight) * BoneCount);
01292                                                                         if (LG==NULL)
01293                                                                                 {
01294                                                                                         geErrorLog_Add(ERR_PUPPET_RENDER,"Failed to allocate space for bone lighting info cache");
01295                                                                                         return GE_FALSE;
01296                                                                                 }
01297                                                                         gePuppet_StaticBoneLightArray = LG;
01298                                                                         gePuppet_StaticBoneLightArraySize = BoneCount;
01299                                                                 }
01300                                                         for (i=0; i<BoneCount; i++)
01301                                                                 {
01302                                                                         gePuppet_StaticBoneLightArray[i].LightCount = gePuppet_PrepLights(P,World,
01303                                                                                                 gePuppet_StaticBoneLightArray[i].Lights,&(XFA[i].Translation));
01304                                                                 }
01305                                                 }
01306                                 }
01307                         else
01308                                 {
01309                                         gePuppet_StaticLightGrp.LightCount = gePuppet_PrepLights(P,World
01310                                                                 ,gePuppet_StaticLightGrp.Lights,&(RootTransform.Translation));
01311                                 }
01312                 }
01313                 else
01314                 {
01315                         gePuppet_StaticLightGrp.LightCount = 0;
01316                 }
01317 
01318                 //XING Studios code
01319                 gePuppet_StaticLightGrp.StaticLightCount = gePuppet_ComputeAmbientLight(P,
01320                                                                                                                                                            World,
01321                                                                                                                                                            &(gePuppet_StaticLightGrp.Ambient),
01322                                                                                                                                                            gePuppet_StaticLightGrp.StaticLights,
01323                                                                                                                                                            &(RootTransform.Translation));
01324                 NumFaces        = G->FaceCount;
01325                 List            = G->FaceList;
01326                 
01327                 // For each face, clip it to the view frustum supplied...
01328                 for (i=0; i<NumFaces; i++)
01329                 {
01330                         #define MAX_TEMP_VERTS          30              // To be safe...
01331 
01332                         int32                           Length1, Length2, v, p;
01333                         geVec3d                         Dest1[MAX_TEMP_VERTS], *pDest1;
01334                         geVec3d                         Dest2[MAX_TEMP_VERTS], *pDest2;
01335                         geVec3d                         Verts[MAX_TEMP_VERTS], *pVerts, v1, v2, v3;
01336                         Surf_TexVert            TexVerts[MAX_TEMP_VERTS], Tex1[MAX_TEMP_VERTS], *pTexVerts;
01337                         Surf_TexVert            Tex2[MAX_TEMP_VERTS], *pTex1, *pTex2;                   
01338                         Surf_TLVertex           ScreenPts[MAX_TEMP_VERTS];
01339                         GFX_Plane                       *FPlanes;
01340                         geBodyInst_Index                Command, Material;
01341                         gePuppet_Material       *PM;
01342                         geFloat                         Dist;
01343 
01344                         Command = *List;
01345                         List++;
01346                         Material = *List;
01347                         List ++;
01348                         
01349                         assert( Command == GE_BODYINST_FACE_TRIANGLE );
01350                         assert( Material>=0 );
01351                         assert( Material<P->MaterialCount);
01352 
01353                         PM = &(P->MaterialArray[Material]);
01354                         gePuppet_StaticLightGrp.MaterialColor = PM->Color;
01355 
01356                         Length1 = 3;                                    //FIXME:  I'm assuming numverts == 3
01357 
01358                         pVerts = Verts;
01359                         pTexVerts = TexVerts;
01360 
01361                         // AHHH!! Copy over till I get a better way...
01362                         for (v=0; v< Length1; v++, pVerts++, pTexVerts++)
01363                         {
01364                                 geBodyInst_SkinVertex   *SVert;
01365                                 GE_LVertex lvert;
01366 
01367                                 SVert = &G->SkinVertexArray[*List];
01368                                 List++;
01369 
01370                                 *pVerts = SVert->SVPoint;
01371 
01372                                 assert( ((geFloat)fabs(1.0-geVec3d_Length( &(G->NormalArray[ *List ] ))))< 0.001f );
01373                                                 
01374                                 gePuppet_StaticLightGrp.SurfaceNormal = (G->NormalArray[ *List ]);
01375                                                 
01376                                 List++;
01377 
01378                                 //gePuppet_SetVertexColor2(P,PM,&Ambient,SurfaceNormal, Lights,LightCount, pTexVerts);
01379                                 gePuppet_SetVertexColor(&lvert,SVert->ReferenceBoneIndex);
01380                                 pTexVerts->r = lvert.r;
01381                                 pTexVerts->g = lvert.g;
01382                                 pTexVerts->b = lvert.b;
01383                                 //Environment mapping code...
01384                                 if( P->internal_env.UseEnvironmentMapping )
01385                                 {
01386                                         pTexVerts->u = ( SVert->SVU * P->internal_env.PercentPuppet );
01387                                         pTexVerts->v = ( SVert->SVV * P->internal_env.PercentPuppet );
01388                                         
01389                                         if( P->internal_env.Supercede && PM->MaterialName[0] == 'g' )
01390                                         {
01391                                                 pTexVerts->u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentMaterial);
01392                                                 pTexVerts->v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentMaterial);
01393                                         }
01394                                         else
01395                                         {
01396                                                 pTexVerts->u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentEnvironment);
01397                                                 pTexVerts->v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentEnvironment);
01398                                         }
01399                                 }
01400                                 else
01401                                 {
01402                                         pTexVerts->u = SVert->SVU;
01403                                         pTexVerts->v = SVert->SVV;
01404                                         
01405                                         if( P->internal_env.Supercede && PM->MaterialName[0] == 'g' )
01406                                         {
01407                                                 pTexVerts->u += ( (G->NormalArray[ *List ]).X * P->internal_env.PercentMaterial);
01408                                                 pTexVerts->v += ( (G->NormalArray[ *List ]).Y * P->internal_env.PercentMaterial);
01409                                         }
01410                                 }
01411                         }
01412 
01413                         geVec3d_Subtract(&Verts[2], &Verts[1], &v1);
01414                         geVec3d_Subtract(&Verts[0], &Verts[1], &v2);
01415                         geVec3d_CrossProduct(&v1, &v2, &v3);
01416                         geVec3d_Normalize(&v3);
01417 
01418                         Dist = geVec3d_DotProduct(&v3, &Verts[0]);
01419 
01420                         Dist = geVec3d_DotProduct(&v3, geCamera_GetPov(Camera)) - Dist;
01421 
01422                         if (Dist <= 0)
01423                                 continue;
01424                         
01425                         pDest1 = Verts;
01426                         pDest2 = Dest2;
01427                         pTex1 = TexVerts;
01428                         pTex2 = Tex2;
01429 
01430                         FPlanes = FInfo->Planes;
01431 
01432                         for (p=0; p< FInfo->NumPlanes; p++, FPlanes++)
01433                         {
01434                                 if (!(ClipFlags & (1<<p)))
01435                                         continue;               // No need to clip...
01436 
01437                                 assert(Length1 < MAX_TEMP_VERTS);
01438 
01439                                 if (!Frustum_ClipToPlaneUVRGBA(FPlanes, pDest1, pDest2, pTex1, pTex2, Length1, &Length2))
01440                                         break;
01441 
01442                                 assert(Length2 < MAX_TEMP_VERTS);
01443                                 
01444                                 if (pDest1 == Dest2)
01445                                 {
01446                                         pDest1 = Dest1;
01447                                         pDest2 = Dest2;
01448                                         pTex1 = Tex1;
01449                                         pTex2 = Tex2;
01450                                 }
01451                                 else
01452                                 {
01453                                         pDest1 = Dest2;
01454                                         pDest2 = Dest1;
01455                                         pTex1 = Tex2;
01456                                         pTex2 = Tex1;
01457                                 }
01458                                 Length1 = Length2;
01459                         }
01460                         
01461                         assert(Length1 < MAX_TEMP_VERTS);
01462           
01463                         if (p != FInfo->NumPlanes)
01464                                 continue;                               // Can't possibly be visible
01465 
01466                         if (Length1 < 3)
01467                                 continue;                               // Can't possibly be visible
01468                         
01469                         // Transform to world space...
01470                         for (v=0; v<Length1; v++)
01471                                 geCamera_Transform(Camera, &pDest1[v], &pDest2[v]);
01472 
01473                         // Project the face, and combine tex coords into one structure (Clipped1)
01474                         Frustum_ProjectRGBA(pDest2, pTex1, (DRV_TLVertex*)ScreenPts, Length1, Camera);
01475 
01476                         // LWM_ACTOR_RENDERING
01477                         #if 1
01478                         ScreenPts[0].a = P->OverallAlpha ;
01479                         #else
01480                         ScreenPts[0].a = 255.0f;
01481                         #endif
01482 
01483                         geEngine_RenderPoly(Engine, (GE_TLVertex*)ScreenPts, Length1, PM->Bitmap, 0 );
01484                 }
01485         }
01486 
01487         #pragma message ("BUG:  Shadow caused crash in mirrors (oops).  Need to write a RenderShadowThroughFrustum...")
01488         /*
01489         if (P->DoShadow)
01490                 {
01491                         gePuppet_DrawShadow(P,Engine,World,Camera);
01492                 }
01493         */
01494         return GE_TRUE;
01495 }
01496 
01497 #ifdef PROFILE
01498 #define PUPPET_AVERAGE_ACROSS 60
01499 double Puppet_AverageCount[PUPPET_AVERAGE_ACROSS]={
01500         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
01501         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
01502         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
01503         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
01504         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
01505         0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
01506 int Puppet_AverageIndex = 0;
01507 #endif
01508 
01509 
01510 geBoolean GENESISCC gePuppet_Render(    const gePuppet *P, 
01511                                                         const gePose *Joints,
01512                                                         geEngine *Engine, 
01513                                                         geWorld *World, 
01514                                                         const geCamera *Camera, 
01515                                                         geExtBox *TestBox)
01516 {
01517         const geXFArray *JointTransforms;
01518         geVec3d Scale;
01519         #ifdef PROFILE
01520         rdtsc_timer_type RDTSCStart,RDTSCEnd;
01521         #endif
01522         geRect ClippingRect;
01523         geBoolean Clipping = GE_TRUE;
01524 
01525         char name[128];
01526         int i, j;
01527         geBoolean flag;
01528 
01529         #define BACK_EDGE (1.0f)
01530 
01531         const geBodyInst_Geometry *G;
01532         assert( P      );
01533         assert( Engine );
01534         assert( World  );
01535         assert( Camera );
01536 
01537         #ifdef PROFILE
01538         rdtsc_read(&RDTSCStart);
01539     rdtsc_zero(&RDTSCEnd);
01540         #endif
01541 
01542         flag = GE_FALSE;
01543         j = Engine->DriverInfo.NumSubDrivers;
01544         for(i=0;i<j;i++)
01545         {
01546                 strcpy(name, Engine->DriverInfo.SubDrivers[i].Name);
01547                 if(name[0]=='G')
01548                 {
01549                         flag = GE_TRUE;
01550                         break;
01551                 }
01552         }
01553         
01554 
01555         geCamera_GetClippingRect(Camera,&ClippingRect);
01556         
01557         if (TestBox != NULL)
01558         {
01559                 // see if the test box is visible on the screen.  If not: don't draw actor.
01560                 // (transform and project it to the screen, then check extents of that projection
01561                 //  against the clipping rect)
01562                 geVec3d BoxCorners[8];
01563                 const geXForm3d *ObjectToCamera;
01564                 geVec3d Maxs,Mins;
01565                 #define BIG_NUMBER (99e9f)  
01566                 int i;
01567                 geBoolean ZFarEnable;
01568                 geFloat ZFar;
01569 
01570                 BoxCorners[0] = TestBox->Min;
01571                 BoxCorners[1] = BoxCorners[0];  BoxCorners[1].X = TestBox->Max.X;
01572                 BoxCorners[2] = BoxCorners[0];  BoxCorners[2].Y = TestBox->Max.Y;
01573                 BoxCorners[3] = BoxCorners[0];  BoxCorners[3].Z = TestBox->Max.Z;
01574                 BoxCorners[4] = TestBox->Max;
01575                 BoxCorners[5] = BoxCorners[4];  BoxCorners[5].X = TestBox->Min.X;
01576                 BoxCorners[6] = BoxCorners[4];  BoxCorners[6].Y = TestBox->Min.Y;
01577                 BoxCorners[7] = BoxCorners[4];  BoxCorners[7].Z = TestBox->Min.Z;
01578 
01579                 ObjectToCamera = geCamera_GetCameraSpaceXForm(Camera);
01580                 assert( ObjectToCamera );
01581 
01582                 geVec3d_Set(&Maxs,-BIG_NUMBER,-BIG_NUMBER,-BIG_NUMBER);
01583                 geVec3d_Set(&Mins, BIG_NUMBER, BIG_NUMBER, BIG_NUMBER);
01584                 for (i=0; i<8; i++)
01585                 {
01586                         geVec3d V;
01587                         geXForm3d_Transform(  ObjectToCamera,&(BoxCorners[i]),&(BoxCorners[i]));
01588                         geCamera_Project(  Camera,&(BoxCorners[i]),&V);
01589                         if (V.X > Maxs.X ) Maxs.X = V.X;
01590                         if (V.X < Mins.X ) Mins.X = V.X;
01591                         if (V.Y > Maxs.Y ) Maxs.Y = V.Y;
01592                         if (V.Y < Mins.Y ) Mins.Y = V.Y;
01593                         if (V.Z > Maxs.Z ) Maxs.Z = V.Z;
01594                         if (V.Z < Mins.Z ) Mins.Z = V.Z;
01595                 }
01596                 
01597                 // Reject against ZFar clipplane if enabled...
01598                 geCamera_GetFarClipPlane(Camera, &ZFarEnable, &ZFar);
01599                 if (ZFarEnable) 
01600                 {
01601                         if ( (Maxs.X < ClippingRect.Left) 
01602                                 || (Mins.X > ClippingRect.Right)
01603                                 || (Maxs.Z < BACK_EDGE)                                 //Test X and Z first, and Y
01604                                 || (Mins.Z > ZFar)
01605                                 || (Maxs.Y < ClippingRect.Top) 
01606                                 || (Mins.Y > ClippingRect.Bottom))
01607                         {
01608                                 // not gonna draw: box is not visible.
01609                                 return GE_TRUE;
01610                         }
01611                         
01612                 } else 
01613                 {
01614                         if ( (Maxs.X < ClippingRect.Left) 
01615                                 || (Mins.X > ClippingRect.Right)
01616                                 || (Maxs.Y < ClippingRect.Top) 
01617                                 || (Mins.Y > ClippingRect.Bottom)
01618                                 || (Maxs.Z < BACK_EDGE))
01619                         {
01620                                 // not gonna draw: box is not visible.
01621                                 return GE_TRUE;
01622                         }
01623                 }
01624  
01625         } 
01626 
01627         Engine->DebugInfo.NumActors++;
01628 
01629         geTClip_SetupEdges(Engine,
01630                                                 (geFloat)ClippingRect.Left,
01631                                                 (geFloat)ClippingRect.Right,
01632                                                 (geFloat)ClippingRect.Top,
01633                                                 (geFloat)ClippingRect.Bottom,
01634                                                 BACK_EDGE);
01635                 
01636         JointTransforms = gePose_GetAllJointTransforms(Joints);
01637 
01638         #pragma message ("Level of detail hacked:")
01639         gePose_GetScale(Joints,&Scale);
01640         G = geBodyInst_GetGeometry(P->BodyInstance, &Scale, JointTransforms, 0,Camera);
01641 
01642         if ( G == NULL )
01643                 {
01644                         geErrorLog_Add(ERR_PUPPET_RENDER, NULL);
01645                         return GE_FALSE;
01646                 }
01647 
01648 #ifdef ONE_OVER_Z_PIPELINE
01649 #define TEST_Z_OUT(zzz, edge)           ((zzz) > (edge)) 
01650 #define TEST_Z_IN(zzz, edge)            ((zzz) < (edge)) 
01651 #pragma message ("test this! this is untested")
01652 #else
01653 #define TEST_Z_OUT(zzz, edge)           ((zzz) < (edge)) 
01654 #define TEST_Z_IN(zzz, edge)            ((zzz) > (edge)) 
01655 #endif
01656 
01657 
01658         // check for trivial rejection:
01659         {
01660                 if (   (G->Maxs.X < ClippingRect.Left) 
01661                         || (G->Mins.X > ClippingRect.Right)
01662                         || ( TEST_Z_OUT( G->Maxs.Z, BACK_EDGE) )                //test Y last
01663                         || (G->Maxs.Y < ClippingRect.Top) 
01664                         || (G->Mins.Y > ClippingRect.Bottom) )
01665                         {
01666                                 // not gonna draw
01667                                 return GE_TRUE;
01668                         }
01669 
01670                 if (   (G->Maxs.X < ClippingRect.Right) 
01671                         && (G->Mins.X > ClippingRect.Left)
01672                         && (G->Maxs.Y < ClippingRect.Bottom) 
01673                         && (G->Mins.Y > ClippingRect.Top)
01674                         && ( TEST_Z_IN( G->Mins.Z, BACK_EDGE) ) )
01675                         {
01676                                 // not gonna clip
01677                                 Clipping = GE_FALSE;
01678                         }
01679                 else
01680                         {
01681                                 Clipping = GE_TRUE;
01682                         } 
01683         }
01684 
01685         {
01686                 GE_LVertex v[3];
01687                 int i,j,Count;
01688                 geBodyInst_Index *List;
01689                 geBodyInst_Index Command;
01690                 geBodyInst_SkinVertex *SV;
01691                 geXForm3d RootTransform;
01692                 gePuppet_Material *PM;
01693                 geBodyInst_Index Material,LastMaterial;
01694 
01695                 gePuppet_StaticLightGrp.UseFillLight             = P->UseFillLight;
01696                 gePuppet_StaticLightGrp.FillLightNormal          = P->FillLightNormal;
01697                 gePuppet_StaticLightGrp.FillLightColor.Red       = P->FillLightColor.Red;
01698                 gePuppet_StaticLightGrp.FillLightColor.Green = P->FillLightColor.Green;
01699                 gePuppet_StaticLightGrp.FillLightColor.Blue  = P->FillLightColor.Blue;
01700                 gePuppet_StaticLightGrp.PerBoneLighting          = P->PerBoneLighting;
01701                 
01702                 gePose_GetJointTransform(Joints,P->LightReferenceBoneIndex,&(RootTransform));
01703 
01704                 if (P->MaxDynamicLightsToUse > 0)
01705                 {
01706                         if (P->PerBoneLighting)
01707                                 {
01708                                         int BoneCount;
01709                                         const geXForm3d *XFA = geXFArray_GetElements(JointTransforms, &BoneCount);
01710                                         if (BoneCount>0)
01711                                                 {
01712                                                         if (gePuppet_StaticBoneLightArraySize < BoneCount)
01713                                                                 {
01714                                                                         gePuppet_BoneLight *LG;
01715                                                         
01716                                                                         LG = geRam_Realloc(gePuppet_StaticBoneLightArray, sizeof(gePuppet_BoneLight) * BoneCount);
01717                                                                         if (LG==NULL)
01718                                                                                 {
01719                                                                                         geErrorLog_Add(ERR_PUPPET_RENDER,"Failed to allocate space for bone lighting info cache");
01720                                                                                         return GE_FALSE;
01721                                                                                 }
01722                                                                         gePuppet_StaticBoneLightArray = LG;
01723                                                                         gePuppet_StaticBoneLightArraySize = BoneCount;
01724                                                                 }
01725                                                         for (i=0; i<BoneCount; i++)
01726                                                                 {
01727                                                                         gePuppet_StaticBoneLightArray[i].LightCount = gePuppet_PrepLights(P,World,
01728                                                                                                 gePuppet_StaticBoneLightArray[i].Lights,&(XFA[i].Translation));
01729                                                                 }
01730                                                 }
01731                                 }
01732                         else
01733                                 {
01734                                         gePuppet_StaticLightGrp.LightCount = gePuppet_PrepLights(P,World
01735                                                                 ,gePuppet_StaticLightGrp.Lights,&(RootTransform.Translation));
01736                                 }
01737                 }
01738                 else
01739                 {
01740                         gePuppet_StaticLightGrp.LightCount = 0;
01741                 }
01742 
01743                 
01744    //XING Studios code
01745                 gePuppet_StaticLightGrp.StaticLightCount = gePuppet_ComputeAmbientLight(P,
01746                                                                                                                                                            World,
01747                                                                                                                                                            &(gePuppet_StaticLightGrp.Ambient),
01748                                                                                                                                                            gePuppet_StaticLightGrp.StaticLights ,
01749                                                                                                                                                            &(RootTransform.Translation));
01750                 Count = G->FaceCount;
01751                 List  = G->FaceList;
01752                 #if 1
01753                 v[0].a = v[1].a= v[2].a = P->OverallAlpha ;
01754                 #else
01755                 v[0].a = v[1].a= v[2].a = 255.0f;
01756                 #endif
01757 
01758                 LastMaterial = -1;
01759 
01760                 for (i=0; i<Count; i++)
01761                 {       
01762 
01763                         Command = *List;
01764                         List ++;
01765                         Material = *List;
01766                         List ++;
01767 
01768                         assert( Command == GE_BODYINST_FACE_TRIANGLE );
01769                         assert( Material>=0 );
01770                         assert( Material<P->MaterialCount);
01771 
01772                         {
01773                                 geFloat AX,AY,BXMinusAX,BYMinusAY,CYMinusAY,CXMinusAX;
01774                                 geBodyInst_Index *List2;
01775                                 
01776                                 List2 = List;
01777                                 SV = &(G->SkinVertexArray[ *List2 ]);
01778                                 AX = SV->SVPoint.X;
01779                                 AY = SV->SVPoint.Y;
01780                                 List2++;
01781                                 List2++;
01782                                 
01783                                 SV = &(G->SkinVertexArray[ *List2 ]);
01784                                 BXMinusAX = SV->SVPoint.X - AX;
01785                                 BYMinusAY = SV->SVPoint.Y - AY;
01786                                 List2++;
01787                                 List2++;
01788 
01789                                 SV = &(G->SkinVertexArray[ *List2 ]);
01790                                 CXMinusAX = SV->SVPoint.X - AX;
01791                                 CYMinusAY = SV->SVPoint.Y - AY;
01792                                 List2++;
01793                                 List2++;
01794 
01795                                 // ZCROSS is z the component of a 2d vector cross product of ABxAC
01796                                 //#define ZCROSS(Ax,Ay,Bx,By,Cx,Cy)  ((((Bx)-(Ax))*((Cy)-(Ay))) - (((By)-(Ay))*((Cx)-(Ax))))
01797 
01798                                 // 2d cross product of AB cross AC   (A is vtx[0], B is vtx[1], C is vtx[2]
01799                                 if ( ((BXMinusAX * CYMinusAY) - (BYMinusAY * CXMinusAX)) > 0.0f )
01800                                 {
01801                                         List = List2;
01802                                         continue;
01803                                 }
01804                         }
01805 
01806                         if ( Material != LastMaterial )
01807                         {
01808                                 PM = &(P->MaterialArray[Material]);
01809                                 geTClip_SetTexture(PM->Bitmap);
01810                                 gePuppet_StaticLightGrp.MaterialColor = PM->Color;
01811                         }
01812 
01813                         for (j=0; j<3; j++)
01814                         {
01815                                 SV = &(G->SkinVertexArray[ *List ]);
01816                                 List++;
01817 
01818                                 v[j].X = SV->SVPoint.X;
01819                                 v[j].Y = SV->SVPoint.Y;
01820 
01821                                 v[j].Z = SV->SVPoint.Z;
01822                                 v[j].u = SV->SVU;
01823                                 v[j].v = SV->SVV;
01824                                 
01825 //                              assert( ((geFloat)fabs(1.0-geVec3d_Length( &(G->NormalArray[ *List ] ))))< 0.001f );
01826                                 
01827                                 gePuppet_StaticLightGrp.SurfaceNormal = (G->NormalArray[ *List ]);
01828                                 List++;
01829 
01830                                 gePuppet_SetVertexColor(&(v[j]),SV->ReferenceBoneIndex);
01831                         }
01832                 
01833                         if(flag==GE_FALSE)
01834                                 Clipping = GE_FALSE;
01835 
01836                         if (Clipping)
01837                         {
01838                                 geTClip_Triangle(v);
01839                         }
01840                         else 
01841                         {
01842                                 geEngine_RenderPoly(Engine, (GE_TLVertex *)v, 3, PM->Bitmap, 0 );
01843                         }
01844 
01845                 }
01846                 assert( ((uint32)List) - ((uint32)G->FaceList) == (uint32)(G->FaceListSize) );
01847         }
01848 
01849 
01850         if (P->DoShadow)
01851         {
01852                 gePuppet_DrawShadow(P,Joints,Engine,World,Camera);
01853         }
01854 
01855 
01856         #ifdef PROFILE
01857         {
01858                 double Count=0.0;
01859                 int i;
01860 
01861                 rdtsc_read(&RDTSCEnd);
01862                 rdtsc_delta(&RDTSCStart,&RDTSCEnd,&RDTSCEnd);
01863                 geEngine_Printf(Engine, 320,10,"Puppet Render Time=%f",(double)(rdtsc_cycles(&RDTSCEnd)/200000000.0));
01864                 geEngine_Printf(Engine, 320,30,"Puppet Render Cycles=%f",(double)(rdtsc_cycles(&RDTSCEnd)));
01865                 #if 1
01866                 Puppet_AverageCount[(Puppet_AverageIndex++)%PUPPET_AVERAGE_ACROSS] = rdtsc_cycles(&RDTSCEnd);
01867                 for (i=0; i<PUPPET_AVERAGE_ACROSS; i++)
01868                         {       
01869                                 Count+=Puppet_AverageCount[i];
01870                         }
01871                 Count /= (double)PUPPET_AVERAGE_ACROSS;
01872 
01873                 geEngine_Printf(Engine, 320,60,"Puppet AVG Render Time=%f",(double)(Count/200000000.0));
01874                 geEngine_Printf(Engine, 320,90,"Puppet AVG Render Cycles=%f",(double)(Count));
01875                 #endif
01876                                 
01877         }
01878         #endif
01879 
01880         return GE_TRUE;
01881 }
01882 
01883 void GENESISCC gePuppet_SetShadow(gePuppet *P, geBoolean DoShadow, 
01884                 geFloat Scale, const geBitmap *ShadowMap,
01885                 int BoneIndex)
01886 {
01887         assert( P );
01888         assert( (DoShadow==GE_FALSE) || (DoShadow==GE_TRUE));
01889 
01890         if ( P->ShadowMap )
01891                 geBitmap_Destroy((geBitmap **)&(P->ShadowMap));
01892 
01893         P->DoShadow = DoShadow;
01894         P->ShadowScale = Scale;
01895         P->ShadowMap = ShadowMap;
01896         P->ShadowBoneIndex = BoneIndex;
01897 
01898         if ( P->ShadowMap )
01899                 geBitmap_CreateRef((geBitmap *)P->ShadowMap);
01900 }
01901 

Generated on Tue Sep 30 12:36:14 2003 for GTestAndEngine by doxygen 1.3.2