/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #include "hsTypes.h" #include "plLightModifier.h" #include "../plGLight/plLightInfo.h" #include "../plInterp/plController.h" #include "hsStream.h" #include "hsResMgr.h" //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// // Basic light plLightModifier::plLightModifier() : fLight(nil), fColorCtl(nil), fAmbientCtl(nil), fSpecularCtl(nil) { } plLightModifier::~plLightModifier() { delete fColorCtl; fColorCtl = nil; delete fAmbientCtl; fAmbientCtl = nil; delete fSpecularCtl; fSpecularCtl = nil; } void plLightModifier::IClearCtls() { delete fColorCtl; fColorCtl = nil; delete fAmbientCtl; fAmbientCtl = nil; delete fSpecularCtl; fSpecularCtl = nil; } void plLightModifier::AddTarget(plSceneObject* so) { plSimpleModifier::AddTarget(so); if( so ) fLight = plLightInfo::ConvertNoRef(so->GetGenericInterface(plLightInfo::Index())); else fLight = nil; } void plLightModifier::RemoveTarget(plSceneObject* so) { if( so = fTarget ) fLight = nil; plSimpleModifier::RemoveTarget(so); } void plLightModifier::Read(hsStream* s, hsResMgr* mgr) { plSimpleModifier::Read(s, mgr); fColorCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fAmbientCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fSpecularCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); } void plLightModifier::Write(hsStream* s, hsResMgr* mgr) { plSimpleModifier::Write(s, mgr); mgr->WriteCreatable(s, fColorCtl); mgr->WriteCreatable(s, fAmbientCtl); mgr->WriteCreatable(s, fSpecularCtl); } void plLightModifier::IApplyDynamic() { hsColorRGBA col; if( fLight != nil ) { if( fColorCtl ) { col.Set(0,0,0,1.f); fColorCtl->Interp(fCurrentTime, &col); fLight->SetDiffuse(col); } if( fAmbientCtl ) { col.Set(0,0,0,1.f); fAmbientCtl->Interp(fCurrentTime, &col); fLight->SetAmbient(col); } if( fSpecularCtl ) { col.Set(0,0,0,1.f); fSpecularCtl->Interp(fCurrentTime, &col); fLight->SetSpecular(col); } } } void plLightModifier::DefaultAnimation() { hsScalar len = MaxAnimLength(0); fTimeConvert.SetBegin(0); fTimeConvert.SetEnd(len); fTimeConvert.SetLoopPoints(0, len); fTimeConvert.Loop(); fTimeConvert.Start(); } hsScalar plLightModifier::MaxAnimLength(hsScalar len) const { if( fColorCtl && (fColorCtl->GetLength() > len) ) len = fColorCtl->GetLength(); if( fAmbientCtl && (fAmbientCtl->GetLength() > len) ) len = fAmbientCtl->GetLength(); if( fSpecularCtl && (fSpecularCtl->GetLength() > len) ) len = fSpecularCtl->GetLength(); return len; } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// // Omni Lights plOmniModifier::plOmniModifier() : fOmni(nil), fAttenCtl(nil) { } plOmniModifier::~plOmniModifier() { delete fAttenCtl; fAttenCtl = nil; } void plOmniModifier::AddTarget(plSceneObject* so) { plLightModifier::AddTarget(so); if( fLight ) fOmni = plOmniLightInfo::ConvertNoRef(fLight); else fOmni = nil; } void plOmniModifier::RemoveTarget(plSceneObject* so) { plLightModifier::RemoveTarget(so); if( !fLight ) fOmni = nil; } void plOmniModifier::IClearCtls() { plLightModifier::IClearCtls(); delete fAttenCtl; fAttenCtl = nil; } void plOmniModifier::Read(hsStream* s, hsResMgr* mgr) { plLightModifier::Read(s, mgr); fAttenCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fInitAtten.Read(s); } void plOmniModifier::Write(hsStream* s, hsResMgr* mgr) { plLightModifier::Write(s, mgr); mgr->WriteCreatable(s, fAttenCtl); fInitAtten.Write(s); } void plOmniModifier::IApplyDynamic() { plLightModifier::IApplyDynamic(); if( fAttenCtl ) { hsPoint3 p = fInitAtten; fAttenCtl->Interp(fCurrentTime, &p); fOmni->SetConstantAttenuation(p.fX); fOmni->SetLinearAttenuation(p.fY); fOmni->SetQuadraticAttenuation(p.fZ); } } hsScalar plOmniModifier::MaxAnimLength(hsScalar len) const { len = plLightModifier::MaxAnimLength(len); if( fAttenCtl && (fAttenCtl->GetLength() > len) ) len = fAttenCtl->GetLength(); return len; } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// // Spot Lights plSpotModifier::plSpotModifier() : fSpot(nil), fInnerCtl(nil), fOuterCtl(nil) { } plSpotModifier::~plSpotModifier() { delete fInnerCtl; fInnerCtl = nil; delete fOuterCtl; fOuterCtl = nil; } void plSpotModifier::AddTarget(plSceneObject* so) { plOmniModifier::AddTarget(so); if( fLight ) fSpot = plSpotLightInfo::ConvertNoRef(fLight); else fSpot = nil; } void plSpotModifier::RemoveTarget(plSceneObject* so) { plOmniModifier::RemoveTarget(so); if( !fLight ) fSpot = nil; } void plSpotModifier::IClearCtls() { plOmniModifier::IClearCtls(); delete fInnerCtl; fInnerCtl = nil; delete fOuterCtl; fOuterCtl = nil; } void plSpotModifier::Read(hsStream* s, hsResMgr* mgr) { plOmniModifier::Read(s, mgr); fInnerCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fOuterCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); } void plSpotModifier::Write(hsStream* s, hsResMgr* mgr) { plOmniModifier::Write(s, mgr); mgr->WriteCreatable(s, fInnerCtl); mgr->WriteCreatable(s, fOuterCtl); } void plSpotModifier::IApplyDynamic() { plOmniModifier::IApplyDynamic(); hsScalar f; if( fInnerCtl ) { fInnerCtl->Interp(fCurrentTime, &f); fSpot->SetSpotInner(hsScalarDegToRad(f)*0.5f); } if( fOuterCtl ) { fOuterCtl->Interp(fCurrentTime, &f); fSpot->SetSpotOuter(hsScalarDegToRad(f)*0.5f); } } hsScalar plSpotModifier::MaxAnimLength(hsScalar len) const { len = plOmniModifier::MaxAnimLength(len); if( fInnerCtl && (fInnerCtl->GetLength() > len) ) len = fInnerCtl->GetLength(); if( fOuterCtl && (fOuterCtl->GetLength() > len) ) len = fOuterCtl->GetLength(); return len; } //////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////// // LtdDir Lights plLtdDirModifier::plLtdDirModifier() : fLtdDir(nil), fWidthCtl(nil), fHeightCtl(nil), fDepthCtl(nil) { } plLtdDirModifier::~plLtdDirModifier() { delete fWidthCtl; fWidthCtl = nil; delete fHeightCtl; fHeightCtl = nil; delete fDepthCtl; fDepthCtl = nil; } void plLtdDirModifier::AddTarget(plSceneObject* so) { plLightModifier::AddTarget(so); if( fLight ) fLtdDir = plLimitedDirLightInfo::ConvertNoRef(fLight); else fLtdDir = nil; } void plLtdDirModifier::RemoveTarget(plSceneObject* so) { plLightModifier::RemoveTarget(so); if( !fLight ) fLtdDir = nil; } void plLtdDirModifier::IClearCtls() { plLightModifier::IClearCtls(); delete fWidthCtl; fWidthCtl = nil; delete fHeightCtl; fHeightCtl = nil; delete fDepthCtl; fDepthCtl = nil; } void plLtdDirModifier::Read(hsStream* s, hsResMgr* mgr) { plLightModifier::Read(s, mgr); fWidthCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fHeightCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); fDepthCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); } void plLtdDirModifier::Write(hsStream* s, hsResMgr* mgr) { plLightModifier::Write(s, mgr); mgr->WriteCreatable(s, fWidthCtl); mgr->WriteCreatable(s, fHeightCtl); mgr->WriteCreatable(s, fDepthCtl); } void plLtdDirModifier::IApplyDynamic() { plLightModifier::IApplyDynamic(); hsScalar f; if( fWidthCtl ) { fWidthCtl->Interp(fCurrentTime, &f); fLtdDir->SetWidth(f); } if( fHeightCtl ) { fHeightCtl->Interp(fCurrentTime, &f); fLtdDir->SetHeight(f); } if( fDepthCtl ) { fDepthCtl->Interp(fCurrentTime, &f); fLtdDir->SetDepth(f); } } hsScalar plLtdDirModifier::MaxAnimLength(hsScalar len) const { len = plLightModifier::MaxAnimLength(len); if( fWidthCtl && (fWidthCtl->GetLength() > len) ) len = fWidthCtl->GetLength(); if( fHeightCtl && (fHeightCtl->GetLength() > len) ) len = fHeightCtl->GetLength(); if( fDepthCtl && (fDepthCtl->GetLength() > len) ) len = fDepthCtl->GetLength(); return len; }