#include "MLRHeaders.hpp" //############################################################################# //######################### MLRLookUpLight ################################ //############################################################################# MLRLookUpLight::ClassData* MLRLookUpLight::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLRLookUpLightClassID, "MidLevelRenderer::MLRLookUpLight", MLRInfiniteLight::DefaultData ); Check_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::TerminateClass() { Check_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRLookUpLight::MLRLookUpLight() : MLRInfiniteLight(DefaultData) { Verify(gos_GetCurrentHeap() == LightsHeap); mapOrigin.x = 0.0f; mapOrigin.y = 0.0f; mapOrigin.z = 0.0f; mapZoneCountX = 1, mapZoneCountZ = 1; zoneSizeX = 1260.0f, zoneSizeZ = 1260.0f; one_Over_zoneSizeX = 1.0f/zoneSizeX; one_Over_zoneSizeZ = 1.0f/zoneSizeZ; shadowIntensity = 0.5f; maps = NULL; mapName = *MString::s_Empty; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRLookUpLight::MLRLookUpLight( Stuff::MemoryStream *stream, int version ) : MLRInfiniteLight(DefaultData, stream, version) { Check_Object(stream); Verify(gos_GetCurrentHeap() == LightsHeap); *stream >> mapOrigin; *stream >> mapZoneCountX >> mapZoneCountZ; *stream >> zoneSizeX >> zoneSizeZ; *stream >> mapName; one_Over_zoneSizeX = 1.0f/zoneSizeX; one_Over_zoneSizeZ = 1.0f/zoneSizeZ; if(version>16) { *stream >> shadowIntensity; } else { shadowIntensity = 0.5f; } maps = new BYTE * [mapZoneCountX * mapZoneCountZ]; Check_Pointer(maps); for(int i=0;i(stream->GetPointer()); stream->AdvancePointer(256*32); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRLookUpLight::MLRLookUpLight(Stuff::Page *page): MLRInfiniteLight(DefaultData, page) { Check_Object(page); Verify(gos_GetCurrentHeap() == LightsHeap); maps = NULL; const char *data; mapOrigin.x = 0.0f; mapOrigin.y = 0.0f; mapOrigin.z = 0.0f; if (page->GetEntry("MapOrigin", &data)) { sscanf(data, "%f %f %f", &mapOrigin.x, &mapOrigin.y, &mapOrigin.z); } mapZoneCountX = 1, mapZoneCountZ = 1; if(page->GetEntry("MapSize", &data)) { sscanf(data, "%d %d", &mapZoneCountX, &mapZoneCountZ); } zoneSizeX = 1280.0f, zoneSizeZ = 1280.0f; if(page->GetEntry("ZoneSize", &data)) { sscanf(data, "%f %f", &zoneSizeX, &zoneSizeX); } one_Over_zoneSizeX = 1.0f/zoneSizeX; one_Over_zoneSizeZ = 1.0f/zoneSizeZ; shadowIntensity = 0.5f; page->GetEntry("ShadowIntensity", &shadowIntensity); mapName = *MString::s_Empty; if(page->GetEntry("MapName", &data)) { mapName = data; } LoadMap(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRLookUpLight::~MLRLookUpLight() { if(maps!=NULL) { for(int i=0;iWriteBytes(maps[i], 256*32); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::Write(Stuff::Page *page) { Check_Object(this); Check_Object(page); MLRInfiniteLight::Write(page); char data[256]; sprintf(data, "%f %f %f", mapOrigin.x, mapOrigin.y, mapOrigin.z); Verify(strlen(data) < sizeof(data)); page->SetEntry("MapOrigin", data); sprintf(data, "%d %d", mapZoneCountX, mapZoneCountZ); Verify(strlen(data) < sizeof(data)); page->SetEntry("MapSize", data); sprintf(data, "%f %f", zoneSizeX, zoneSizeZ); Verify(strlen(data) < sizeof(data)); page->SetEntry("ZoneSize", data); page->SetEntry("ShadowIntensity", shadowIntensity); page->SetEntry("MapName", mapName); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::SetMapSizeAndName(int x, int z, const char *name) { Check_Object(this); if(maps!=NULL) { for(int i=0;i>=1) { if(*uptr++>128) { maps[j*mapZoneCountX+i][k*32+l] |= mask; } } // Mem_Copy(&maps[j*mapZoneCountX+i][k*256], uptr, 256, (256-k)*256); // uptr += 256; // &map[(256*j+k)*(mapZoneCountX*256) + i*256] } } } } Check_Pointer(map); delete map; return false; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::SetLightToShapeMatrix(const LinearMatrix4D& worldToShape) { Check_Object(this); lightToShape.Multiply(lightToWorld, worldToShape); shapeToWorld.Invert(worldToShape); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::TestInstance() { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::LightVertex(const MLRVertexData& vertexData) { UnitVector3D light_z; GetInShapeDirection(light_z); // const Scalar One_Over_255 = 1.f/255.0f; Point3D worldPoint; worldPoint.Multiply(*(vertexData.point), shapeToWorld); Scalar prep_x = mapZoneCountX*zoneSizeX - worldPoint.x - mapOrigin.x; Scalar prep_z = mapZoneCountZ*zoneSizeZ - worldPoint.z - mapOrigin.z; if(prep_x < 0) { prep_x = 0; } int map_x = Truncate_Float_To_Word(prep_x*one_Over_zoneSizeX); if(prep_z < 0) { prep_z = 0; } int map_z = Truncate_Float_To_Word(prep_z*one_Over_zoneSizeZ); if(map_x>=mapZoneCountX) { map_x = mapZoneCountX-1; } if(map_z>=mapZoneCountZ) { map_z = mapZoneCountZ-1; } // Verify(map_x>=0 && map_x=0 && map_z255) { off_x = 255; } if(off_z < 0) { off_z = 0; } if(off_z>255) { off_z = 255; } // Verify(off_x>=0 && off_x < 256); // Verify(off_z>=0 && off_z < 256); BYTE b = maps[map_z*mapZoneCountX+map_x][(off_z<<5) + (off_x>>3)]; Scalar mapIntensity = b & (0x80>>(off_x&7)) ? intensity : shadowIntensity; // //------------------------------------------------------------------- // Now we reduce the light level falling on the vertex based upon the // cosine of the angle between light and normal //------------------------------------------------------------------- // Scalar cosine = mapIntensity; if(vertexData.normal!=NULL) { cosine = -(light_z * (*vertexData.normal))*mapIntensity; } RGBColor light_color(color); if (cosine > SMALL) { light_color.red *= cosine; light_color.green *= cosine; light_color.blue *= cosine; Stuff::RGBAColor *t = const_cast(vertexData.color); Check_Pointer(t); t->red += light_color.red; t->green += light_color.green; t->blue += light_color.blue; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRLookUpLight::LightCenter(RGBAColor& rcol) { UnitVector3D light_z; GetInShapeDirection(light_z); // const Scalar One_Over_255 = 1.f/255.0f; Point3D worldPoint; worldPoint = shapeToWorld; Scalar prep_x = mapZoneCountX*zoneSizeX - worldPoint.x - mapOrigin.x; Scalar prep_z = mapZoneCountZ*zoneSizeZ - worldPoint.z - mapOrigin.z; if(prep_x < 0.0f) { prep_x = 0.0f; } int map_x = Truncate_Float_To_Word(prep_x*one_Over_zoneSizeX); if(prep_z < 0.0f) { prep_z = 0.0f; } int map_z = Truncate_Float_To_Word(prep_z*one_Over_zoneSizeZ); if(map_x>=mapZoneCountX) { map_x = mapZoneCountX-1; } if(map_z>=mapZoneCountZ) { map_z = mapZoneCountZ-1; } // Verify(map_x>=0 && map_x=0 && map_z255) { off_x = 255; } if(off_z < 0) { off_z = 0; } if(off_z>255) { off_z = 255; } // Verify(off_x>=0 && off_x < 256); // Verify(off_z>=0 && off_z < 256); // Scalar mapIntensity = maps[map_z*mapZoneCountX+map_x][(off_z<<8)+off_x]*One_Over_255; BYTE b = maps[map_z*mapZoneCountX+map_x][(off_z<<5)+(off_x>>3)]; Scalar mapIntensity = b & (0x80>>(off_x&3)) ? intensity : shadowIntensity; // //------------------------------------------------------------------- // Now we reduce the light level falling on the vertex based upon the // cosine of the angle between light and normal //------------------------------------------------------------------- // Scalar cosine = mapIntensity; RGBColor light_color(color); if (cosine > SMALL) { light_color.red *= cosine; light_color.green *= cosine; light_color.blue *= cosine; rcol.red += light_color.red; rcol.green += light_color.green; rcol.blue += light_color.blue; } }