#include "MLRHeaders.hpp" //############################################################################# //############### MLRInfiniteLightWithFalloff ########################### //############################################################################# MLRInfiniteLightWithFalloff::ClassData* MLRInfiniteLightWithFalloff::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLRInfiniteLightWithFalloffClassID, "MidLevelRenderer::MLRInfiniteLightWithFalloff", MLRLight::DefaultData ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRInfiniteLightWithFalloff::MLRInfiniteLightWithFalloff(ClassData *class_data) : MLRLight(class_data) { Verify(gos_GetCurrentHeap() == LightsHeap); lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode; innerRadius = 0.0f; outerRadius = 0.0f; oneOverDistance = 100.0f; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRInfiniteLightWithFalloff::MLRInfiniteLightWithFalloff( ClassData *class_data, Stuff::MemoryStream *stream, int version ) : MLRLight(class_data, stream, version) { Check_Object(stream); Verify(gos_GetCurrentHeap() == LightsHeap); lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode; Scalar inner, outer; *stream >> inner >> outer; SetFalloffDistance (inner, outer); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRInfiniteLightWithFalloff::MLRInfiniteLightWithFalloff( ClassData *class_data, Stuff::Page *page ) : MLRLight(class_data, page) { Check_Object(page); Verify(gos_GetCurrentHeap() == LightsHeap); lightMask = MLRState::FaceLightingMode|MLRState::VertexLightingMode; Scalar inner=0.0f; page->GetEntry("InnerRadius", &inner); Scalar outer=100.0; page->GetEntry("OuterRadius", &outer); if (outer <= inner) { STOP(( "Error: %s[%s]: InnerRadius must be less than OuterRadius", page->GetNotationFile()->GetFileName(), page->GetName() )); } SetFalloffDistance (inner, outer); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLRInfiniteLightWithFalloff::~MLRInfiniteLightWithFalloff() { } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::Save(Stuff::MemoryStream *stream) { Check_Object(this); Check_Object(stream); MLRLight::Save(stream); *stream << innerRadius << outerRadius; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::Write(Stuff::Page *page) { Check_Object(this); Check_Object(page); MLRLight::Write(page); page->SetEntry("InnerRadius", innerRadius); page->SetEntry("OuterRadius", outerRadius); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::TestInstance() { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::SetFalloffDistance (Scalar ir, Scalar or) { Check_Object(this); innerRadius = ir; outerRadius = or; oneOverDistance = 1.0f/(outerRadius - innerRadius); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MLRInfiniteLightWithFalloff::GetFalloffDistance (Scalar& ir, Scalar& or) { Check_Object(this); ir = innerRadius; or = outerRadius; return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLRInfiniteLightWithFalloff::LightVertex(const MLRVertexData& vertexData) { UnitVector3D light_z; GetInShapeDirection(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 = 0.7071f; if(vertexData.normal!=NULL) { cosine = -(light_z * (*vertexData.normal)) * intensity; } 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; } 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 MLRInfiniteLightWithFalloff::LightCenter(RGBAColor& rcol) { UnitVector3D light_z; GetInShapeDirection(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 = 0.701f; RGBColor light_color(color); Point3D vertex_to_light; Verify(GetFalloffDistance(vertex_to_light.x, vertex_to_light.y)); GetInShapePosition(vertex_to_light); // //-------------------------------------------------------------- // 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; } 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; } }