MLRLookUpLight.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "MLRHeaders.hpp"
  5. //#############################################################################
  6. //######################### MLRLookUpLight ################################
  7. //#############################################################################
  8. MLRLookUpLight::ClassData*
  9. MLRLookUpLight::DefaultData = NULL;
  10. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11. //
  12. void
  13. MLRLookUpLight::InitializeClass()
  14. {
  15. Verify(!DefaultData);
  16. Verify(gos_GetCurrentHeap() == StaticHeap);
  17. DefaultData =
  18. new ClassData(
  19. MLRLookUpLightClassID,
  20. "MidLevelRenderer::MLRLookUpLight",
  21. MLRInfiniteLight::DefaultData
  22. );
  23. Check_Object(DefaultData);
  24. }
  25. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26. //
  27. void
  28. MLRLookUpLight::TerminateClass()
  29. {
  30. Check_Object(DefaultData);
  31. delete DefaultData;
  32. DefaultData = NULL;
  33. }
  34. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. //
  36. MLRLookUpLight::MLRLookUpLight() :
  37. MLRInfiniteLight(DefaultData)
  38. {
  39. Verify(gos_GetCurrentHeap() == Heap);
  40. mapOrigin.x = 0.0f;
  41. mapOrigin.y = 0.0f;
  42. mapOrigin.z = 0.0f;
  43. mapZoneCountX = 1, mapZoneCountZ = 1;
  44. zoneSizeX = 1260.0f, zoneSizeZ = 1260.0f;
  45. one_Over_zoneSizeX = 1.0f/zoneSizeX;
  46. one_Over_zoneSizeZ = 1.0f/zoneSizeZ;
  47. maps = NULL;
  48. mapName = "";
  49. }
  50. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  51. //
  52. MLRLookUpLight::MLRLookUpLight(
  53. Stuff::MemoryStream *stream,
  54. int version
  55. ) :
  56. MLRInfiniteLight(DefaultData, stream, version)
  57. {
  58. Check_Object(stream);
  59. Verify(gos_GetCurrentHeap() == Heap);
  60. *stream >> mapOrigin;
  61. *stream >> mapZoneCountX >> mapZoneCountZ;
  62. *stream >> zoneSizeX >> zoneSizeZ;
  63. *stream >> mapName;
  64. one_Over_zoneSizeX = 1.0f/zoneSizeX;
  65. one_Over_zoneSizeZ = 1.0f/zoneSizeZ;
  66. maps = new unsigned char * [mapZoneCountX * mapZoneCountZ];
  67. Check_Pointer(maps);
  68. for(int i=0;i<mapZoneCountX*mapZoneCountZ;i++)
  69. {
  70. maps[i] = new unsigned char [256*256];
  71. Check_Pointer(maps[i]);
  72. stream->ReadBytes(maps[i], 256*256);
  73. }
  74. }
  75. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  76. //
  77. MLRLookUpLight::MLRLookUpLight(Stuff::Page *page):
  78. MLRInfiniteLight(DefaultData, page)
  79. {
  80. Check_Object(page);
  81. Verify(gos_GetCurrentHeap() == Heap);
  82. maps = NULL;
  83. const char *data;
  84. mapOrigin.x = 0.0f;
  85. mapOrigin.y = 0.0f;
  86. mapOrigin.z = 0.0f;
  87. if (page->GetEntry("MapOrigin", &data))
  88. {
  89. sscanf(data, "%f %f %f", &mapOrigin.x, &mapOrigin.y, &mapOrigin.z);
  90. }
  91. mapZoneCountX = 1, mapZoneCountZ = 1;
  92. if(page->GetEntry("MapSize", &data))
  93. {
  94. sscanf(data, "%d %d", &mapZoneCountX, &mapZoneCountZ);
  95. }
  96. zoneSizeX = 1280.0f, zoneSizeZ = 1280.0f;
  97. if(page->GetEntry("ZoneSize", &data))
  98. {
  99. sscanf(data, "%f %f", &zoneSizeX, &zoneSizeX);
  100. }
  101. one_Over_zoneSizeX = 1.0f/zoneSizeX;
  102. one_Over_zoneSizeZ = 1.0f/zoneSizeZ;
  103. mapName = "";
  104. if(page->GetEntry("MapName", &data))
  105. {
  106. mapName = data;
  107. }
  108. LoadMap();
  109. }
  110. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  111. //
  112. MLRLookUpLight::~MLRLookUpLight()
  113. {
  114. if(maps!=NULL)
  115. {
  116. for(int i=0;i<mapZoneCountX*mapZoneCountZ;i++)
  117. {
  118. Check_Pointer(maps[i]);
  119. delete [] maps[i];
  120. maps[i] = NULL;
  121. }
  122. Check_Pointer(maps);
  123. delete [] maps;
  124. maps = NULL;
  125. }
  126. }
  127. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  128. //
  129. void
  130. MLRLookUpLight::Save(Stuff::MemoryStream *stream)
  131. {
  132. Check_Object(this);
  133. Check_Object(stream);
  134. MLRInfiniteLight::Save(stream);
  135. *stream << mapOrigin;
  136. *stream << mapZoneCountX << mapZoneCountZ;
  137. *stream << zoneSizeX << zoneSizeZ;
  138. *stream << mapName;
  139. for(int i=0;i<mapZoneCountX*mapZoneCountZ;i++)
  140. {
  141. stream->WriteBytes(maps[i], 256*256);
  142. }
  143. }
  144. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  145. //
  146. void
  147. MLRLookUpLight::Write(Stuff::Page *page)
  148. {
  149. Check_Object(this);
  150. Check_Object(page);
  151. MLRInfiniteLight::Write(page);
  152. char data[256];
  153. sprintf(data, "%f %f %f", mapOrigin.x, mapOrigin.y, mapOrigin.z);
  154. Verify(strlen(data) < sizeof(data));
  155. page->SetEntry("MapOrigin", data);
  156. sprintf(data, "%d %d", mapZoneCountX, mapZoneCountZ);
  157. Verify(strlen(data) < sizeof(data));
  158. page->SetEntry("MapSize", data);
  159. sprintf(data, "%f %f", zoneSizeX, zoneSizeZ);
  160. Verify(strlen(data) < sizeof(data));
  161. page->SetEntry("ZoneSize", data);
  162. page->SetEntry("MapName", mapName);
  163. }
  164. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165. //
  166. void
  167. MLRLookUpLight::SetMapSizeAndName(int x, int z, const char *name)
  168. {
  169. Check_Object(this);
  170. if(maps!=NULL)
  171. {
  172. for(int i=0;i<mapZoneCountX*mapZoneCountZ;i++)
  173. {
  174. Check_Pointer(maps[i]);
  175. delete [] maps[i];
  176. maps[i] = NULL;
  177. }
  178. Check_Pointer(maps);
  179. delete [] maps;
  180. maps = NULL;
  181. }
  182. mapZoneCountX = x;
  183. mapZoneCountZ = z;
  184. mapName = name;
  185. LoadMap();
  186. }
  187. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  188. //
  189. bool
  190. MLRLookUpLight::LoadMap()
  191. {
  192. Check_Object(this);
  193. Stuff::FileStream element_stream(mapName);
  194. unsigned char *map = new unsigned char [mapZoneCountX*mapZoneCountZ*256*256];
  195. Check_Pointer(map);
  196. element_stream.ReadBytes(map, mapZoneCountX*mapZoneCountZ*256*256);
  197. Verify(maps==NULL);
  198. maps = new unsigned char * [mapZoneCountX * mapZoneCountZ];
  199. Check_Pointer(maps);
  200. int i, j, k;
  201. for(j=0;j<mapZoneCountZ;j++)
  202. {
  203. for(i=0;i<mapZoneCountX;i++)
  204. {
  205. maps[j*mapZoneCountX+i] = new unsigned char [256*256];
  206. Check_Pointer(maps[j*mapZoneCountX+i]);
  207. }
  208. }
  209. unsigned char *uptr = map;
  210. for(j=0;j<mapZoneCountZ;j++)
  211. {
  212. for(k=0;k<256;k++)
  213. {
  214. for(i=0;i<mapZoneCountX;i++)
  215. {
  216. Mem_Copy(&maps[j*mapZoneCountX+i][k*256], uptr, 256, (256-k)*256);
  217. uptr += 256;
  218. // &map[(256*j+k)*(mapZoneCountX*256) + i*256]
  219. }
  220. }
  221. }
  222. Check_Pointer(map);
  223. delete map;
  224. return false;
  225. }
  226. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  227. //
  228. void
  229. MLRLookUpLight::SetLightToShapeMatrix(const LinearMatrix4D& worldToShape)
  230. {
  231. Check_Object(this);
  232. lightToShape.Multiply(lightToWorld, worldToShape);
  233. shapeToWorld.Invert(worldToShape);
  234. }
  235. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  236. //
  237. void
  238. MLRLookUpLight::TestInstance()
  239. {
  240. Verify(IsDerivedFrom(DefaultData));
  241. }
  242. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  243. //
  244. void
  245. MLRLookUpLight::LightVertex(const MLRVertexData& vertexData)
  246. {
  247. UnitVector3D light_z;
  248. GetInShapeDirection(light_z);
  249. const Scalar One_Over_255 = 1.f/255.0f;
  250. Point3D worldPoint;
  251. worldPoint.Multiply(*(vertexData.point), shapeToWorld);
  252. Scalar prep_x = mapZoneCountX*zoneSizeX - worldPoint.x + mapOrigin.x;
  253. Scalar prep_z = mapZoneCountZ*zoneSizeZ - worldPoint.z + mapOrigin.z;
  254. int map_x = Truncate_Float_To_Word(prep_x*one_Over_zoneSizeX);
  255. int map_z = Truncate_Float_To_Word(prep_z*one_Over_zoneSizeZ);
  256. Verify(map_x>=0 && map_x<mapZoneCountX);
  257. Verify(map_z>=0 && map_z<mapZoneCountZ);
  258. int off_x = Truncate_Float_To_Word((prep_x - map_x*zoneSizeX)*256.0f*one_Over_zoneSizeX);
  259. int off_z = Truncate_Float_To_Word((prep_z - map_z*zoneSizeZ)*256.0f*one_Over_zoneSizeZ);
  260. Verify(off_x>=0 && off_x < 256);
  261. Verify(off_z>=0 && off_z < 256);
  262. Scalar mapIntensity = maps[map_z*mapZoneCountX+map_x][(off_z<<8)+off_x]*One_Over_255;
  263. //
  264. //-------------------------------------------------------------------
  265. // Now we reduce the light level falling on the vertex based upon the
  266. // cosine of the angle between light and normal
  267. //-------------------------------------------------------------------
  268. //
  269. Scalar cosine = -(light_z * (*vertexData.normal))*mapIntensity*intensity;
  270. #if COLOR_AS_DWORD
  271. TO_DO;
  272. #else // COLOR_AS_DWORD
  273. RGBColor light_color(color);
  274. if (cosine > SMALL)
  275. {
  276. light_color.red *= cosine;
  277. light_color.green *= cosine;
  278. light_color.blue *= cosine;
  279. vertexData.color->red += light_color.red;
  280. vertexData.color->green += light_color.green;
  281. vertexData.color->blue += light_color.blue;
  282. }
  283. #endif // COLOR_AS_DWORD
  284. }