From 83945cf2800292cdc975bbf837bdf4ebddd92ed1 Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sat, 3 Dec 2016 15:24:21 -0700 Subject: [PATCH 1/7] Added reasonable approximation of magic bolt lights --- apps/openmw/mwworld/projectilemanager.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 35df52a18..4b373dad0 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -2,6 +2,8 @@ #include +#include +#include #include #include @@ -142,8 +144,8 @@ namespace MWWorld state.mNode->setNodeMask(MWRender::Mask_Effect); state.mNode->setPosition(pos); state.mNode->setAttitude(orient); - - osg::Group* attachTo = state.mNode; + + osg::Group* attachTo = state.mNode; if (rotate) { @@ -167,6 +169,23 @@ namespace MWWorld mResourceSystem->getSceneManager()->getInstance("meshes\\" + weapon->mModel, findVisitor.mFoundNode); } + // Add projectile light + osg::ref_ptr projectileLight(new osg::Light); + projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); + projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); + projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); + projectileLight->setLinearAttenuation(0.5f / 15); + projectileLight->setPosition(osg::Vec4(pos, 1.0)); + + // Add projectile light source + SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; + projectileLightSource->setNodeMask(MWRender::Mask_Lighting); + projectileLightSource->setRadius(66.f); + + state.mNode->addChild(projectileLightSource); + projectileLightSource->setLight(projectileLight); + + SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor; state.mNode->accept(disableFreezeOnCullVisitor); From 49ce80346c93f14456acb927b81bc0264874e20c Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sat, 3 Dec 2016 15:42:24 -0700 Subject: [PATCH 2/7] Changed methods slightly to ensure non-magic projectiles do not receive lights --- apps/openmw/mwworld/projectilemanager.cpp | 50 ++++++++++++----------- apps/openmw/mwworld/projectilemanager.hpp | 2 +- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 4b373dad0..a81188046 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -138,7 +138,7 @@ namespace MWWorld }; - void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, std::string texture) + void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool isMagic, std::string texture) { state.mNode = new osg::PositionAttitudeTransform; state.mNode->setNodeMask(MWRender::Mask_Effect); @@ -169,21 +169,25 @@ namespace MWWorld mResourceSystem->getSceneManager()->getInstance("meshes\\" + weapon->mModel, findVisitor.mFoundNode); } - // Add projectile light - osg::ref_ptr projectileLight(new osg::Light); - projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); - projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); - projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); - projectileLight->setLinearAttenuation(0.5f / 15); - projectileLight->setPosition(osg::Vec4(pos, 1.0)); - - // Add projectile light source - SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; - projectileLightSource->setNodeMask(MWRender::Mask_Lighting); - projectileLightSource->setRadius(66.f); - - state.mNode->addChild(projectileLightSource); - projectileLightSource->setLight(projectileLight); + if (isMagic) + { + // Add magic bolt light + osg::ref_ptr projectileLight(new osg::Light); + projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); + projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); + projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); + projectileLight->setLinearAttenuation(0.5f / 15); + projectileLight->setPosition(osg::Vec4(pos, 1.0)); + + // Add magic bolt light source + SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; + projectileLightSource->setNodeMask(MWRender::Mask_Lighting); + projectileLightSource->setRadius(66.f); + + // Attach to scene node + state.mNode->addChild(projectileLightSource); + projectileLightSource->setLight(projectileLight); + } SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor; @@ -248,7 +252,7 @@ namespace MWWorld MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), state.mIdMagic.at(0)); MWWorld::Ptr ptr = ref.getPtr(); - createModel(state, ptr.getClass().getModel(ptr), pos, orient, true, texture); + createModel(state, ptr.getClass().getModel(ptr), pos, orient, true, true, texture); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); for (size_t it = 0; it != state.mSoundIds.size(); it++) @@ -272,7 +276,7 @@ namespace MWWorld MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId()); MWWorld::Ptr ptr = ref.getPtr(); - createModel(state, ptr.getClass().getModel(ptr), pos, orient, false); + createModel(state, ptr.getClass().getModel(ptr), pos, orient, false, false); mProjectiles.push_back(state); } @@ -478,9 +482,9 @@ namespace MWWorld bool ProjectileManager::readRecord(ESM::ESMReader &reader, uint32_t type) { - if (type == ESM::REC_PROJ) + if (type == ESM::REC_PROJ) { - ESM::ProjectileState esm; + ESM::ProjectileState esm; esm.load(reader); ProjectileState state; @@ -502,14 +506,14 @@ namespace MWWorld return true; } - createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), false); + createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), false, false); mProjectiles.push_back(state); return true; } else if (type == ESM::REC_MPRJ) { - ESM::MagicBoltState esm; + ESM::MagicBoltState esm; esm.load(reader); MagicBoltState state; @@ -537,7 +541,7 @@ namespace MWWorld return true; } - createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, texture); + createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, true, texture); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index a8769fcf9..d17e24b0c 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -122,7 +122,7 @@ namespace MWWorld void moveProjectiles(float dt); void moveMagicBolts(float dt); - void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, std::string texture = ""); + void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool isMagic, std::string texture = ""); void update (State& state, float duration); void operator=(const ProjectileManager&); From 61097d93b9d72f8c16db35b118e9cffe5ce7cd20 Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sat, 3 Dec 2016 19:09:03 -0700 Subject: [PATCH 3/7] Replaced tabs with spaces (oops) --- apps/openmw/mwworld/projectilemanager.cpp | 51 +++++++++++------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index a81188046..56a4b75fe 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -144,8 +144,8 @@ namespace MWWorld state.mNode->setNodeMask(MWRender::Mask_Effect); state.mNode->setPosition(pos); state.mNode->setAttitude(orient); - - osg::Group* attachTo = state.mNode; + + osg::Group* attachTo = state.mNode; if (rotate) { @@ -169,27 +169,26 @@ namespace MWWorld mResourceSystem->getSceneManager()->getInstance("meshes\\" + weapon->mModel, findVisitor.mFoundNode); } - if (isMagic) - { - // Add magic bolt light - osg::ref_ptr projectileLight(new osg::Light); - projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); - projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); - projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); - projectileLight->setLinearAttenuation(0.5f / 15); - projectileLight->setPosition(osg::Vec4(pos, 1.0)); - - // Add magic bolt light source - SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; - projectileLightSource->setNodeMask(MWRender::Mask_Lighting); - projectileLightSource->setRadius(66.f); - - // Attach to scene node - state.mNode->addChild(projectileLightSource); - projectileLightSource->setLight(projectileLight); - } - - + if (isMagic) + { + // Add magic bolt light + osg::ref_ptr projectileLight(new osg::Light); + projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); + projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); + projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); + projectileLight->setLinearAttenuation(0.5f / 15); + projectileLight->setPosition(osg::Vec4(pos, 1.0)); + + // Add magic bolt light source + SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; + projectileLightSource->setNodeMask(MWRender::Mask_Lighting); + projectileLightSource->setRadius(66.f); + + // Attach to scene node + state.mNode->addChild(projectileLightSource); + projectileLightSource->setLight(projectileLight); + } + SceneUtil::DisableFreezeOnCullVisitor disableFreezeOnCullVisitor; state.mNode->accept(disableFreezeOnCullVisitor); @@ -482,9 +481,9 @@ namespace MWWorld bool ProjectileManager::readRecord(ESM::ESMReader &reader, uint32_t type) { - if (type == ESM::REC_PROJ) + if (type == ESM::REC_PROJ) { - ESM::ProjectileState esm; + ESM::ProjectileState esm; esm.load(reader); ProjectileState state; @@ -513,7 +512,7 @@ namespace MWWorld } else if (type == ESM::REC_MPRJ) { - ESM::MagicBoltState esm; + ESM::MagicBoltState esm; esm.load(reader); MagicBoltState state; From 099e79edbec0d641399d14b2ab8fdb4edf56d3a5 Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sat, 3 Dec 2016 19:12:25 -0700 Subject: [PATCH 4/7] Changed a line that did not need to be changed apparently --- apps/openmw/mwworld/projectilemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 56a4b75fe..ba1104f93 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -144,7 +144,7 @@ namespace MWWorld state.mNode->setNodeMask(MWRender::Mask_Effect); state.mNode->setPosition(pos); state.mNode->setAttitude(orient); - + osg::Group* attachTo = state.mNode; if (rotate) From 3816d0f6dc0b6094765c0b44caf24e252d35c0fb Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sat, 3 Dec 2016 19:44:52 -0700 Subject: [PATCH 5/7] Changed light values to better match vanilla. Still need to pull diffusion properties from spells --- apps/openmw/mwworld/projectilemanager.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index ba1104f93..0842f5d1d 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -173,10 +173,12 @@ namespace MWWorld { // Add magic bolt light osg::ref_ptr projectileLight(new osg::Light); - projectileLight->setDiffuse(osg::Vec4(0.95f, 0.71f, 0.25f, 1.0f)); - projectileLight->setAmbient(osg::Vec4(0.32f, 0.08f, 0.01f, 1.0f)); - projectileLight->setSpecular(osg::Vec4(0, 0, 0, 0)); - projectileLight->setLinearAttenuation(0.5f / 15); + projectileLight->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); + projectileLight->setDiffuse(osg::Vec4(0.814f, 0.682f, 0.652f, 1.0f)); + projectileLight->setSpecular(osg::Vec4(30.0f, 30.0f, 30.0f, 1.0f)); + projectileLight->setConstantAttenuation(0.f); + projectileLight->setLinearAttenuation(0.1f); + projectileLight->setQuadraticAttenuation(0.f); projectileLight->setPosition(osg::Vec4(pos, 1.0)); // Add magic bolt light source From ef5cf76ad81b344726d9869f9998818c708795a3 Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sun, 4 Dec 2016 16:11:21 -0700 Subject: [PATCH 6/7] Implemented retrieval of effect colors for lights, made recommended changes --- apps/openmw/mwworld/projectilemanager.cpp | 37 +++++++++++++++++++---- apps/openmw/mwworld/projectilemanager.hpp | 2 +- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 0842f5d1d..1d290c8a1 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -2,8 +2,6 @@ #include -#include -#include #include #include @@ -138,7 +136,7 @@ namespace MWWorld }; - void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool isMagic, std::string texture) + void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool createLight, std::string texture) { state.mNode = new osg::PositionAttitudeTransform; state.mNode->setNodeMask(MWRender::Mask_Effect); @@ -169,13 +167,40 @@ namespace MWWorld mResourceSystem->getSceneManager()->getInstance("meshes\\" + weapon->mModel, findVisitor.mFoundNode); } - if (isMagic) + if (createLight) { + // Combine colors of individual effects + osg::Vec4 lightDiffuseColor; + if (state.mIdMagic.size() > 0) + { + float lightDiffuseRed = 0.0f; + float lightDiffuseGreen = 0.0f; + float lightDiffuseBlue = 0.0f; + for (std::vector::const_iterator it = ((MagicBoltState&)state).mEffects.mList.begin(); it != ((MagicBoltState&)state).mEffects.mList.end(); ++it) + { + const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find( + it->mEffectID); + lightDiffuseRed += ((float) magicEffect->mData.mRed / 255.f); + lightDiffuseGreen += ((float) magicEffect->mData.mGreen / 255.f); + lightDiffuseBlue += ((float) magicEffect->mData.mBlue / 255.f); + } + int numberOfEffects = ((MagicBoltState&)state).mEffects.mList.size(); + lightDiffuseColor = osg::Vec4(lightDiffuseRed / numberOfEffects + , lightDiffuseGreen / numberOfEffects + , lightDiffuseBlue / numberOfEffects + , 1.0f); + printf("%f, %f, %f", (lightDiffuseRed / numberOfEffects), (lightDiffuseGreen / numberOfEffects), (lightDiffuseBlue / numberOfEffects)); + } + else + { + lightDiffuseColor = osg::Vec4(0.814f, 0.682f, 0.652f, 1.0f); + } + // Add magic bolt light osg::ref_ptr projectileLight(new osg::Light); projectileLight->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); - projectileLight->setDiffuse(osg::Vec4(0.814f, 0.682f, 0.652f, 1.0f)); - projectileLight->setSpecular(osg::Vec4(30.0f, 30.0f, 30.0f, 1.0f)); + projectileLight->setDiffuse(lightDiffuseColor); + projectileLight->setSpecular(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); projectileLight->setConstantAttenuation(0.f); projectileLight->setLinearAttenuation(0.1f); projectileLight->setQuadraticAttenuation(0.f); diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index d17e24b0c..db090eaef 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -122,7 +122,7 @@ namespace MWWorld void moveProjectiles(float dt); void moveMagicBolts(float dt); - void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool isMagic, std::string texture = ""); + void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, bool createLight, std::string texture = ""); void update (State& state, float duration); void operator=(const ProjectileManager&); From c2e5f24e981ecd4bc826075d274816469f75d4a4 Mon Sep 17 00:00:00 2001 From: mrohrlach Date: Sun, 4 Dec 2016 16:31:11 -0700 Subject: [PATCH 7/7] Tidying up --- apps/openmw/mwworld/projectilemanager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index 1d290c8a1..3d9c4df90 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -169,7 +169,7 @@ namespace MWWorld if (createLight) { - // Combine colors of individual effects + // Case: magical effects (combine colors of individual effects) osg::Vec4 lightDiffuseColor; if (state.mIdMagic.size() > 0) { @@ -189,14 +189,14 @@ namespace MWWorld , lightDiffuseGreen / numberOfEffects , lightDiffuseBlue / numberOfEffects , 1.0f); - printf("%f, %f, %f", (lightDiffuseRed / numberOfEffects), (lightDiffuseGreen / numberOfEffects), (lightDiffuseBlue / numberOfEffects)); } else { + // Case: no magical effects, but still creating light lightDiffuseColor = osg::Vec4(0.814f, 0.682f, 0.652f, 1.0f); } - // Add magic bolt light + // Add light osg::ref_ptr projectileLight(new osg::Light); projectileLight->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); projectileLight->setDiffuse(lightDiffuseColor); @@ -206,7 +206,7 @@ namespace MWWorld projectileLight->setQuadraticAttenuation(0.f); projectileLight->setPosition(osg::Vec4(pos, 1.0)); - // Add magic bolt light source + // Add light source SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; projectileLightSource->setNodeMask(MWRender::Mask_Lighting); projectileLightSource->setRadius(66.f);