// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2007 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27514 // http://www.emergentgametech.com #include "NiSpeedTreePluginPCH.h" #if _MSC_VER == 1310 #pragma unmanaged #include #include <_vcclrit.h> #pragma managed #endif #include "MPlugin.h" #include "MSptFilenameEditor.h" #include "MIniFilenameEditor.h" #include "MSettingsHelper.h" //#using #include #include #include #include #include #include #include #include using namespace System; using namespace System::IO; using namespace System::Drawing; using namespace System::Reflection; using namespace Emergent::Gamebryo::SceneDesigner::NiSpeedTreePlugin; using namespace Emergent::Gamebryo::SceneDesigner::PluginAPI::StandardServices; using namespace Emergent::Gamebryo::SceneDesigner::Framework; using namespace System::Windows::Forms; //--------------------------------------------------------------------------- MPlugin::MPlugin(void) { m_pkFogColor = NiNew NiColor(); } //--------------------------------------------------------------------------- MPlugin::~MPlugin(void) { NiDelete m_pkFogColor; } //--------------------------------------------------------------------------- void MPlugin::Do_Dispose(bool bDisposing) { if (bDisposing) { NiSpeedTreeSDM::Shutdown(); MSettingsHelper::Shutdown(); } } //--------------------------------------------------------------------------- String* MPlugin::get_Name() { return "NiSpeedTree Plug-in"; } //--------------------------------------------------------------------------- System::Version* MPlugin::get_Version() { return Assembly::GetCallingAssembly()->GetName()->Version; } //--------------------------------------------------------------------------- System::Version* MPlugin::get_ExpectedVersion() { return new System::Version(2, 2); } //--------------------------------------------------------------------------- void MPlugin::Load(int iToolMajorVersion, int iToolMinorVersion) { NiSpeedTreeSDM::Init(); MSettingsHelper::Init(); } //--------------------------------------------------------------------------- IService* MPlugin::GetProvidedServices()[] { return new IService*[]; } //--------------------------------------------------------------------------- void MPlugin::Start() { RegisterProperties(); RegisterComponents(); RegisterSettings(); RegisterProxies(); NiSpeedTreeComponent::SetManager(NiNew NiSpeedTreeManager); NiSpeedTreeComponent::SetCuller(NiNew NiSpeedTreeCullerDefault()); } //--------------------------------------------------------------------------- void MPlugin::RegisterProperties() { // Get property type service. IPropertyTypeService* pmPropertyTypeService = MGetService( IPropertyTypeService); MAssert(pmPropertyTypeService != NULL, "Service not found!"); pmPropertyTypeService->RegisterType(new PropertyType( "SPT Filename", NiEntityPropertyInterface::PT_STRING, __typeof(String), __typeof(MSptFilenameEditor), NULL)); pmPropertyTypeService->RegisterType(new PropertyType( "INI Filename", NiEntityPropertyInterface::PT_STRING, __typeof(String), __typeof(MIniFilenameEditor), NULL)); } //--------------------------------------------------------------------------- void MPlugin::RegisterComponents() { // Get component service. IComponentService* pmComponentService = MGetService(IComponentService); MAssert(pmComponentService != NULL, "Component service not found!"); // Get component factory. MComponentFactory* pmFactory = MFramework::Instance->ComponentFactory; MAssert(pmFactory != NULL, "Component factory not found!"); // Register standard component types. pmComponentService->RegisterComponent(pmFactory->Get(NiNew NiSpeedTreeComponent())); pmComponentService->RegisterComponent(pmFactory->Get(NiNew NiSpeedWindComponent())); __hook(&MEventManager::NewSceneLoaded, MFramework::Instance->EventManager, &MPlugin::OnNewSceneLoaded); } //--------------------------------------------------------------------------- void MPlugin::RegisterProxies() { m_pmMasterProxy = MFramework::Instance->ProxyManager-> CreateGenericMasterProxyEntity(".\\Data\\wind.nif", "Wind Proxy", true); MFramework::Instance->ProxyManager->AddProxyHandler(this); } //--------------------------------------------------------------------------- void MPlugin::RegisterSettings() { // Register the event handler for changed settings SettingChangedHandler* pmHandler = new SettingChangedHandler(this, &MPlugin::OnSettingChanged); // Defaults m_fLODNear = 200.0f; m_fLODFar = 500.0f; m_fOrthoPercent = 0.5f; m_bDrawBillboard = false; m_bDrawWireframe = false; // Default to a known good shader directory char acPath[MAX_PATH] = ".\\Shaders\\Data\\"; NiPath::ConvertToAbsolute(acPath, sizeof(acPath)); m_pmShaderPath = new MFolderLocation(acPath); m_bFogEnabled = false; m_fFogNear = 1000.0f; *m_pkFogColor = NiColor::WHITE; MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::NEAR_LOD_DISTANCE, m_fLODNear, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::FAR_LOD_DISTANCE, m_fLODFar, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::ORTHO_LOD_PERCENT, m_fOrthoPercent, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::RENDER_AS_BILLBOARDS, m_bDrawBillboard, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::RENDER_WIREFRAME, m_bDrawWireframe, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::SHADER_PATH, m_pmShaderPath, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::FOG_ENABLED, m_bFogEnabled, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::FOG_NEAR_DISTANCE, m_fFogNear, pmHandler); MSettingsHelper::Instance->RegisterSetting( MSettingsHelper::FOG_COLOR, *m_pkFogColor, pmHandler); } //--------------------------------------------------------------------------- void MPlugin::OnNewSceneLoaded(MScene* pmScene) { // Update current values from registered values... SetValue(MSettingsHelper::NEAR_LOD_DISTANCE, m_fLODNear); SetValue(MSettingsHelper::FAR_LOD_DISTANCE, m_fLODFar); SetValue(MSettingsHelper::ORTHO_LOD_PERCENT, m_fOrthoPercent); SetValue(MSettingsHelper::RENDER_AS_BILLBOARDS, m_bDrawBillboard); SetValue(MSettingsHelper::RENDER_WIREFRAME, m_bDrawWireframe); SetValue(MSettingsHelper::SHADER_PATH, m_pmShaderPath); SetValue(MSettingsHelper::FOG_ENABLED, m_bFogEnabled); SetValue(MSettingsHelper::FOG_NEAR_DISTANCE, m_fFogNear); SetValue(MSettingsHelper::FOG_COLOR, *m_pkFogColor); } //--------------------------------------------------------------------------- bool MPlugin::SetValue(MSettingsHelper::StandardSetting eSetting, float fValue) { NiSpeedTreeManager* pkManager = NiSpeedTreeComponent::GetManager(); NIASSERT(pkManager); NiSpeedTreeCuller* pkCuller; NiFogProperty* pkFog; switch (eSetting) { case MSettingsHelper::NEAR_LOD_DISTANCE: pkCuller = NiSpeedTreeComponent::GetCuller(); NIASSERT(pkCuller); pkCuller->SetNearLOD(fValue); return true; case MSettingsHelper::FAR_LOD_DISTANCE: pkCuller = NiSpeedTreeComponent::GetCuller(); NIASSERT(pkCuller); pkCuller->SetFarLOD(fValue); return true; case MSettingsHelper::ORTHO_LOD_PERCENT: pkCuller = NiSpeedTreeComponent::GetCuller(); NIASSERT(pkCuller); pkCuller->SetOrthoLOD(fValue); return true; case MSettingsHelper::FOG_NEAR_DISTANCE: pkFog = pkManager->GetFogProperty(); NIASSERT(pkFog); pkFog->SetDepth(fValue); return true; default: return false; } } //--------------------------------------------------------------------------- bool MPlugin::SetValue(MSettingsHelper::StandardSetting eSetting, bool bValue) { NiSpeedTreeManager* pkManager = NiSpeedTreeComponent::GetManager(); NIASSERT(pkManager); NiSpeedTreeCuller* pkCuller; NiFogProperty* pkFog; switch (eSetting) { case MSettingsHelper::RENDER_AS_BILLBOARDS: pkCuller = NiSpeedTreeComponent::GetCuller(); NIASSERT(pkCuller); pkCuller->SetGlobalLODHint(bValue ? NiSpeedTreeInstance::LOD_BILLBOARD : NiSpeedTreeInstance::LOD_DEFAULT); return true; case MSettingsHelper::RENDER_WIREFRAME: pkManager->SetWireframeMode(bValue); return true; case MSettingsHelper::FOG_ENABLED: pkFog = pkManager->GetFogProperty(); NIASSERT(pkFog); pkFog->SetFog(bValue); return true; default: return false; } } //--------------------------------------------------------------------------- bool MPlugin::SetValue(MSettingsHelper::StandardSetting eSetting, MFolderLocation* pmLoc) { NiSpeedTreeManager* pkManager = NiSpeedTreeComponent::GetManager(); NIASSERT(pkManager); const char* pcPath; switch (eSetting) { case MSettingsHelper::SHADER_PATH: pcPath = MStringToCharPointer(pmLoc->Path); pkManager->SetShaderPath(pcPath); MFreeCharPointer(pcPath); return true; default: return false; } } //--------------------------------------------------------------------------- bool MPlugin::SetValue(MSettingsHelper::StandardSetting eSetting, NiColor& kColor) { NiSpeedTreeManager* pkManager = NiSpeedTreeComponent::GetManager(); NIASSERT(pkManager); NiFogProperty* pkFog = pkManager->GetFogProperty(); switch (eSetting) { case MSettingsHelper::FOG_COLOR: pkFog->SetFogColor(kColor); return true; default: return false; } } //--------------------------------------------------------------------------- void MPlugin::OnSettingChanged(Object* pmSender, SettingChangedEventArgs* pmEventArgs) { String* strSetting = pmEventArgs->Name; SettingsCategory eCategory = pmEventArgs->Category; ISettingsService* pmSettingsService = MSettingsHelper::Instance->SettingsService; // if a setting we care about was changed, re-cache it if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::NEAR_LOD_DISTANCE)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box float* pfVal = dynamic_cast<__box float*>(pmObj); if (pfVal != NULL) { m_fLODNear = *pfVal; SetValue(MSettingsHelper::NEAR_LOD_DISTANCE, m_fLODNear); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::FAR_LOD_DISTANCE)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box float* pfVal = dynamic_cast<__box float*>(pmObj); if (pfVal != NULL) { m_fLODFar = *pfVal; SetValue(MSettingsHelper::FAR_LOD_DISTANCE, m_fLODFar); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::ORTHO_LOD_PERCENT)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box float* pfVal = dynamic_cast<__box float*>(pmObj); if (pfVal != NULL) { m_fOrthoPercent = *pfVal; SetValue(MSettingsHelper::ORTHO_LOD_PERCENT, m_fOrthoPercent); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::RENDER_AS_BILLBOARDS)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box bool* pbVal = dynamic_cast<__box bool*>(pmObj); if (pbVal != NULL) { m_bDrawBillboard = *pbVal; SetValue(MSettingsHelper::RENDER_AS_BILLBOARDS, m_bDrawBillboard); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::RENDER_WIREFRAME)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box bool* pbVal = dynamic_cast<__box bool*>(pmObj); if (pbVal != NULL) { m_bDrawWireframe = *pbVal; SetValue(MSettingsHelper::RENDER_WIREFRAME, m_bDrawWireframe); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::SHADER_PATH)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); MFolderLocation* pmVal = dynamic_cast(pmObj); if (pmVal != NULL) { m_pmShaderPath = pmVal; SetValue(MSettingsHelper::SHADER_PATH, m_pmShaderPath); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::FOG_ENABLED)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box bool* pbVal = dynamic_cast<__box bool*>(pmObj); if (pbVal != NULL) { m_bFogEnabled = *pbVal; SetValue(MSettingsHelper::FOG_ENABLED, m_bFogEnabled); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::FOG_NEAR_DISTANCE)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box float* pfVal = dynamic_cast<__box float*>(pmObj); if (pfVal != NULL) { m_fFogNear = *pfVal; SetValue(MSettingsHelper::FOG_NEAR_DISTANCE, m_fFogNear); } } else if (MSettingsHelper::IsArgStandardSetting(pmEventArgs, MSettingsHelper::FOG_COLOR)) { Object* pmObj; pmObj = pmSettingsService->GetSettingsObject(strSetting, eCategory); __box Color* pmValue; pmValue = dynamic_cast<__box Color*>(pmObj); if (pmValue != NULL) { m_pkFogColor->r = MUtility::RGBToFloat((*pmValue).R); m_pkFogColor->g = MUtility::RGBToFloat((*pmValue).G); m_pkFogColor->b = MUtility::RGBToFloat((*pmValue).B); SetValue(MSettingsHelper::FOG_COLOR, *m_pkFogColor); } } } //--------------------------------------------------------------------------- MEntity* MPlugin::GetMasterProxyEntity(MEntity* pmEntity) { MComponent* amComponents[] = pmEntity->GetComponents(); for (int j = 0; j < amComponents->Count; j++) { NiEntityComponentInterface* pkComponent = amComponents[j]->GetNiEntityComponentInterface(); if (NiSpeedWindComponent::IsWindComponent(pkComponent)) { return m_pmMasterProxy; } } return NULL; } //--------------------------------------------------------------------------- //The following is related to a bug in VC7.1/.Net CLR 1.1 // see http://support.microsoft.com/?id=814472 void MPlugin::InitStatics() { #if _MSC_VER == 1310 __crt_dll_initialize(); #endif } //--------------------------------------------------------------------------- void MPlugin::ShutdownStatics() { #if _MSC_VER == 1310 //__crt_dll_terminate(); #endif } //---------------------------------------------------------------------------