123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- #include "MLRHeaders.hpp"
- //#############################################################################
- //######################### MLRSpotLight ################################
- //#############################################################################
- MLRSpotLight::ClassData*
- MLRSpotLight::DefaultData = NULL;
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::InitializeClass()
- {
- Verify(!DefaultData);
- Verify(gos_GetCurrentHeap() == StaticHeap);
- DefaultData =
- new ClassData(
- MLRSpotLightClassID,
- "MidLevelRenderer::MLRSpotLight",
- MLRInfiniteLightWithFalloff::DefaultData
- );
- Register_Object(DefaultData);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::TerminateClass()
- {
- Unregister_Object(DefaultData);
- delete DefaultData;
- DefaultData = NULL;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLRSpotLight::MLRSpotLight() :
- MLRInfiniteLightWithFalloff(DefaultData)
- {
- Verify(gos_GetCurrentHeap() == Heap);
- lightMap = NULL;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLRSpotLight::MLRSpotLight(
- Stuff::MemoryStream *stream,
- int version
- ) :
- MLRInfiniteLightWithFalloff(DefaultData, stream, version)
- {
- Check_Object(stream);
- Verify(gos_GetCurrentHeap() == Heap);
- lightMap = NULL;
- if (version > 7)
- {
- MString name;
- *stream >> name;
- if (name.GetLength() > 0)
- {
- Check_Object(MLRTexturePool::Instance);
- MLRTexture *texture = (*MLRTexturePool::Instance)(name, 0);
- if (!texture)
- texture = MLRTexturePool::Instance->Add(name, 0);
- Check_Object(texture);
- lightMap = new MLRLightMap(texture);
- Check_Object(lightMap);
- lightMask |= MLRState::LightMapLightingMode;
- }
- }
- Radian angle;
- *stream >> angle;
- SetSpreadAngle(angle);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLRSpotLight::MLRSpotLight(Stuff::Page *page):
- MLRInfiniteLightWithFalloff(DefaultData, page)
- {
- Check_Object(page);
- Verify(gos_GetCurrentHeap() == Heap);
- lightMap = NULL;
- const char* lightmap;
- if (page->GetEntry("LightMap", &lightmap))
- {
- Check_Pointer(lightmap);
- Check_Object(MLRTexturePool::Instance);
- MLRTexture *texture = (*MLRTexturePool::Instance)(lightmap, 0);
- if (!texture)
- texture = MLRTexturePool::Instance->Add(lightmap, 0);
- Check_Object(texture);
- lightMap = new MLRLightMap(texture);
- Check_Object(lightMap);
- lightMask |= MLRState::LightMapLightingMode;
- }
- Degree angle=45.0;
- page->GetEntry("Spread", &angle.angle);
- SetSpreadAngle(angle);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLRSpotLight::~MLRSpotLight()
- {
- if (lightMap)
- {
- Check_Object(lightMap);
- delete lightMap;
- }
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::Save(Stuff::MemoryStream *stream)
- {
- Check_Object(this);
- Check_Object(stream);
- MLRInfiniteLightWithFalloff::Save(stream);
- if (lightMap)
- {
- Check_Object(lightMap);
- unsigned handle = lightMap->GetState().GetTextureHandle();
- MLRTexture *texture = (*MLRTexturePool::Instance)[handle];
- Check_Object(texture);
- MString name = texture->GetTextureName();
- *stream << name;
- }
- else
- *stream << MString("");
- *stream << spreadAngle;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::Write(Stuff::Page *page)
- {
- Check_Object(this);
- Check_Object(page);
- MLRInfiniteLightWithFalloff::Write(page);
- if (lightMap)
- {
- Check_Object(lightMap);
- unsigned handle = lightMap->GetState().GetTextureHandle();
- MLRTexture *texture = (*MLRTexturePool::Instance)[handle];
- Check_Object(texture);
- page->SetEntry("LightMap", texture->GetTextureName());
- }
- page->SetEntry("Spread", spreadAngle * Degrees_Per_Radian);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::TestInstance()
- {
- Verify(IsDerivedFrom(DefaultData));
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::SetSpreadAngle(const Radian &radian)
- {
- Check_Object(this);
- spreadAngle = radian;
- tanSpreadAngle = (Scalar)tan(spreadAngle);
- cosSpreadAngle = (Scalar)cos(spreadAngle);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::SetSpreadAngle(const Degree °ree)
- {
- Check_Object(this);
- spreadAngle = degree;
- tanSpreadAngle = (Scalar)tan(spreadAngle);
- cosSpreadAngle = (Scalar)cos(spreadAngle);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- bool
- MLRSpotLight::GetSpreadAngle(Radian *angle)
- {
- Check_Object(this);
- *angle = spreadAngle;
- return true;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::LightVertex(const MLRVertexData& vertexData)
- {
- UnitVector3D light_z;
- RGBColor light_color(color);
- Point3D vertex_to_light;
- Verify(GetFalloffDistance(vertex_to_light.x, vertex_to_light.y));
- GetInShapePosition(vertex_to_light);
- vertex_to_light -= *vertexData.point;
- //
- //--------------------------------------------------------------
- // If the distance to the vertex is zero, the light will not
- // contribute to the vertex coloration. Otherwise, decrease the
- // light level as appropriate to the distance
- //--------------------------------------------------------------
- //
- Scalar length = vertex_to_light.GetApproximateLength();
- Scalar falloff = 1.0f;
- if(GetFalloff(length, falloff))
- {
- light_color.red *= falloff;
- light_color.green *= falloff;
- light_color.blue *= falloff;
- }
- else
- {
- return;
- }
- Scalar cos_spread_angle = GetCosSpreadAngle();
- GetInWorldDirection(light_z);
- length = -1.0f / length;
- vertex_to_light *= length;
-
- Scalar t = vertex_to_light * light_z;
-
- if (t <= cos_spread_angle)
- {
- return;
- }
- /* Verify(!Close_Enough(cos_spread_angle, 1.0f));
-
- spread = 1.0f - ((1.0f - t) / (1.0f - cos_spread_angle));
-
- light_color.red *= cos_spread_angle;
- light_color.green *= cos_spread_angle;
- light_color.blue *= cos_spread_angle;
- */
- light_z.x = vertex_to_light.x;
- light_z.y = vertex_to_light.y;
- light_z.z = vertex_to_light.z;
- //
- //-------------------------------------------------------------------
- // Now we reduce the light level falling on the vertex based upon the
- // cosine of the angle between light and normal
- //-------------------------------------------------------------------
- //
- Scalar cosine = -(light_z * (*vertexData.normal)) * intensity;
- #if COLOR_AS_DWORD
- #else
- if (cosine > SMALL)
- {
- light_color.red *= cosine;
- light_color.green *= cosine;
- light_color.blue *= cosine;
- vertexData.color->red += light_color.red;
- vertexData.color->green += light_color.green;
- vertexData.color->blue += light_color.blue;
- }
- #endif
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLRSpotLight::SetLightMap(MLRLightMap *light_map)
- {
- Check_Object(this);
- if (lightMap)
- {
- Check_Object(lightMap);
- delete lightMap;
- }
- lightMap = light_map;
- if (lightMap == NULL)
- {
- lightMask &= ~MLRState::LightMapLightingMode;
- }
- else
- {
- Check_Object(light_map);
- lightMask |= MLRState::LightMapLightingMode;
- }
- }
|