00001 #define WIN32_LEAN_AND_MEAN
00002 #include <windows.h>
00003
00004 #include <math.h>
00005 #include <stdlib.h>
00006 #include <assert.h>
00007
00008 #define BUILD_DYNLIGHT
00009 #include "Dynlight.h"
00010 #include "errorlog.h"
00011
00012 static geBoolean DynLight_SetWorld(geWorld *World, geVFile *Context);
00013
00014 geBoolean DynLight_Init(geEngine *Engine, geWorld *World, geVFile *Context)
00015 {
00016
00017 if (!DynLight_SetWorld(World, Context))
00018 return GE_FALSE;
00019
00020 return GE_TRUE;
00021 }
00022
00023 geBoolean DynLight_Reset(geWorld *World)
00024 {
00025 geEntity_EntitySet * Set;
00026 geEntity * Entity;
00027
00028 if (!World)
00029 return GE_TRUE;
00030
00031 Set = geWorld_GetEntitySet(World, "DynamicLight");
00032 if (Set == NULL)
00033 return GE_TRUE;
00034
00035 Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00036 while (Entity)
00037 {
00038 DynamicLight * Light;
00039
00040 Light = geEntity_GetUserData(Entity);
00041 Light->LastTime = 0.0f;
00042
00043 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00044 }
00045
00046 return GE_TRUE;
00047 }
00048
00049 geBoolean DynLight_Shutdown(void)
00050 {
00051 return GE_TRUE;
00052 }
00053
00054 geBoolean DynLight_Frame(geWorld *World, const geXForm3d *XForm, geFloat DeltaTime)
00055 {
00056 geEntity_EntitySet * Set;
00057 geEntity * Entity;
00058
00059 if (World == NULL)
00060 return GE_TRUE;
00061
00062 Set = geWorld_GetEntitySet(World, "DynamicLight");
00063 if (Set == NULL)
00064 return GE_TRUE;
00065
00066 Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00067 while (Entity)
00068 {
00069 DynamicLight * Light;
00070 geFloat Radius;
00071 geFloat Percentage;
00072 int Index;
00073 geVec3d Pos;
00074
00075 Light = geEntity_GetUserData(Entity);
00076 assert(Light->DynLight);
00077
00078
00079 if (Light->Model)
00080 {
00081 geXForm3d XForm;
00082
00083
00084 geWorld_GetModelXForm(World, Light->Model, &XForm);
00085
00086 Pos = Light->origin;
00087 if (Light->AllowRotation)
00088 {
00089 geVec3d Center;
00090
00091
00092 geWorld_GetModelRotationalCenter(World, Light->Model, &Center);
00093 geVec3d_Subtract(&Pos, &Center, &Pos);
00094 geXForm3d_Transform(&XForm, &Pos, &Pos);
00095 geVec3d_Add(&Pos, &Center, &Pos);
00096 }
00097 else
00098 geVec3d_Add(&Pos, &XForm.Translation, &Pos);
00099 }
00100 else
00101 {
00102 Pos = Light->origin;
00103 }
00104
00105 assert(Light->RadiusSpeed > Light->LastTime);
00106 Percentage = Light->LastTime / Light->RadiusSpeed;
00107
00108 Index = (int)(Percentage * Light->NumFunctionValues);
00109 assert(Index < Light->NumFunctionValues);
00110 assert(Light->RadiusFunction[Index] >= 'a' && Light->RadiusFunction[Index] <= 'z');
00111
00112 if (Light->InterpolateValues && Index < Light->NumFunctionValues - 1)
00113 {
00114 geFloat Remainder;
00115 geFloat InterpolationPercentage;
00116 int DeltaValue;
00117 geFloat Value;
00118
00119 Remainder = (geFloat)fmod(Light->LastTime, Light->IntervalWidth);
00120 InterpolationPercentage = Remainder / Light->IntervalWidth;
00121
00122 DeltaValue = Light->RadiusFunction[Index + 1] - Light->RadiusFunction[Index];
00123 Value = Light->RadiusFunction[Index] + DeltaValue * InterpolationPercentage;
00124 Percentage = ((geFloat)(Value - 'a')) / ((geFloat)('z' - 'a'));
00125 }
00126 else
00127 {
00128 Percentage = ((geFloat)(Light->RadiusFunction[Index] - 'a')) / ((geFloat)('z' - 'a'));
00129 }
00130
00131 Radius = Percentage * (Light->MaxRadius - Light->MinRadius) + Light->MinRadius;
00132
00133 geWorld_SetLightAttributes(World,
00134 Light->DynLight,
00135 &Pos,
00136 &Light->Color,
00137 Radius,
00138 GE_TRUE);
00139
00140 Light->LastTime = (geFloat)fmod(Light->LastTime + DeltaTime, Light->RadiusSpeed);
00141
00142 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00143 }
00144
00145 return GE_TRUE;
00146 }
00147
00148 static geBoolean DynLight_SetWorld(geWorld *World, geVFile *Context)
00149 {
00150 geEntity_EntitySet * Set;
00151 geEntity * Entity;
00152
00153 Context;
00154
00155 if (World == NULL)
00156 return GE_TRUE;
00157
00158 Set = geWorld_GetEntitySet(World, "DynamicLight");
00159 if (Set == NULL)
00160 return GE_TRUE;
00161
00162 Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00163 while (Entity)
00164 {
00165 DynamicLight * Light;
00166 #define MAX_NAME 200
00167 char EntityName[MAX_NAME];
00168
00169 geEntity_GetName(Entity, EntityName, MAX_NAME-1);
00170 EntityName[MAX_NAME-1]=0;
00171
00172 Light = geEntity_GetUserData(Entity);
00173 Light->NumFunctionValues = strlen(Light->RadiusFunction);
00174 if (Light->NumFunctionValues == 0)
00175 {
00176 geErrorLog_AddString(0,"DynLight_SetWorld: DynamicLight has no RadiusFunction string:",EntityName);
00177 return GE_FALSE;
00178 }
00179 Light->IntervalWidth = Light->RadiusSpeed / (geFloat)Light->NumFunctionValues;
00180 Light->DynLight = geWorld_AddLight(World);
00181 if (!Light->DynLight)
00182 {
00183 geErrorLog_AddString(0,"DynLight_SetWorld: DynamicLight failed to create light in world:",EntityName);
00184 return GE_FALSE;
00185 }
00186
00187 Entity = geEntity_EntitySetGetNextEntity(Set, Entity);
00188 }
00189
00190 return GE_TRUE;
00191 }