From 006f25d1c04f25542c83ed488202223b786d1829 Mon Sep 17 00:00:00 2001 From: gus Date: Mon, 6 May 2013 00:46:50 +0100 Subject: [PATCH 01/18] First try to improve AI. Does not work yet due to strange bug in physicsystem --- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwmechanics/pathfinding.cpp | 23 ++++++++++++++++------- apps/openmw/mwworld/physicssystem.cpp | 8 +++++--- apps/openmw/mwworld/physicssystem.hpp | 4 ++-- apps/openmw/mwworld/worldimp.cpp | 7 +++++++ apps/openmw/mwworld/worldimp.hpp | 3 +++ libs/openengine/bullet/physic.cpp | 15 +++++++++------ libs/openengine/bullet/physic.hpp | 4 ++-- 8 files changed, 47 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 6c9fa67032..8d71b37cc7 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -245,6 +245,9 @@ namespace MWBase virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0; ///< Run physics simulation and modify \a world accordingly. + virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0; + ///< cast a Ray and return true if there is an object in the ray path. + virtual bool toggleCollisionMode() = 0; ///< Toggle collision mode for player. If disabled player object should ignore /// collisions and gravity. diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 2f27d25f8a..3f175e00e8 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -1,4 +1,8 @@ #include "pathfinding.hpp" + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" + #include #include #include "boost/tuple/tuple.hpp" @@ -169,15 +173,20 @@ namespace MWMechanics void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, const ESM::Pathgrid* pathGrid,float xCell,float yCell) { - int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ); - int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ); - - if(start != -1 && end != -1) + //first check if there is an obstacle + if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX,startPoint.mY,startPoint.mZ, + endPoint.mX,endPoint.mY,endPoint.mZ) ) { - PathGridGraph graph = buildGraph(pathGrid,xCell,yCell); - mPath = findPath(start,end,graph); - } + std::cout << "hit"; + int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ); + int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ); + if(start != -1 && end != -1) + { + PathGridGraph graph = buildGraph(pathGrid,xCell,yCell); + mPath = findPath(start,end,graph); + } + } mPath.push_back(endPoint); mIsPathConstructed = true; } diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 7abe94aa60..8b6de68049 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -333,14 +333,14 @@ namespace MWWorld return result; } - bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to) + bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly) { btVector3 _from, _to; _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - std::pair result = mEngine->rayTest(_from, _to); - + std::pair result = mEngine->rayTest(_from, _to, false);//raycastingObjectOnly); + std::cout << result.first << " " << result.second; return !(result.first == ""); } @@ -419,6 +419,7 @@ namespace MWWorld OEngine::Physic::RigidBody* raycastingBody = mEngine->createAndAdjustRigidBody( mesh, node->getName(), node->getScale().x, node->getPosition(), node->getOrientation(), 0, 0, true, placeable); mEngine->addRigidBody(body, true, raycastingBody); + std::cout << "Object:" << mesh; } void PhysicsSystem::addActor (const Ptr& ptr) @@ -427,6 +428,7 @@ namespace MWWorld Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); //TODO:optimize this. Searching the std::map isn't very efficient i think. mEngine->addCharacter(node->getName(), mesh, node->getPosition(), node->getScale().x, node->getOrientation()); + std::cout << "Actor:" << mesh; } void PhysicsSystem::removeObject (const std::string& handle) diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 3322c38a62..ad8eb2ebae 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -62,8 +62,8 @@ namespace MWWorld btVector3 getRayPoint(float extent, float mouseX, float mouseY); - // cast ray, return true if it hit something - bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to); + // cast ray, return true if it hit something. if raycasringObjectOnlt is set to false, it ignores NPCs and objects with no collisions. + bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool raycastingObjectOnly = true); std::pair castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index d2a6d9af69..a40889515e 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1042,6 +1042,13 @@ namespace MWWorld mPhysEngine->stepSimulation (duration); } + bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2) + { + Ogre::Vector3 a(x1,y1,z1);std::cout << x1 << " " << x2; + Ogre::Vector3 b(x2,y2,z2); + return mPhysics->castRay(a,b,false); + } + void World::processDoors(float duration) { std::map::iterator it = mDoorStates.begin(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index dadb701f5e..2466edd0f0 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -279,6 +279,9 @@ namespace MWWorld virtual void doPhysics(const PtrMovementList &actors, float duration); ///< Run physics simulation and modify \a world accordingly. + virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2); + ///< cast a Ray and return true if there is an object in the ray path. + virtual bool toggleCollisionMode(); ///< Toggle collision mode for player. If disabled player object should ignore /// collisions and gravity. diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 2b59e0aade..e6fd18ea2e 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -28,7 +28,7 @@ namespace Physic mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true); Ogre::Quaternion inverse = mBoxRotation.Inverse(); mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w); - mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map + //mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map } PhysicActor::~PhysicActor() @@ -422,15 +422,17 @@ namespace Physic } - void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap, RigidBody* raycastingBody) + void PhysicEngine::addRigidBody(RigidBody* body, bool addToMap, RigidBody* raycastingBody,bool actor) { if(!body && !raycastingBody) return; // nothing to do const std::string& name = (body ? body->mName : raycastingBody->mName); - if (body) - dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal); + if (body){ + if(actor) {dynamicsWorld->addRigidBody(body,CollisionType_ActorInternal,CollisionType_World|CollisionType_ActorInternal);std::cout << "actor";} + else dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal); + } if (raycastingBody) dynamicsWorld->addRigidBody(raycastingBody,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_World); @@ -603,14 +605,15 @@ namespace Physic { } - std::pair PhysicEngine::rayTest(btVector3& from,btVector3& to) + std::pair PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly) { std::string name = ""; float d = -1; float d1 = 10000.; btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); - resultCallback1.m_collisionFilterMask = CollisionType_Raycasting; + if(raycastingObjectOnly) resultCallback1.m_collisionFilterMask = CollisionType_Raycasting; + else resultCallback1.m_collisionFilterMask = CollisionType_ActorExternal; dynamicsWorld->rayTest(from, to, resultCallback1); if (resultCallback1.hasHit()) { diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 67e94c8f86..063c8be0e1 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -226,7 +226,7 @@ namespace Physic /** * Add a RigidBody to the simulation */ - void addRigidBody(RigidBody* body, bool addToMap = true, RigidBody* raycastingBody = NULL); + void addRigidBody(RigidBody* body, bool addToMap = true, RigidBody* raycastingBody = NULL,bool actor = false); /** * Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap. @@ -293,7 +293,7 @@ namespace Physic /** * Return the closest object hit by a ray. If there are no objects, it will return ("",-1). */ - std::pair rayTest(btVector3& from,btVector3& to); + std::pair rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true); /** * Return all objects hit by a ray. From 68f249e8f439bbb5ca20321b2466e2c4aaaa2c82 Mon Sep 17 00:00:00 2001 From: Glorf Date: Tue, 7 May 2013 10:27:37 +0200 Subject: [PATCH 02/18] Small weather cleanup --- apps/openmw/mwworld/weather.cpp | 168 +++++++++++++++++--------------- apps/openmw/mwworld/weather.hpp | 4 + 2 files changed, 95 insertions(+), 77 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index b6a649bcb7..cb9c8f2c46 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -65,9 +65,8 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), mMonth(0), mDay(0), - mTimePassed(0), mFallback(fallback), mWindSpeed(0.f) + mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) { - mRendering = rendering; //Globals mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); mThunderSoundID1 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1"); @@ -78,10 +77,22 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa mSunriseDuration = mFallback->getFallbackFloat("Weather_Sunrise_Duration"); mSunsetDuration = mFallback->getFallbackFloat("Weather_Sunset_Duration"); mHoursBetweenWeatherChanges = mFallback->getFallbackFloat("Weather_Hours_Between_Weather_Changes"); - mWeatherUpdateTime = mHoursBetweenWeatherChanges*3600; + mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; mThunderFrequency = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency"); mThunderThreshold = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold"); mThunderSoundDelay = 0.25; + + //Some useful values + /* TODO: Use pre-sunrise_time, pre-sunset_time, + * post-sunrise_time, and post-sunset_time to better + * describe sunrise/sunset time. + * These values are fallbacks attached to weather. + */ + mNightStart = mSunsetTime + mSunsetDuration; + mNightEnd = mSunriseTime - 0.5; + mDayStart = mSunriseTime + mSunriseDuration; + mDayEnd = mSunsetTime; + //Weather Weather clear; clear.mCloudTexture = "tx_sky_clear.dds"; @@ -147,12 +158,12 @@ void WeatherManager::setWeather(const String& weather, bool instant) if (mNextWeather != "") { // transition more than 50% finished? - if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600) <= 0.5) + if (mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600) <= 0.5) mCurrentWeather = mNextWeather; } mNextWeather = weather; - mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600; + mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600; } mFirstUpdate = false; } @@ -170,13 +181,13 @@ WeatherResult WeatherManager::getResult(const String& weather) result.mGlareView = current.mGlareView; result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; result.mSunColor = current.mSunDiscSunsetColor; - - result.mNight = (mHour < 6 || mHour > 19); + + result.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1); result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth; // night - if (mHour <= 5.5f || mHour >= 21) + if (mHour <= mNightEnd || mHour >= mNightStart + 1) { result.mFogColor = current.mFogNightColor; result.mAmbientColor = current.mAmbientNightColor; @@ -186,12 +197,12 @@ WeatherResult WeatherManager::getResult(const String& weather) } // sunrise - else if (mHour >= 5.5f && mHour <= 9) + else if (mHour >= mNightEnd && mHour <= mDayStart + 1) { - if (mHour <= 6) + if (mHour <= mSunriseTime) { // fade in - float advance = 6-mHour; + float advance = mSunriseTime - mHour; float factor = advance / 0.5f; result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor); @@ -202,7 +213,7 @@ WeatherResult WeatherManager::getResult(const String& weather) else //if (mHour >= 6) { // fade out - float advance = mHour-6; + float advance = mHour - mSunriseTime; float factor = advance / 3.f; result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor); @@ -212,7 +223,7 @@ WeatherResult WeatherManager::getResult(const String& weather) } // day - else if (mHour >= 9 && mHour <= 17) + else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1) { result.mFogColor = current.mFogDayColor; result.mAmbientColor = current.mAmbientDayColor; @@ -221,12 +232,12 @@ WeatherResult WeatherManager::getResult(const String& weather) } // sunset - else if (mHour >= 17 && mHour <= 21) + else if (mHour >= mDayEnd - 1 && mHour <= mNightStart + 1) { - if (mHour <= 19) + if (mHour <= mDayEnd + 1) { // fade in - float advance = 19-mHour; + float advance = (mDayEnd + 1) - mHour; float factor = (advance / 2); result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor); @@ -236,7 +247,7 @@ WeatherResult WeatherManager::getResult(const String& weather) else //if (mHour >= 19) { // fade out - float advance = mHour-19; + float advance = mHour - (mDayEnd + 1); float factor = advance / 2.f; result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor); @@ -294,7 +305,7 @@ void WeatherManager::update(float duration) if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) { mCurrentRegion = regionstr; - mWeatherUpdateTime = mHoursBetweenWeatherChanges*3600; + mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600; std::string weather = "clear"; @@ -363,7 +374,7 @@ void WeatherManager::update(float duration) } if (mNextWeather != "") - result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600))); + result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); else result = getResult(mCurrentWeather); @@ -372,7 +383,7 @@ void WeatherManager::update(float duration) mRendering->configureFog(result.mFogDepth, result.mFogColor); // disable sun during night - if (mHour >= 20 || mHour <= 6.f) + if (mHour >= mNightStart || mHour <= mSunriseTime) mRendering->getSkyManager()->sunDisable(); else mRendering->getSkyManager()->sunEnable(); @@ -380,28 +391,31 @@ void WeatherManager::update(float duration) // sun angle float height; - // rise at 6, set at 20 - if (mHour >= 6 && mHour <= 20) - height = 1-std::abs(((mHour-13)/7.f)); - else if (mHour > 20) - height = (mHour-20.f)/4.f; - else //if (mHour > 0 && mHour < 6) - height = 1-(mHour/6.f); + //Day duration + float dayDuration = (mNightStart - 1) - mSunriseTime; - int facing = (mHour > 13.f) ? 1 : -1; + // rise at 6, set at 20 + if (mHour >= mSunriseTime && mHour <= mNightStart) + height = 1 - std::abs(((mHour - dayDuration) / 7.f)); + else if (mHour > mNightStart) + height = (mHour - mNightStart) / 4.f; + else //if (mHour > 0 && mHour < 6) + height = 1 - (mHour / mSunriseTime); + + int facing = (mHour > dayDuration) ? 1 : -1; Vector3 final( - -(1-height)*facing, - -(1-height)*facing, + -(1 - height) * facing, + -(1 - height) * facing, height); mRendering->setSunDirection(final); // moon calculations float night; if (mHour >= 14) - night = mHour-14; + night = mHour - 14; else if (mHour <= 10) - night = mHour+10; + night = mHour + 10; else night = 0; @@ -409,16 +423,16 @@ void WeatherManager::update(float duration) if (night != 0) { - float moonHeight = 1-std::abs((night-0.5)*2); - int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1; + float moonHeight = 1 - std::abs((night - 0.5) * 2); + int facing = (mHour > 0.f && mHour< 12.f) ? 1 : -1; Vector3 masser( - (1-moonHeight)*facing, - (1-moonHeight)*facing, + (1 - moonHeight) * facing, + (1 - moonHeight) * facing, moonHeight); Vector3 secunda( - (1-moonHeight)*facing*0.8, - (1-moonHeight)*facing*1.25, + (1 - moonHeight) * facing * 0.8, + (1 - moonHeight) * facing * 1.25, moonHeight); mRendering->getSkyManager()->setMasserDirection(masser); @@ -426,56 +440,56 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->masserEnable(); mRendering->getSkyManager()->secundaEnable(); - float secunda_hour_fade; - float secunda_fadeout_start=mFallback->getFallbackFloat("Moons_Secunda_Fade_Out_Start"); - float secunda_fadein_start=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Start"); - float secunda_fadein_finish=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Finish"); + float secundaHourFade; + float secundaFadeOutStart=mFallback->getFallbackFloat("Moons_Secunda_Fade_Out_Start"); + float secundaFadeInStart=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Start"); + float secundaFadeInFinish=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Finish"); - if (mHour >= secunda_fadeout_start && mHour <= secunda_fadein_start) - secunda_hour_fade = 1-(mHour-secunda_fadeout_start)/3.f; - else if (mHour >= secunda_fadein_start && mHour <= secunda_fadein_finish) - secunda_hour_fade = mHour-secunda_fadein_start; + if (mHour >= secundaFadeOutStart && mHour <= secundaFadeInStart) + secundaHourFade = 1 - (mHour - secundaFadeOutStart) / 3.f; + else if (mHour >= secundaFadeInStart && mHour <= secundaFadeInFinish) + secundaHourFade = mHour - secundaFadeInStart; else - secunda_hour_fade = 1; + secundaHourFade = 1; - float masser_hour_fade; - float masser_fadeout_start=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Start"); - float masser_fadein_start=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start"); - float masser_fadein_finish=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Finish"); - if (mHour >= masser_fadeout_start && mHour <= masser_fadein_start) - masser_hour_fade = 1-(mHour-masser_fadeout_start)/3.f; - else if (mHour >= masser_fadein_start && mHour <= masser_fadein_finish) - masser_hour_fade = mHour-masser_fadein_start; + float masserHourFade; + float masserFadeOutStart=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Start"); + float masserFadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start"); + float masserFadeInFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Finish"); + if (mHour >= masserFadeOutStart && mHour <= masserFadeInStart) + masserHourFade = 1 - (mHour - masserFadeOutStart) / 3.f; + else if (mHour >= masserFadeInStart && mHour <= masserFadeInFinish) + masserHourFade = mHour - masserFadeInStart; else - masser_hour_fade = 1; + masserHourFade = 1; - float angle = moonHeight*90.f; + float angle = moonHeight * 90.f; - float secunda_angle_fade; - float secunda_end_angle=mFallback->getFallbackFloat("Moons_Secunda_Fade_End_Angle"); - float secunda_start_angle=mFallback->getFallbackFloat("Moons_Secunda_Fade_Start_Angle"); - if (angle >= secunda_end_angle && angle <= secunda_start_angle) - secunda_angle_fade = (angle-secunda_end_angle)/20.f; - else if (angle < secunda_end_angle) - secunda_angle_fade = 0.f; + float secundaAngleFade; + float secundaEndAngle=mFallback->getFallbackFloat("Moons_Secunda_Fade_End_Angle"); + float secundaStartAngle=mFallback->getFallbackFloat("Moons_Secunda_Fade_Start_Angle"); + if (angle >= secundaEndAngle && angle <= secundaStartAngle) + secundaAngleFade = (angle - secundaEndAngle) / 20.f; + else if (angle < secundaEndAngle) + secundaAngleFade = 0.f; else - secunda_angle_fade = 1.f; + secundaAngleFade = 1.f; - float masser_angle_fade; - float masser_end_angle=mFallback->getFallbackFloat("Moons_Masser_Fade_End_Angle"); - float masser_start_angle=mFallback->getFallbackFloat("Moons_Masser_Fade_Start_Angle"); - if (angle >= masser_end_angle && angle <= masser_start_angle) - masser_angle_fade = (angle-masser_end_angle)/10.f; - else if (angle < masser_end_angle) - masser_angle_fade = 0.f; + float masserAngleFade; + float masserEndAngle=mFallback->getFallbackFloat("Moons_Masser_Fade_End_Angle"); + float masserStartAngle=mFallback->getFallbackFloat("Moons_Masser_Fade_Start_Angle"); + if (angle >= masserEndAngle && angle <= masserStartAngle) + masserAngleFade = (angle - masserEndAngle) / 10.f; + else if (angle < masserEndAngle) + masserAngleFade = 0.f; else - masser_angle_fade = 1.f; + masserAngleFade = 1.f; - masser_angle_fade *= masser_hour_fade; - secunda_angle_fade *= secunda_hour_fade; + masserAngleFade *= masserHourFade; + secundaAngleFade *= secundaHourFade; - mRendering->getSkyManager()->setMasserFade(masser_angle_fade); - mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade); + mRendering->getSkyManager()->setMasserFade(masserAngleFade); + mRendering->getSkyManager()->setSecundaFade(secundaAngleFade); } else { diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index a1dc454206..fd99e49a8a 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -184,6 +184,10 @@ namespace MWWorld float mThunderFrequency; float mThunderThreshold; float mThunderSoundDelay; + float mNightStart; + float mNightEnd; + float mDayStart; + float mDayEnd; std::string mThunderSoundID0; std::string mThunderSoundID1; std::string mThunderSoundID2; From 8845c0cee1aa83d360bce38c7f375ef880590269 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 May 2013 17:38:24 +0200 Subject: [PATCH 03/18] Camera relative sky rendering. Now we no longer need to keep sky position in sync with camera. --- apps/openmw/mwrender/occlusionquery.cpp | 56 +++++++------------ apps/openmw/mwrender/occlusionquery.hpp | 5 +- apps/openmw/mwrender/sky.cpp | 72 +++++++++---------------- apps/openmw/mwrender/sky.hpp | 20 +++---- apps/openmw/mwrender/water.cpp | 4 -- extern/shiny/Main/Factory.cpp | 5 +- files/materials/atmosphere.shader | 15 +++++- files/materials/clouds.shader | 17 ++++-- files/materials/moon.shader | 18 +++++-- files/materials/sky.mat | 35 +++++++++++- files/materials/stars.shader | 17 ++++-- files/materials/sun.shader | 18 +++++-- 12 files changed, 162 insertions(+), 120 deletions(-) diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index eaa155b066..67e3820e72 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -1,5 +1,4 @@ #include "occlusionquery.hpp" -#include "renderconst.hpp" #include #include @@ -7,8 +6,11 @@ #include #include #include +#include #include +#include "renderconst.hpp" + using namespace MWRender; using namespace Ogre; @@ -16,7 +18,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mWasVisible(false), - mBBNode(0), mActive(false) + mActive(false) { mRendering = renderer; mSunNode = sunNode; @@ -40,39 +42,24 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod return; } - MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); - MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels"); - matQueryArea->setDepthWriteEnabled(false); - matQueryArea->setColourWriteEnabled(false); - matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects - MaterialPtr matQueryVisible = matBase->clone("QueryVisiblePixels"); - matQueryVisible->setDepthWriteEnabled(false); - matQueryVisible->setColourWriteEnabled(false); // Uncomment this to visualize the occlusion query - matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects - matQueryVisible->setCullingMode(CULL_NONE); - matQueryVisible->setManualCullingMode(MANUAL_CULL_NONE); - - if (sunNode) - mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode(); - mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); - mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); + static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("occlusionbillboard", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y); + plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE); + + mBBQueryTotal = mRendering->getScene()->createEntity(plane); mBBQueryTotal->setCastShadows(false); - mBBQueryTotal->setDefaultDimensions(150, 150); - mBBQueryTotal->createBillboard(Vector3::ZERO); - mBBQueryTotal->setMaterialName("QueryTotalPixels"); - mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); + mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); + mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBNodeReal->attachObject(mBBQueryTotal); - mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); + mBBQueryVisible = mRendering->getScene()->createEntity(plane); mBBQueryVisible->setCastShadows(false); - mBBQueryVisible->setDefaultDimensions(150, 150); - mBBQueryVisible->createBillboard(Vector3::ZERO); - mBBQueryVisible->setMaterialName("QueryVisiblePixels"); - mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); + mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); + mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBNodeReal->attachObject(mBBQueryVisible); mRendering->getScene()->addRenderObjectListener(this); @@ -116,12 +103,12 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass // Open a new occlusion query if (mDoQuery == true) { - if (rend == mBBQueryTotal) + if (rend == mBBQueryTotal->getSubEntity(0)) { mActiveQuery = mSunTotalAreaQuery; mWasVisible = true; } - else if (rend == mBBQueryVisible) + else if (rend == mBBQueryVisible->getSubEntity(0)) { mActiveQuery = mSunVisibleAreaQuery; } @@ -170,12 +157,11 @@ void OcclusionQuery::update(float duration) if (dist==0) dist = 10000000; dist -= 1000; // bias dist /= 1000.f; - if (mBBNode) + if (mSunNode) { - mBBNode->setPosition(mSunNode->getPosition() * dist); - mBBNode->setScale(dist, dist, dist); - mBBNodeReal->setPosition(mBBNode->_getDerivedPosition()); - mBBNodeReal->setScale(mBBNode->getScale()); + mBBNodeReal->setPosition(mSunNode->getPosition() * dist); + mBBNodeReal->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-mBBNodeReal->getPosition().normalisedCopy())); + mBBNodeReal->setScale(150.f*dist, 150.f*dist, 150.f*dist); } // Stop occlusion queries until we get their information @@ -209,6 +195,4 @@ void OcclusionQuery::update(float duration) void OcclusionQuery::setSunNode(Ogre::SceneNode* node) { mSunNode = node; - if (!mBBNode) - mBBNode = node->getParentSceneNode()->createChildSceneNode(); } diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index 145d773553..615ada532a 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -49,11 +49,10 @@ namespace MWRender Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery; Ogre::HardwareOcclusionQuery* mActiveQuery; - Ogre::BillboardSet* mBBQueryVisible; - Ogre::BillboardSet* mBBQueryTotal; + Ogre::Entity* mBBQueryVisible; + Ogre::Entity* mBBQueryTotal; Ogre::SceneNode* mSunNode; - Ogre::SceneNode* mBBNode; Ogre::SceneNode* mBBNodeReal; float mSunVisibility; diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 516b48ddef..c24c44fd82 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include #include @@ -41,25 +43,25 @@ BillboardObject::BillboardObject( const String& textureName, static unsigned int bodyCount=0; - /// \todo These billboards are not 100% correct, might want to revisit them later - mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1); - mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize); - mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); - mBBSet->setCommonDirection( -position.normalisedCopy() ); - mBBSet->setVisibilityFlags(RV_Sky); + mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material); + mMaterial->setProperty("texture", sh::makeProperty(new sh::StringValue(textureName))); + + static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("billboard", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y); + plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE); + mEntity = sceneMgr->createEntity(plane); + mEntity->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); + mEntity->setVisibilityFlags(RV_Sky); + mEntity->setCastShadows(false); + mNode = rootNode->createChildSceneNode(); mNode->setPosition(finalPosition); - mNode->attachObject(mBBSet); - mBBSet->createBillboard(0,0,0); - mBBSet->setCastShadows(false); - - mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material); - mMaterial->setProperty("texture", sh::makeProperty(new sh::StringValue(textureName))); + mNode->attachObject(mEntity); + mNode->setScale(Ogre::Vector3(550.f*initialSize)); + mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-position.normalisedCopy())); sh::Factory::getInstance().getMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount))->setListener(this); - mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); - bodyCount++; } @@ -79,12 +81,12 @@ void BillboardObject::createdConfiguration (sh::MaterialInstance* m, const std:: void BillboardObject::setVisible(const bool visible) { - mBBSet->setVisible(visible); + mEntity->setVisible(visible); } void BillboardObject::setSize(const float size) { - mNode->setScale(size, size, size); + mNode->setScale(550.f*size, 550.f*size, 550.f*size); } void BillboardObject::setVisibility(const float visibility) @@ -103,21 +105,18 @@ void BillboardObject::setPosition(const Vector3& pPosition) { Vector3 normalised = pPosition.normalisedCopy(); Vector3 finalPosition = normalised * 1000.f; - - mBBSet->setCommonDirection( -normalised ); - + mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-normalised)); mNode->setPosition(finalPosition); } Vector3 BillboardObject::getPosition() const { - Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition(); - return p; + return mNode->getPosition(); } void BillboardObject::setVisibilityFlags(int flags) { - mBBSet->setVisibilityFlags(flags); + mEntity->setVisibilityFlags(flags); } void BillboardObject::setColour(const ColourValue& pColour) @@ -134,7 +133,7 @@ void BillboardObject::setColour(const ColourValue& pColour) void BillboardObject::setRenderQueue(unsigned int id) { - mBBSet->setRenderQueueGroup(id); + mEntity->setRenderQueueGroup(id); } SceneNode* BillboardObject::getNode() @@ -218,7 +217,6 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera) , mSceneMgr(NULL) , mAtmosphereDay(NULL) , mAtmosphereNight(NULL) - , mCloudFragmentShader() , mClouds() , mNextClouds() , mCloudBlendFactor(0.0f) @@ -283,8 +281,7 @@ void SkyManager::create() mSunGlare->setRenderQueue(RQG_SkiesLate); mSunGlare->setVisibilityFlags(RV_NoReflection); - Ogre::AxisAlignedBox aabInf; - aabInf.setInfinite (); + Ogre::AxisAlignedBox aabInf = Ogre::AxisAlignedBox::BOX_INFINITE; // Stars mAtmosphereNight = mRootNode->createChildSceneNode(); @@ -372,8 +369,6 @@ void SkyManager::update(float duration) { if (!mEnabled) return; const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback(); - mCamera->getParentSceneNode ()->needUpdate (); - mRootNode->setPosition(mCamera->getDerivedPosition()); // UV Scroll the clouds mCloudAnimationTimer += duration * mCloudSpeed; @@ -407,8 +402,7 @@ void SkyManager::update(float duration) Vector3 cam = mCamera->getRealDirection(); const Degree angle = sun.angleBetween( cam ); float val = 1- (angle.valueDegrees() / 180.f); - val = (val*val*val*val)*2; - + val = (val*val*val*val)*6; mSunGlare->setSize(val * mGlareFade); } @@ -537,7 +531,7 @@ void SkyManager::setGlare(const float glare) Vector3 SkyManager::getRealSunPos() { if (!mCreated) return Vector3(0,0,0); - return mSun->getNode()->_getDerivedPosition(); + return mSun->getNode()->getPosition() + mCamera->getRealPosition(); } void SkyManager::sunEnable() @@ -644,22 +638,6 @@ Ogre::SceneNode* SkyManager::getSunNode() return mSun->getNode(); } -void SkyManager::setSkyPosition(const Ogre::Vector3& position) -{ - mRootNode->setPosition(position); -} - -void SkyManager::resetSkyPosition() -{ - mCamera->getParentSceneNode ()->needUpdate (); - mRootNode->setPosition(mCamera->getDerivedPosition()); -} - -void SkyManager::scaleSky(float scale) -{ - mRootNode->setScale(scale, scale, scale); -} - void SkyManager::setGlareEnabled (bool enabled) { if (!mCreated) diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 66557a6c12..3df8846cd4 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -1,5 +1,5 @@ -#ifndef _GAME_RENDER_SKY_H -#define _GAME_RENDER_SKY_H +#ifndef GAME_RENDER_SKY_H +#define GAME_RENDER_SKY_H #include @@ -61,7 +61,7 @@ namespace MWRender Ogre::ColourValue mColour; Ogre::SceneNode* mNode; sh::MaterialInstance* mMaterial; - Ogre::BillboardSet* mBBSet; + Ogre::Entity* mEntity; }; @@ -117,9 +117,6 @@ namespace MWRender void update(float duration); - void create(); - ///< no need to call this, automatically done on first enable() - void enable(); void disable(); @@ -173,11 +170,10 @@ namespace MWRender void setGlareEnabled(bool enabled); Ogre::Vector3 getRealSunPos(); - void setSkyPosition(const Ogre::Vector3& position); - void resetSkyPosition(); - void scaleSky(float scale); - private: + void create(); + ///< no need to call this, automatically done on first enable() + bool mCreated; bool mMoonRed; @@ -200,8 +196,6 @@ namespace MWRender Ogre::SceneNode* mAtmosphereDay; Ogre::SceneNode* mAtmosphereNight; - Ogre::HighLevelGpuProgramPtr mCloudFragmentShader; - // remember some settings so we don't have to apply them again if they didnt change Ogre::String mClouds; Ogre::String mNextClouds; @@ -227,4 +221,4 @@ namespace MWRender }; } -#endif // _GAME_RENDER_SKY_H +#endif // GAME_RENDER_SKY_H diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index c8b9db7f10..772eaf623e 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -136,9 +136,6 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) mCamera->setFOVy(mParentCamera->getFOVy()); mRenderActive = true; - Vector3 pos = mParentCamera->getRealPosition(); - pos.y = (mWaterPlane).d*2 - pos.y; - mSky->setSkyPosition(pos); mCamera->enableReflection(mWaterPlane); // for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane. @@ -153,7 +150,6 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { - mSky->resetSkyPosition(); mCamera->disableReflection(); mCamera->disableCustomNearClipPlane(); mRenderActive = false; diff --git a/extern/shiny/Main/Factory.cpp b/extern/shiny/Main/Factory.cpp index 780d5eece3..c27848b5f0 100644 --- a/extern/shiny/Main/Factory.cpp +++ b/extern/shiny/Main/Factory.cpp @@ -721,7 +721,6 @@ namespace sh // delete any outdated shaders based on this shader set if (removeCache (it->first)) removeBinaryCache = true; - mShadersLastModified[sourceRelative] = lastModified; } } else @@ -730,11 +729,13 @@ namespace sh // in both cases we can safely delete if (removeCache (it->first)) removeBinaryCache = true; - mShadersLastModified[sourceRelative] = lastModified; } mShaderSets.insert(std::make_pair(it->first, newSet)); } + // new is now current + mShadersLastModified = mShadersLastModifiedNew; + return removeBinaryCache; } diff --git a/files/materials/atmosphere.shader b/files/materials/atmosphere.shader index eb05c3e18b..f02c5766fe 100644 --- a/files/materials/atmosphere.shader +++ b/files/materials/atmosphere.shader @@ -3,13 +3,24 @@ #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + shUniform(float4x4, view) @shAutoConstant(view, view_matrix) + shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) shOutput(float, alphaFade) SH_START_PROGRAM { - shOutputPosition = shMatrixMult(wvp, shInputPosition); + float4x4 viewFixed = view; +#if !SH_GLSL + viewFixed[0][3] = 0; + viewFixed[1][3] = 0; + viewFixed[2][3] = 0; +#else + viewFixed[3][0] = 0; + viewFixed[3][1] = 0; + viewFixed[3][2] = 0; +#endif + shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition)); alphaFade = shInputPosition.z < 150.0 ? 0.0 : 1.0; } diff --git a/files/materials/clouds.shader b/files/materials/clouds.shader index e60026d3bd..b76f2ded72 100644 --- a/files/materials/clouds.shader +++ b/files/materials/clouds.shader @@ -3,15 +3,26 @@ #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + shUniform(float4x4, view) @shAutoConstant(view, view_matrix) +shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) shVertexInput(float2, uv0) shOutput(float2, UV) shOutput(float, alphaFade) SH_START_PROGRAM { - shOutputPosition = shMatrixMult(wvp, shInputPosition); - UV = uv0; + float4x4 viewFixed = view; +#if !SH_GLSL + viewFixed[0][3] = 0; + viewFixed[1][3] = 0; + viewFixed[2][3] = 0; +#else + viewFixed[3][0] = 0; + viewFixed[3][1] = 0; + viewFixed[3][2] = 0; +#endif + shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition)); + UV = uv0; alphaFade = (shInputPosition.z <= 200.f) ? ((shInputPosition.z <= 100.f) ? 0.0 : 0.25) : 1.0; } diff --git a/files/materials/moon.shader b/files/materials/moon.shader index 231f60ba06..a7d183d108 100644 --- a/files/materials/moon.shader +++ b/files/materials/moon.shader @@ -3,14 +3,26 @@ #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + shUniform(float4x4, world) @shAutoConstant(world, world_matrix) + shUniform(float4x4, view) @shAutoConstant(view, view_matrix) +shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) shVertexInput(float2, uv0) shOutput(float2, UV) SH_START_PROGRAM { - shOutputPosition = shMatrixMult(wvp, shInputPosition); - UV = uv0; + float4x4 viewFixed = view; +#if !SH_GLSL + viewFixed[0][3] = 0; + viewFixed[1][3] = 0; + viewFixed[2][3] = 0; +#else + viewFixed[3][0] = 0; + viewFixed[3][1] = 0; + viewFixed[3][2] = 0; +#endif + shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition))); + UV = uv0; } #else diff --git a/files/materials/sky.mat b/files/materials/sky.mat index e50aa51d8f..ccf2a8053c 100644 --- a/files/materials/sky.mat +++ b/files/materials/sky.mat @@ -1,3 +1,34 @@ +material QueryTotalPixels +{ + allow_fixed_function false + pass + { + vertex_program sun_vertex + fragment_program sun_fragment + cull_hardware none + polygon_mode_overrideable off + depth_check off + depth_write off + colour_write off + } +} + +material QueryVisiblePixels +{ + allow_fixed_function false + pass + { + vertex_program sun_vertex + fragment_program sun_fragment + cull_hardware none + cull_software none + polygon_mode_overrideable off + depth_check on + depth_write off + colour_write off + } +} + material openmw_moon { allow_fixed_function false @@ -5,7 +36,8 @@ material openmw_moon { vertex_program moon_vertex fragment_program moon_fragment - + cull_hardware none + polygon_mode_overrideable off depth_write off depth_check off @@ -92,6 +124,7 @@ material openmw_sun { vertex_program sun_vertex fragment_program sun_fragment + cull_hardware none polygon_mode_overrideable off diff --git a/files/materials/stars.shader b/files/materials/stars.shader index fea007424b..33f22bd14b 100644 --- a/files/materials/stars.shader +++ b/files/materials/stars.shader @@ -3,15 +3,26 @@ #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) - + shUniform(float4x4, view) @shAutoConstant(view, view_matrix) +shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) + shVertexInput(float2, uv0) shOutput(float2, UV) shOutput(float, fade) SH_START_PROGRAM { - shOutputPosition = shMatrixMult(wvp, shInputPosition); + float4x4 viewFixed = view; +#if !SH_GLSL + viewFixed[0][3] = 0; + viewFixed[1][3] = 0; + viewFixed[2][3] = 0; +#else + viewFixed[3][0] = 0; + viewFixed[3][1] = 0; + viewFixed[3][2] = 0; +#endif + shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shInputPosition)); UV = uv0; fade = (shInputPosition.z > 50) ? 1 : 0; diff --git a/files/materials/sun.shader b/files/materials/sun.shader index 7954f417ce..abe4c97f15 100644 --- a/files/materials/sun.shader +++ b/files/materials/sun.shader @@ -3,14 +3,26 @@ #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + shUniform(float4x4, world) @shAutoConstant(world, world_matrix) + shUniform(float4x4, view) @shAutoConstant(view, view_matrix) +shUniform(float4x4, projection) @shAutoConstant(projection, projection_matrix) shVertexInput(float2, uv0) shOutput(float2, UV) SH_START_PROGRAM { - shOutputPosition = shMatrixMult(wvp, shInputPosition); - UV = uv0; + float4x4 viewFixed = view; +#if !SH_GLSL + viewFixed[0][3] = 0; + viewFixed[1][3] = 0; + viewFixed[2][3] = 0; +#else + viewFixed[3][0] = 0; + viewFixed[3][1] = 0; + viewFixed[3][2] = 0; +#endif + shOutputPosition = shMatrixMult(projection, shMatrixMult(viewFixed, shMatrixMult(world, shInputPosition))); + UV = uv0; } #else From 301efb411ecf53f01c985f8556e91f51d7c40e63 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 7 May 2013 19:15:28 +0200 Subject: [PATCH 04/18] Fix exit crash --- apps/openmw/mwrender/occlusionquery.cpp | 8 ++++---- apps/openmw/mwrender/sky.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 67e3820e72..5a4790b971 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -44,18 +44,18 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); - static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("occlusionbillboard", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y); + static Ogre::Mesh* plane = MeshManager::getSingleton().createPlane("occlusionbillboard", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y).get(); plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE); - mBBQueryTotal = mRendering->getScene()->createEntity(plane); + mBBQueryTotal = mRendering->getScene()->createEntity("occlusionbillboard"); mBBQueryTotal->setCastShadows(false); mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBNodeReal->attachObject(mBBQueryTotal); - mBBQueryVisible = mRendering->getScene()->createEntity(plane); + mBBQueryVisible = mRendering->getScene()->createEntity("occlusionbillboard"); mBBQueryVisible->setCastShadows(false); mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index c24c44fd82..0b9c7e250d 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -46,10 +46,10 @@ BillboardObject::BillboardObject( const String& textureName, mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material); mMaterial->setProperty("texture", sh::makeProperty(new sh::StringValue(textureName))); - static Ogre::MeshPtr plane = MeshManager::getSingleton().createPlane("billboard", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y); + static Ogre::Mesh* plane = MeshManager::getSingleton().createPlane("billboard", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y).get(); plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE); - mEntity = sceneMgr->createEntity(plane); + mEntity = sceneMgr->createEntity("billboard"); mEntity->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount)); mEntity->setVisibilityFlags(RV_Sky); mEntity->setCastShadows(false); From a328a03bd305fdfe55020fe68946c3c844b40ce5 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 7 May 2013 19:35:10 +0100 Subject: [PATCH 05/18] more fix. Fargoth quest almost work as in vanilla now. --- apps/openmw/mwworld/physicssystem.cpp | 5 +---- libs/openengine/bullet/physic.cpp | 16 ++++++++-------- libs/openengine/bullet/physic.hpp | 4 ++-- libs/openengine/bullet/trace.cpp | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 8b6de68049..b309bd1dba 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -339,8 +339,7 @@ namespace MWWorld _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - std::pair result = mEngine->rayTest(_from, _to, false);//raycastingObjectOnly); - std::cout << result.first << " " << result.second; + std::pair result = mEngine->rayTest(_from, _to, raycastingObjectOnly); return !(result.first == ""); } @@ -419,7 +418,6 @@ namespace MWWorld OEngine::Physic::RigidBody* raycastingBody = mEngine->createAndAdjustRigidBody( mesh, node->getName(), node->getScale().x, node->getPosition(), node->getOrientation(), 0, 0, true, placeable); mEngine->addRigidBody(body, true, raycastingBody); - std::cout << "Object:" << mesh; } void PhysicsSystem::addActor (const Ptr& ptr) @@ -428,7 +426,6 @@ namespace MWWorld Ogre::SceneNode* node = ptr.getRefData().getBaseNode(); //TODO:optimize this. Searching the std::map isn't very efficient i think. mEngine->addCharacter(node->getName(), mesh, node->getPosition(), node->getScale().x, node->getOrientation()); - std::cout << "Actor:" << mesh; } void PhysicsSystem::removeObject (const std::string& handle) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index e6fd18ea2e..74a204cd72 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -28,7 +28,7 @@ namespace Physic mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true); Ogre::Quaternion inverse = mBoxRotation.Inverse(); mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w); - //mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map + mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map } PhysicActor::~PhysicActor() @@ -109,7 +109,7 @@ namespace Physic //Create the newly scaled rigid body mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot); mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot, 0, 0, true); - mEngine->addRigidBody(mBody, false, mRaycastingBody); //Add rigid body to dynamics world, but do not add to object map + mEngine->addRigidBody(mBody, false, mRaycastingBody,true); //Add rigid body to dynamics world, but do not add to object map } Ogre::Vector3 PhysicActor::getHalfExtents() const @@ -331,8 +331,8 @@ namespace Physic mHeightFieldMap [name] = hf; - dynamicsWorld->addRigidBody(body,CollisionType_World|CollisionType_Raycasting, - CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal|CollisionType_Raycasting); + dynamicsWorld->addRigidBody(body,CollisionType_HeightMap|CollisionType_Raycasting, + CollisionType_World|CollisionType_Actor|CollisionType_Raycasting); } void PhysicEngine::removeHeightField(int x, int y) @@ -430,8 +430,8 @@ namespace Physic const std::string& name = (body ? body->mName : raycastingBody->mName); if (body){ - if(actor) {dynamicsWorld->addRigidBody(body,CollisionType_ActorInternal,CollisionType_World|CollisionType_ActorInternal);std::cout << "actor";} - else dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal); + if(actor) dynamicsWorld->addRigidBody(body,CollisionType_Actor,CollisionType_World|CollisionType_HeightMap); + else dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_Actor|CollisionType_HeightMap); } if (raycastingBody) @@ -613,7 +613,7 @@ namespace Physic float d1 = 10000.; btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); if(raycastingObjectOnly) resultCallback1.m_collisionFilterMask = CollisionType_Raycasting; - else resultCallback1.m_collisionFilterMask = CollisionType_ActorExternal; + else resultCallback1.m_collisionFilterMask = CollisionType_World; dynamicsWorld->rayTest(from, to, resultCallback1); if (resultCallback1.hasHit()) { @@ -644,7 +644,7 @@ namespace Physic std::pair PhysicEngine::sphereCast (float radius, btVector3& from, btVector3& to) { OurClosestConvexResultCallback callback(from, to); - callback.m_collisionFilterMask = OEngine::Physic::CollisionType_World; + callback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap; btSphereShape shape(radius); const btQuaternion btrot(0.0f, 0.0f, 0.0f); diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 063c8be0e1..03c8493f0e 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -46,8 +46,8 @@ namespace Physic enum CollisionType { CollisionType_Nothing = 0, //dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback); From 603af21715677e65cb29d645e3bfac9660e21a12 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 7 May 2013 19:42:21 +0100 Subject: [PATCH 06/18] little interface improvement --- apps/openmw/mwworld/physicssystem.cpp | 4 ++-- apps/openmw/mwworld/physicssystem.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 2 +- libs/openengine/bullet/physic.cpp | 4 +++- libs/openengine/bullet/physic.hpp | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index b309bd1dba..c4120f8ff7 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -333,13 +333,13 @@ namespace MWWorld return result; } - bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly) + bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly,bool ignoreHeightMap) { btVector3 _from, _to; _from = btVector3(from.x, from.y, from.z); _to = btVector3(to.x, to.y, to.z); - std::pair result = mEngine->rayTest(_from, _to, raycastingObjectOnly); + std::pair result = mEngine->rayTest(_from, _to, raycastingObjectOnly,ignoreHeightMap); return !(result.first == ""); } diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index ad8eb2ebae..7b48f880ee 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -63,7 +63,7 @@ namespace MWWorld // cast ray, return true if it hit something. if raycasringObjectOnlt is set to false, it ignores NPCs and objects with no collisions. - bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool raycastingObjectOnly = true); + bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool raycastingObjectOnly = true,bool ignoreHeightMap = false); std::pair castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a40889515e..facc4925d5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1046,7 +1046,7 @@ namespace MWWorld { Ogre::Vector3 a(x1,y1,z1);std::cout << x1 << " " << x2; Ogre::Vector3 b(x2,y2,z2); - return mPhysics->castRay(a,b,false); + return mPhysics->castRay(a,b,false,true); } void World::processDoors(float duration) diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 74a204cd72..9537deb283 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -605,7 +605,7 @@ namespace Physic { } - std::pair PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly) + std::pair PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap) { std::string name = ""; float d = -1; @@ -614,6 +614,8 @@ namespace Physic btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); if(raycastingObjectOnly) resultCallback1.m_collisionFilterMask = CollisionType_Raycasting; else resultCallback1.m_collisionFilterMask = CollisionType_World; + + if(!ignoreHeightMap) resultCallback1.m_collisionFilterMask = resultCallback1.m_collisionFilterMask|| CollisionType_HeightMap; dynamicsWorld->rayTest(from, to, resultCallback1); if (resultCallback1.hasHit()) { diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 03c8493f0e..fbd9507fb1 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -293,7 +293,7 @@ namespace Physic /** * Return the closest object hit by a ray. If there are no objects, it will return ("",-1). */ - std::pair rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true); + std::pair rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false); /** * Return all objects hit by a ray. From 15afbe58a833b5a72d2a51eb051679656451c7d8 Mon Sep 17 00:00:00 2001 From: gus Date: Tue, 7 May 2013 19:43:44 +0100 Subject: [PATCH 07/18] minor corretion --- libs/openengine/bullet/physic.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index fbd9507fb1..80c681fe5b 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -46,8 +46,8 @@ namespace Physic enum CollisionType { CollisionType_Nothing = 0, // Date: Wed, 8 May 2013 13:55:15 +0200 Subject: [PATCH 08/18] Fix image buttons --- apps/openmw/mwgui/bookwindow.cpp | 21 ++++++++++ apps/openmw/mwgui/bookwindow.hpp | 1 + apps/openmw/mwgui/journalwindow.cpp | 38 +++++++++++++++++ apps/openmw/mwgui/scrollwindow.cpp | 15 +++++++ files/mygui/openmw_book.layout | 26 ++++++------ files/mygui/openmw_journal.layout | 63 ++++++++++++++--------------- files/mygui/openmw_scroll.layout | 2 +- 7 files changed, 120 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 12e5b466b3..3b5deb5acc 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -38,6 +38,18 @@ namespace MWGui getWidget(mLeftPage, "LeftPage"); getWidget(mRightPage, "RightPage"); + adjustButton(mCloseButton); + adjustButton(mTakeButton); + adjustButton(mNextPageButton); + adjustButton(mPrevPageButton); + + if (mNextPageButton->getSize().width == 64) + { + // english button has a 7 pixel wide strip of garbage on its right edge + mNextPageButton->setSize(64-7, mNextPageButton->getSize().height); + mNextPageButton->setImageCoord(MyGUI::IntCoord(0,0,64-7,mNextPageButton->getSize().height)); + } + center(); } @@ -174,4 +186,13 @@ namespace MWGui } } + void BookWindow::adjustButton (MWGui::ImageButton* button) + { + MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(); + button->setSize(button->getRequestedSize()); + + if (button->getAlign().isRight()) + button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0)); + } + } diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index 9123969e09..c6ea486d44 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -27,6 +27,7 @@ namespace MWGui void updatePages(); void clearPages(); + void adjustButton(MWGui::ImageButton* button); private: MWGui::ImageButton* mCloseButton; diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index d0332c9431..e463bf0ba3 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -137,10 +137,47 @@ namespace getPage (QuestsPage)->adviseLinkClicked (callback); } + adjustButton(OptionsBTN); + adjustButton(PrevPageBTN); + adjustButton(NextPageBTN); + adjustButton(CloseBTN); + adjustButton(CancelBTN); + adjustButton(ShowAllBTN); + adjustButton(ShowActiveBTN); + adjustButton(JournalBTN); + + MWGui::ImageButton* nextButton = getWidget(NextPageBTN); + if (nextButton->getSize().width == 64) + { + // english button has a 7 pixel wide strip of garbage on its right edge + nextButton->setSize(64-7, nextButton->getSize().height); + nextButton->setImageCoord(MyGUI::IntCoord(0,0,64-7,nextButton->getSize().height)); + } + + adjustButton(TopicsBTN); + adjustButton(QuestsBTN); + int width = getWidget(TopicsBTN)->getSize().width + getWidget(QuestsBTN)->getSize().width; + int topicsWidth = getWidget(TopicsBTN)->getSize().width; + int pageWidth = getWidget(RightBookPage)->getSize().width; + + getWidget(TopicsBTN)->setPosition((pageWidth - width)/2, getWidget(TopicsBTN)->getPosition().top); + getWidget(QuestsBTN)->setPosition((pageWidth - width)/2 + topicsWidth, getWidget(QuestsBTN)->getPosition().top); + mQuestMode = false; mAllQuests = false; } + void adjustButton (char const * name) + { + MWGui::ImageButton* button = getWidget(name); + + MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(); + button->setSize(button->getRequestedSize()); + + if (button->getAlign().isRight()) + button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0)); + } + void open() { mModel->load (); @@ -391,6 +428,7 @@ namespace void notifyClose(MyGUI::Widget* _sender) { + MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0); MWBase::Environment::get().getWindowManager ()->popGuiMode (); } diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index b44c21c6eb..eb46b9c1e6 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -10,6 +10,18 @@ #include "formatting.hpp" +namespace +{ + void adjustButton (MWGui::ImageButton* button) + { + MyGUI::IntSize diff = button->getSize() - button->getRequestedSize(); + button->setSize(button->getRequestedSize()); + + if (button->getAlign().isRight()) + button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0)); + } +} + namespace MWGui { @@ -26,6 +38,9 @@ namespace MWGui getWidget(mTakeButton, "TakeButton"); mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked); + adjustButton(mCloseButton); + adjustButton(mTakeButton); + center(); } diff --git a/files/mygui/openmw_book.layout b/files/mygui/openmw_book.layout index 96d1153f0e..d9ac2f43ae 100644 --- a/files/mygui/openmw_book.layout +++ b/files/mygui/openmw_book.layout @@ -8,25 +8,27 @@ - - - - - + + + + + + - - - - - + + + + + + + - - + diff --git a/files/mygui/openmw_journal.layout b/files/mygui/openmw_journal.layout index 1b440b8337..58d2c2690a 100644 --- a/files/mygui/openmw_journal.layout +++ b/files/mygui/openmw_journal.layout @@ -8,6 +8,21 @@ + + + + + + + + + + + + + + + @@ -17,29 +32,16 @@ - - - - - - - - - - - - + - - + - @@ -62,6 +64,18 @@ + + + + + + + + + + + + @@ -72,36 +86,19 @@ - - - - - - - - - - - - - - - - + - - diff --git a/files/mygui/openmw_scroll.layout b/files/mygui/openmw_scroll.layout index 6315c02416..194700f36e 100644 --- a/files/mygui/openmw_scroll.layout +++ b/files/mygui/openmw_scroll.layout @@ -13,7 +13,7 @@ - + From 51067698a877eb4f4ca658ee23906c10a1f63f48 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 8 May 2013 21:26:39 +0200 Subject: [PATCH 09/18] minor cleanup --- apps/openmw/mwmechanics/pathfinding.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 3f175e00e8..62c825be75 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -92,7 +92,7 @@ namespace const PathGridGraph & mGraph; PointID mGoal; };*/ - + class goalVisited : public boost::default_dijkstra_visitor { public: @@ -177,7 +177,6 @@ namespace MWMechanics if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX,startPoint.mY,startPoint.mZ, endPoint.mX,endPoint.mY,endPoint.mZ) ) { - std::cout << "hit"; int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ); int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ); From 10840765d91eeda98227866a1f991ad015ba1a1c Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 8 May 2013 15:27:20 -0700 Subject: [PATCH 10/18] Framework - duration and pathing implemented, no waiting for follower yet. --- apps/openmw/mwmechanics/aiescort.cpp | 194 +++++++++++++++++++++++---- apps/openmw/mwmechanics/aiescort.hpp | 45 +++++-- 2 files changed, 207 insertions(+), 32 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index ebbea55b0e..6ffdb960eb 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,30 +1,178 @@ #include "aiescort.hpp" -#include - -MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x, float y, float z) -: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) -{ -} +#include + +#include "character.hpp" + +#include "../mwworld/class.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/timestamp.hpp" +#include "../mwbase/environment.hpp" +#include "../mwworld/player.hpp" +#include "movement.hpp" + +#include +#include +#include "boost/tuple/tuple.hpp" + +namespace +{ + float sgn(float a) + { + if(a>0) return 1.; + else return -1.; + } +} + +// TODO: Fix all commenting! +// TODO: Test vanilla behavior on passing x0, y0, and z0 with duration of anything including 0. +// TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. +// Necessary? MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, true); + +MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x, float y, float z) +: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) +{ + //\ < The CS Help File states that if a duration is givin, the AI package will run for that long + // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. + if(mX != 0 || mY != 0 || mZ != 0) + mDuration = 0; + + else + { + MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + std::cout << "AiEscort Started at: " << mStartingSecond << " For: " + << duration << "Started At: " << mStartingSecond << std::endl; + } +} MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z) : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) { + //\ < The CS Help File states that if a duration is givin, the AI package will run for that long + // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. + if(mX != 0 || mY != 0 || mZ != 0) + mDuration = 0; + + else + { + MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); + std::cout << "AiEscort Started at: " << mStartingSecond << " For: " + << duration << "Started At: " << mStartingSecond << std::endl; + } +} + + +MWMechanics::AiEscort *MWMechanics::AiEscort::clone() const +{ + return new AiEscort(*this); +} + +bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) +{ + // If AiEscort has ran for as long or longer then the duration specified + // and the duration is not infinite, the package is complete. + if(mDuration != 0) + { + MWWorld::TimeStamp current = MWBase::Environment::get().getWorld()->getTimeStamp(); + unsigned int currentSecond = ((current.getHour() - int(current.getHour())) * 100); + std::cout << "AiEscort: " << currentSecond << " time: " << currentSecond - mStartingSecond << std::endl; + if(currentSecond - mStartingSecond >= mDuration) + { + std::cout << "AiEscort Has Run It's Duration: " << currentSecond - mStartingSecond + << " >= " << mDuration << std::endl; + return true; + } + } + + ESM::Position pos = actor.getRefData().getPosition(); + bool cellChange = actor.getCell()->mCell->mData.mX != cellX || actor.getCell()->mCell->mData.mY != cellY; + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const ESM::Pathgrid *pathgrid = + MWBase::Environment::get().getWorld()->getStore().get().search(*actor.getCell()->mCell); + + + if(actor.getCell()->mCell->mData.mX != player.getCell()->mCell->mData.mX) + { + int sideX = sgn(actor.getCell()->mCell->mData.mX - player.getCell()->mCell->mData.mX); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideX*(pos.pos[0] - actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE) > sideX*(ESM::Land::REAL_SIZE/2. - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } + } + if(actor.getCell()->mCell->mData.mY != player.getCell()->mCell->mData.mY) + { + int sideY = sgn(actor.getCell()->mCell->mData.mY - player.getCell()->mCell->mData.mY); + // Check if actor is near the border of an inactive cell. If so, disable AiEscort. + // FIXME: This *should* pause the AiEscort package instead of terminating it. + if(sideY*(pos.pos[1] - actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE) > sideY*(ESM::Land::REAL_SIZE/2. - 200)) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } + } + + + if(!mPathFinder.isPathConstructed() || cellChange) + { + cellX = actor.getCell()->mCell->mData.mX; + cellY = actor.getCell()->mCell->mData.mY; + float xCell = 0; + float yCell = 0; + if (actor.getCell()->mCell->isExterior()) + { + xCell = actor.getCell()->mCell->mData.mX * ESM::Land::REAL_SIZE; + yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE; + } + + ESM::Pathgrid::Point dest; + dest.mX = mX; + dest.mY = mY; + dest.mZ = mZ; + + ESM::Pathgrid::Point start; + start.mX = pos.pos[0]; + start.mY = pos.pos[1]; + start.mZ = pos.pos[2]; + + mPathFinder.buildPath(start,dest,pathgrid,xCell,yCell); + } + + if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2])) + { + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + return true; + } + +/* + if(getDistanceBetween() <= ???) + { + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + } + // Stop moving if the player is to far away + else + { + // TODO: Set the actor to do the equivilent of AIWander 0 0 0 playing the "look back" idle animation. + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + } +*/ + // Delete these three when above code is enabled! + + + float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); + MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); + MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + + return false; +} + +int MWMechanics::AiEscort::getTypeId() const +{ + return 2; } - -MWMechanics::AiEscort *MWMechanics::AiEscort::clone() const -{ - return new AiEscort(*this); -} - -bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) -{ - std::cout << "AiEscort completed. \n"; - return true; -} - -int MWMechanics::AiEscort::getTypeId() const -{ - return 2; -} - diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index d89a9586ce..69e24e9fb1 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -2,13 +2,36 @@ #define GAME_MWMECHANICS_AIESCORT_H #include "aipackage.hpp" +#include "pathfinding.hpp" #include +/* From CS: +Escort + +Makes the actor escort another actor to a location or for a specified period of time. During this time the actor will also protect the actor it is escorting. + +If you are not doing this package with the player as the target, you’ll want to also put a follow package on the target Actor, since escorting an actor makes the escorter wait for the other actor. If the Target does not know they are supposed to follow, the escorter will most likely just stand there. + +Target: The ActorID to Escort. Remember that since all ActorIDs share the same AI packages, putting this on an Actor with multiple references will cause ALL references of that actor to attempt to escort the same actor. Thus, this type of AI should only be placed on specific or unique sets of Actors. + +Duration: The duration the actor should escort for. Trumped by providing a location. + +Escort to: Check this to use location data for the escort. + +Cell: The Cell to escort to. + +XYZ: Like Travel, specify the XYZ location to escort to. + +View Location: A red X will appear in the render window that you can move around with the standard render window object controls. Place the X on the escort destination. + + +*/ + namespace MWMechanics -{ - class AiEscort : public AiPackage - { - public: +{ + class AiEscort : public AiPackage + { + public: AiEscort(const std::string &actorId,int duration, float x, float y, float z); ///< \implement AiEscort AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z); @@ -27,8 +50,12 @@ namespace MWMechanics float mX; float mY; float mZ; - int mDuration; - - }; -} -#endif + unsigned int mStartingSecond; + unsigned int mDuration; + + PathFinder mPathFinder; + int cellX; + int cellY; + }; +} +#endif From c605f15a15d1022a2b493f2e75ca0a0b2b707b5d Mon Sep 17 00:00:00 2001 From: Glorf Date: Thu, 9 May 2013 00:36:58 +0200 Subject: [PATCH 11/18] Another weather cleanup --- apps/openmw/mwworld/weather.cpp | 75 ++++++++++++++------------------- apps/openmw/mwworld/weather.hpp | 3 ++ 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index cb9c8f2c46..1e5cbd389a 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -24,6 +24,7 @@ namespace { return x * (1-factor) + y * factor; } + Ogre::ColourValue lerp (const Ogre::ColourValue& x, const Ogre::ColourValue& y, float factor) { return x * (1-factor) + y * factor; @@ -61,6 +62,33 @@ void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name mWeatherSettings[name] = weather; } + +float WeatherManager::calculateHourFade (const std::string& moonName) +{ + float fadeOutStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Start"); + float fadeInStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Start"); + float fadeInFinish=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Finish"); + + if (mHour >= fadeOutStart && mHour <= fadeInStart) + return (1 - (mHour - fadeOutStart)); + else if (mHour >= fadeInStart && mHour <= fadeInFinish) + return (mHour - fadeInStart); + else + return 1; +} + +float WeatherManager::calculateAngleFade (const std::string& moonName, float angle) +{ + float endAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_End_Angle"); + float startAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Start_Angle"); + if (angle >= endAngle && angle <= startAngle) + return (angle - endAngle); + else if (angle < endAngle) + return 0.f; + else + return 1.f; +} + WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) : mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), @@ -440,50 +468,11 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->masserEnable(); mRendering->getSkyManager()->secundaEnable(); - float secundaHourFade; - float secundaFadeOutStart=mFallback->getFallbackFloat("Moons_Secunda_Fade_Out_Start"); - float secundaFadeInStart=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Start"); - float secundaFadeInFinish=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Finish"); - - if (mHour >= secundaFadeOutStart && mHour <= secundaFadeInStart) - secundaHourFade = 1 - (mHour - secundaFadeOutStart) / 3.f; - else if (mHour >= secundaFadeInStart && mHour <= secundaFadeInFinish) - secundaHourFade = mHour - secundaFadeInStart; - else - secundaHourFade = 1; - - float masserHourFade; - float masserFadeOutStart=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Start"); - float masserFadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start"); - float masserFadeInFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Finish"); - if (mHour >= masserFadeOutStart && mHour <= masserFadeInStart) - masserHourFade = 1 - (mHour - masserFadeOutStart) / 3.f; - else if (mHour >= masserFadeInStart && mHour <= masserFadeInFinish) - masserHourFade = mHour - masserFadeInStart; - else - masserHourFade = 1; - float angle = moonHeight * 90.f; - - float secundaAngleFade; - float secundaEndAngle=mFallback->getFallbackFloat("Moons_Secunda_Fade_End_Angle"); - float secundaStartAngle=mFallback->getFallbackFloat("Moons_Secunda_Fade_Start_Angle"); - if (angle >= secundaEndAngle && angle <= secundaStartAngle) - secundaAngleFade = (angle - secundaEndAngle) / 20.f; - else if (angle < secundaEndAngle) - secundaAngleFade = 0.f; - else - secundaAngleFade = 1.f; - - float masserAngleFade; - float masserEndAngle=mFallback->getFallbackFloat("Moons_Masser_Fade_End_Angle"); - float masserStartAngle=mFallback->getFallbackFloat("Moons_Masser_Fade_Start_Angle"); - if (angle >= masserEndAngle && angle <= masserStartAngle) - masserAngleFade = (angle - masserEndAngle) / 10.f; - else if (angle < masserEndAngle) - masserAngleFade = 0.f; - else - masserAngleFade = 1.f; + float masserHourFade = calculateHourFade("Masser"); + float secundaHourFade = calculateHourFade("Secunda"); + float masserAngleFade = calculateAngleFade("Masser", angle); + float secundaAngleFade = calculateAngleFade("Secunda", angle); masserAngleFade *= masserHourFade; secundaAngleFade *= secundaHourFade; diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index fd99e49a8a..bf6c8bfd8b 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -174,6 +174,9 @@ namespace MWWorld WeatherResult transition(const float factor); WeatherResult getResult(const Ogre::String& weather); + float calculateHourFade (const std::string& moonName); + float calculateAngleFade (const std::string& moonName, float angle); + void setWeather(const Ogre::String& weather, bool instant=false); float mSunriseTime; float mSunsetTime; From c03dca47f5a5df24c58cee243ef80b34d5d352dc Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 8 May 2013 17:19:47 -0700 Subject: [PATCH 12/18] AIEscort implemented and working - only touchups are needed. --- apps/openmw/mwmechanics/aiescort.cpp | 58 +++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 6ffdb960eb..6366f5da22 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,5 +1,6 @@ #include "aiescort.hpp" #include +#include #include "character.hpp" @@ -21,6 +22,42 @@ namespace if(a>0) return 1.; else return -1.; } + + /* + + MWWorld::Ptr InterpreterContext::getReference ( + const std::string& id, bool activeOnly) + { + if (!id.empty()) + { + return MWBase::Environment::get().getWorld()->getPtr (id, activeOnly); + } + else + { + if (mReference.isEmpty()) + throw std::runtime_error ("no implicit reference"); + + return mReference; + } + } + + float InterpreterContext::getDistance (const std::string& name, const std::string& id) const + { + // TODO handle exterior cells (when ref and ref2 are located in different cells) + /const MWWorld::Ptr ref2 = MWBase::Environment::get().getWorld()->getPtr(id, false); + + double diff[3]; + + const float* const pos1 = actor.getRefData().getPosition().pos; + const float* const pos2 = ref2.getRefData().getPosition().pos; + + for (int i=0; i<3; ++i) + diff[i] = pos1[i] - pos2[i]; + + return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]); + } + */ + } // TODO: Fix all commenting! @@ -147,8 +184,18 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) return true; } -/* - if(getDistanceBetween() <= ???) + const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); + const float* const leaderPos = actor.getRefData().getPosition().pos; + const float* const followerPos = follower.getRefData().getPosition().pos; + double differenceBetween[3]; + + for (short i = 0; i < 3; ++i) + differenceBetween[i] = (leaderPos[i] - followerPos[i]); + + float distanceBetweenResult = + std::sqrt((differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2])); + + if(distanceBetweenResult <= 500) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); @@ -160,13 +207,6 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) // TODO: Set the actor to do the equivilent of AIWander 0 0 0 playing the "look back" idle animation. MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; } -*/ - // Delete these three when above code is enabled! - - - float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); - MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); - MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; return false; } From 133964f0e48910508f2cb2cbcbf84ed88bf3a1c0 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 8 May 2013 20:02:24 -0700 Subject: [PATCH 13/18] AIEscort complete --- apps/openmw/mwmechanics/aiescort.cpp | 70 +++++++++------------------- apps/openmw/mwmechanics/aiescort.hpp | 1 + 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index 6366f5da22..c30146e6e7 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -3,13 +3,14 @@ #include #include "character.hpp" +#include "movement.hpp" #include "../mwworld/class.hpp" -#include "../mwbase/world.hpp" -#include "../mwworld/timestamp.hpp" -#include "../mwbase/environment.hpp" #include "../mwworld/player.hpp" -#include "movement.hpp" +#include "../mwworld/timestamp.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include #include @@ -22,53 +23,20 @@ namespace if(a>0) return 1.; else return -1.; } - - /* - - MWWorld::Ptr InterpreterContext::getReference ( - const std::string& id, bool activeOnly) - { - if (!id.empty()) - { - return MWBase::Environment::get().getWorld()->getPtr (id, activeOnly); - } - else - { - if (mReference.isEmpty()) - throw std::runtime_error ("no implicit reference"); - - return mReference; - } - } - - float InterpreterContext::getDistance (const std::string& name, const std::string& id) const - { - // TODO handle exterior cells (when ref and ref2 are located in different cells) - /const MWWorld::Ptr ref2 = MWBase::Environment::get().getWorld()->getPtr(id, false); - - double diff[3]; - - const float* const pos1 = actor.getRefData().getPosition().pos; - const float* const pos2 = ref2.getRefData().getPosition().pos; - - for (int i=0; i<3; ++i) - diff[i] = pos1[i] - pos2[i]; - - return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]); - } - */ - } -// TODO: Fix all commenting! -// TODO: Test vanilla behavior on passing x0, y0, and z0 with duration of anything including 0. -// TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. -// Necessary? MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, true); +/* + TODO: Test vanilla behavior on passing x0, y0, and z0 with duration of anything including 0. + TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. + TODO: Take account for actors being in different cells. +*/ MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x, float y, float z) : mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration) { - //\ < The CS Help File states that if a duration is givin, the AI package will run for that long + mMaxDist = 470; + + // The CS Help File states that if a duration is givin, the AI package will run for that long // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. if(mX != 0 || mY != 0 || mZ != 0) mDuration = 0; @@ -85,7 +53,9 @@ MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z) : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration) { - //\ < The CS Help File states that if a duration is givin, the AI package will run for that long + mMaxDist = 470; + + // The CS Help File states that if a duration is givin, the AI package will run for that long // BUT if a location is givin, it "trumps" the duration so it will simply escort to that location. if(mX != 0 || mY != 0 || mZ != 0) mDuration = 0; @@ -195,17 +165,19 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) float distanceBetweenResult = std::sqrt((differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2])); - if(distanceBetweenResult <= 500) + if(distanceBetweenResult <= mMaxDist) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1; + mMaxDist = 470; } - // Stop moving if the player is to far away else { - // TODO: Set the actor to do the equivilent of AIWander 0 0 0 playing the "look back" idle animation. + // Stop moving if the player is to far away + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, "idle3", 0, 1); MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 0; + mMaxDist = 330; } return false; diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index 69e24e9fb1..667b88e31a 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -50,6 +50,7 @@ namespace MWMechanics float mX; float mY; float mZ; + float mMaxDist; unsigned int mStartingSecond; unsigned int mDuration; From d20178dd56a53a03a844ec615e2eb669d1923c44 Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 8 May 2013 20:05:45 -0700 Subject: [PATCH 14/18] Removed unnecessary std::cout messages --- apps/openmw/mwmechanics/aiescort.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index c30146e6e7..cd4ea7a613 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,5 +1,4 @@ #include "aiescort.hpp" -#include #include #include "character.hpp" @@ -45,8 +44,6 @@ MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x { MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); - std::cout << "AiEscort Started at: " << mStartingSecond << " For: " - << duration << "Started At: " << mStartingSecond << std::endl; } } @@ -64,8 +61,6 @@ MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &ce { MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp(); mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100); - std::cout << "AiEscort Started at: " << mStartingSecond << " For: " - << duration << "Started At: " << mStartingSecond << std::endl; } } @@ -86,8 +81,6 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) std::cout << "AiEscort: " << currentSecond << " time: " << currentSecond - mStartingSecond << std::endl; if(currentSecond - mStartingSecond >= mDuration) { - std::cout << "AiEscort Has Run It's Duration: " << currentSecond - mStartingSecond - << " >= " << mDuration << std::endl; return true; } } From 4928c9d079bab7f59f90b05812706daf3943aa4c Mon Sep 17 00:00:00 2001 From: Torben Carrington Date: Wed, 8 May 2013 20:47:31 -0700 Subject: [PATCH 15/18] Removed sqrt function call (minor optimization thanks to Chris) --- apps/openmw/mwmechanics/aiescort.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index cd4ea7a613..7c28dd216c 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -1,5 +1,4 @@ #include "aiescort.hpp" -#include #include "character.hpp" #include "movement.hpp" @@ -156,9 +155,9 @@ bool MWMechanics::AiEscort::execute (const MWWorld::Ptr& actor) differenceBetween[i] = (leaderPos[i] - followerPos[i]); float distanceBetweenResult = - std::sqrt((differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2])); + (differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2]); - if(distanceBetweenResult <= mMaxDist) + if(distanceBetweenResult <= mMaxDist * mMaxDist) { float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]); MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false); From fe5aaa9dffa94a804134be3f9984496894d60af6 Mon Sep 17 00:00:00 2001 From: gus Date: Thu, 9 May 2013 11:12:55 +0100 Subject: [PATCH 16/18] fix NPC collisions --- libs/openengine/bullet/trace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openengine/bullet/trace.cpp b/libs/openengine/bullet/trace.cpp index 88d33a7e35..d246417c7a 100644 --- a/libs/openengine/bullet/trace.cpp +++ b/libs/openengine/bullet/trace.cpp @@ -27,7 +27,7 @@ void newtrace(traceResults *results, const Ogre::Quaternion& orient, const Ogre: const btTransform to(btorient, btend); btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend); - newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap; + newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap|OEngine::Physic::CollisionType_Actor; enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback); From 6417fa504e45a5703664925c28e958b2c8d5fe23 Mon Sep 17 00:00:00 2001 From: Glorf Date: Thu, 9 May 2013 13:56:13 +0200 Subject: [PATCH 17/18] Fixed constness --- apps/openmw/mwworld/weather.cpp | 4 ++-- apps/openmw/mwworld/weather.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 1e5cbd389a..954d5c8658 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -63,7 +63,7 @@ void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name } -float WeatherManager::calculateHourFade (const std::string& moonName) +float WeatherManager::calculateHourFade (const std::string& moonName) const { float fadeOutStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Out_Start"); float fadeInStart=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_In_Start"); @@ -77,7 +77,7 @@ float WeatherManager::calculateHourFade (const std::string& moonName) return 1; } -float WeatherManager::calculateAngleFade (const std::string& moonName, float angle) +float WeatherManager::calculateAngleFade (const std::string& moonName, float angle) const { float endAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_End_Angle"); float startAngle=mFallback->getFallbackFloat("Moons_"+moonName+"_Fade_Start_Angle"); diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index bf6c8bfd8b..081bd7f87d 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -174,8 +174,8 @@ namespace MWWorld WeatherResult transition(const float factor); WeatherResult getResult(const Ogre::String& weather); - float calculateHourFade (const std::string& moonName); - float calculateAngleFade (const std::string& moonName, float angle); + float calculateHourFade (const std::string& moonName) const; + float calculateAngleFade (const std::string& moonName, float angle) const; void setWeather(const Ogre::String& weather, bool instant=false); float mSunriseTime; From 7e05b725d06d7851cc0148d5d5ecb3419aa37413 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 9 May 2013 19:28:07 +0200 Subject: [PATCH 18/18] updated credits file --- credits.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/credits.txt b/credits.txt index c7430d6841..390a2d721d 100644 --- a/credits.txt +++ b/credits.txt @@ -58,7 +58,7 @@ Sebastian Wick (swick) Sergey Shambir Sylvain Thesnieres (Garvek) Tom Mason (wheybags) - +Torben Leif Carrington (TorbenC) Packagers: Alexander Olofsson (Ace) - Windows