1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-16 08:42:23 +00:00

Merge remote-tracking branch 'zini/master' into animations

This commit is contained in:
Chris Robinson 2013-05-09 13:53:38 -07:00
commit 74ed1f73b4
33 changed files with 644 additions and 313 deletions

View File

@ -245,6 +245,9 @@ namespace MWBase
virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0; virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0;
///< Run physics simulation and modify \a world accordingly. ///< 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; virtual bool toggleCollisionMode() = 0;
///< Toggle collision mode for player. If disabled player object should ignore ///< Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity. /// collisions and gravity.

View File

@ -38,6 +38,18 @@ namespace MWGui
getWidget(mLeftPage, "LeftPage"); getWidget(mLeftPage, "LeftPage");
getWidget(mRightPage, "RightPage"); 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(); 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));
}
} }

View File

@ -27,6 +27,7 @@ namespace MWGui
void updatePages(); void updatePages();
void clearPages(); void clearPages();
void adjustButton(MWGui::ImageButton* button);
private: private:
MWGui::ImageButton* mCloseButton; MWGui::ImageButton* mCloseButton;

View File

@ -137,10 +137,47 @@ namespace
getPage (QuestsPage)->adviseLinkClicked (callback); getPage (QuestsPage)->adviseLinkClicked (callback);
} }
adjustButton(OptionsBTN);
adjustButton(PrevPageBTN);
adjustButton(NextPageBTN);
adjustButton(CloseBTN);
adjustButton(CancelBTN);
adjustButton(ShowAllBTN);
adjustButton(ShowActiveBTN);
adjustButton(JournalBTN);
MWGui::ImageButton* nextButton = getWidget<MWGui::ImageButton>(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<MyGUI::Widget>(TopicsBTN)->getSize().width + getWidget<MyGUI::Widget>(QuestsBTN)->getSize().width;
int topicsWidth = getWidget<MyGUI::Widget>(TopicsBTN)->getSize().width;
int pageWidth = getWidget<MyGUI::Widget>(RightBookPage)->getSize().width;
getWidget<MyGUI::Widget>(TopicsBTN)->setPosition((pageWidth - width)/2, getWidget<MyGUI::Widget>(TopicsBTN)->getPosition().top);
getWidget<MyGUI::Widget>(QuestsBTN)->setPosition((pageWidth - width)/2 + topicsWidth, getWidget<MyGUI::Widget>(QuestsBTN)->getPosition().top);
mQuestMode = false; mQuestMode = false;
mAllQuests = false; mAllQuests = false;
} }
void adjustButton (char const * name)
{
MWGui::ImageButton* button = getWidget<MWGui::ImageButton>(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() void open()
{ {
mModel->load (); mModel->load ();
@ -391,6 +428,7 @@ namespace
void notifyClose(MyGUI::Widget* _sender) void notifyClose(MyGUI::Widget* _sender)
{ {
MWBase::Environment::get().getSoundManager()->playSound ("book close", 1.0, 1.0);
MWBase::Environment::get().getWindowManager ()->popGuiMode (); MWBase::Environment::get().getWindowManager ()->popGuiMode ();
} }

View File

@ -10,6 +10,18 @@
#include "formatting.hpp" #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 namespace MWGui
{ {
@ -26,6 +38,9 @@ namespace MWGui
getWidget(mTakeButton, "TakeButton"); getWidget(mTakeButton, "TakeButton");
mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked); mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ScrollWindow::onTakeButtonClicked);
adjustButton(mCloseButton);
adjustButton(mTakeButton);
center(); center();
} }

View File

@ -1,30 +1,182 @@
#include "aiescort.hpp" #include "aiescort.hpp"
#include <iostream>
#include "character.hpp"
MWMechanics::AiEscort::AiEscort(const std::string &actorId,int duration, float x, float y, float z) #include "movement.hpp"
: mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration)
{ #include "../mwworld/class.hpp"
} #include "../mwworld/player.hpp"
#include "../mwworld/timestamp.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include <boost/graph/astar_search.hpp>
#include <boost/graph/adjacency_list.hpp>
#include "boost/tuple/tuple.hpp"
namespace
{
float sgn(float a)
{
if(a>0) return 1.;
else return -1.;
}
}
/*
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)
{
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;
else
{
MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp();
mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100);
}
}
MWMechanics::AiEscort::AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z) 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) : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration)
{ {
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;
else
{
MWWorld::TimeStamp startTime = MWBase::Environment::get().getWorld()->getTimeStamp();
mStartingSecond = ((startTime.getHour() - int(startTime.getHour())) * 100);
}
}
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)
{
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<ESM::Pathgrid>().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;
}
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 =
(differenceBetween[0] * differenceBetween[0]) + (differenceBetween[1] * differenceBetween[1]) + (differenceBetween[2] * differenceBetween[2]);
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);
MWWorld::Class::get(actor).getMovementSettings(actor).mPosition[1] = 1;
mMaxDist = 470;
}
else
{
// 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;
}
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;
}

View File

@ -2,13 +2,36 @@
#define GAME_MWMECHANICS_AIESCORT_H #define GAME_MWMECHANICS_AIESCORT_H
#include "aipackage.hpp" #include "aipackage.hpp"
#include "pathfinding.hpp"
#include <string> #include <string>
/* 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, youll 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 namespace MWMechanics
{ {
class AiEscort : public AiPackage class AiEscort : public AiPackage
{ {
public: public:
AiEscort(const std::string &actorId,int duration, float x, float y, float z); AiEscort(const std::string &actorId,int duration, float x, float y, float z);
///< \implement AiEscort ///< \implement AiEscort
AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z); AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z);
@ -27,8 +50,13 @@ namespace MWMechanics
float mX; float mX;
float mY; float mY;
float mZ; float mZ;
int mDuration; float mMaxDist;
unsigned int mStartingSecond;
}; unsigned int mDuration;
}
#endif PathFinder mPathFinder;
int cellX;
int cellY;
};
}
#endif

View File

@ -1,4 +1,8 @@
#include "pathfinding.hpp" #include "pathfinding.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include <boost/graph/dijkstra_shortest_paths.hpp> #include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/adjacency_list.hpp> #include <boost/graph/adjacency_list.hpp>
#include "boost/tuple/tuple.hpp" #include "boost/tuple/tuple.hpp"
@ -88,7 +92,7 @@ namespace
const PathGridGraph & mGraph; const PathGridGraph & mGraph;
PointID mGoal; PointID mGoal;
};*/ };*/
class goalVisited : public boost::default_dijkstra_visitor class goalVisited : public boost::default_dijkstra_visitor
{ {
public: public:
@ -169,15 +173,19 @@ namespace MWMechanics
void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint, void PathFinder::buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
const ESM::Pathgrid* pathGrid,float xCell,float yCell) const ESM::Pathgrid* pathGrid,float xCell,float yCell)
{ {
int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ); //first check if there is an obstacle
int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ); if(MWBase::Environment::get().getWorld()->castRay(startPoint.mX,startPoint.mY,startPoint.mZ,
endPoint.mX,endPoint.mY,endPoint.mZ) )
if(start != -1 && end != -1)
{ {
PathGridGraph graph = buildGraph(pathGrid,xCell,yCell); int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ);
mPath = findPath(start,end,graph); 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); mPath.push_back(endPoint);
mIsPathConstructed = true; mIsPathConstructed = true;
} }

View File

@ -1,5 +1,4 @@
#include "occlusionquery.hpp" #include "occlusionquery.hpp"
#include "renderconst.hpp"
#include <OgreRenderSystem.h> #include <OgreRenderSystem.h>
#include <OgreRoot.h> #include <OgreRoot.h>
@ -7,8 +6,11 @@
#include <OgreHardwareOcclusionQuery.h> #include <OgreHardwareOcclusionQuery.h>
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreSubEntity.h> #include <OgreSubEntity.h>
#include <OgreMeshManager.h>
#include <OgreMaterialManager.h> #include <OgreMaterialManager.h>
#include "renderconst.hpp"
using namespace MWRender; using namespace MWRender;
using namespace Ogre; using namespace Ogre;
@ -16,7 +18,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0), mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0),
mDoQuery(0), mSunVisibility(0), mDoQuery(0), mSunVisibility(0),
mWasVisible(false), mWasVisible(false),
mBBNode(0), mActive(false) mActive(false)
{ {
mRendering = renderer; mRendering = renderer;
mSunNode = sunNode; mSunNode = sunNode;
@ -40,39 +42,24 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
return; 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(); mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); 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("occlusionbillboard");
mBBQueryTotal->setCastShadows(false); mBBQueryTotal->setCastShadows(false);
mBBQueryTotal->setDefaultDimensions(150, 150);
mBBQueryTotal->createBillboard(Vector3::ZERO);
mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery);
mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryTotal->setMaterialName("QueryTotalPixels");
mBBNodeReal->attachObject(mBBQueryTotal); mBBNodeReal->attachObject(mBBQueryTotal);
mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); mBBQueryVisible = mRendering->getScene()->createEntity("occlusionbillboard");
mBBQueryVisible->setCastShadows(false); mBBQueryVisible->setCastShadows(false);
mBBQueryVisible->setDefaultDimensions(150, 150);
mBBQueryVisible->createBillboard(Vector3::ZERO);
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery);
mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1);
mBBQueryVisible->setMaterialName("QueryVisiblePixels");
mBBNodeReal->attachObject(mBBQueryVisible); mBBNodeReal->attachObject(mBBQueryVisible);
mRendering->getScene()->addRenderObjectListener(this); mRendering->getScene()->addRenderObjectListener(this);
@ -116,12 +103,12 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
// Open a new occlusion query // Open a new occlusion query
if (mDoQuery == true) if (mDoQuery == true)
{ {
if (rend == mBBQueryTotal) if (rend == mBBQueryTotal->getSubEntity(0))
{ {
mActiveQuery = mSunTotalAreaQuery; mActiveQuery = mSunTotalAreaQuery;
mWasVisible = true; mWasVisible = true;
} }
else if (rend == mBBQueryVisible) else if (rend == mBBQueryVisible->getSubEntity(0))
{ {
mActiveQuery = mSunVisibleAreaQuery; mActiveQuery = mSunVisibleAreaQuery;
} }
@ -170,12 +157,11 @@ void OcclusionQuery::update(float duration)
if (dist==0) dist = 10000000; if (dist==0) dist = 10000000;
dist -= 1000; // bias dist -= 1000; // bias
dist /= 1000.f; dist /= 1000.f;
if (mBBNode) if (mSunNode)
{ {
mBBNode->setPosition(mSunNode->getPosition() * dist); mBBNodeReal->setPosition(mSunNode->getPosition() * dist);
mBBNode->setScale(dist, dist, dist); mBBNodeReal->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-mBBNodeReal->getPosition().normalisedCopy()));
mBBNodeReal->setPosition(mBBNode->_getDerivedPosition()); mBBNodeReal->setScale(150.f*dist, 150.f*dist, 150.f*dist);
mBBNodeReal->setScale(mBBNode->getScale());
} }
// Stop occlusion queries until we get their information // Stop occlusion queries until we get their information
@ -209,6 +195,4 @@ void OcclusionQuery::update(float duration)
void OcclusionQuery::setSunNode(Ogre::SceneNode* node) void OcclusionQuery::setSunNode(Ogre::SceneNode* node)
{ {
mSunNode = node; mSunNode = node;
if (!mBBNode)
mBBNode = node->getParentSceneNode()->createChildSceneNode();
} }

View File

@ -49,11 +49,10 @@ namespace MWRender
Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery; Ogre::HardwareOcclusionQuery* mSunVisibleAreaQuery;
Ogre::HardwareOcclusionQuery* mActiveQuery; Ogre::HardwareOcclusionQuery* mActiveQuery;
Ogre::BillboardSet* mBBQueryVisible; Ogre::Entity* mBBQueryVisible;
Ogre::BillboardSet* mBBQueryTotal; Ogre::Entity* mBBQueryTotal;
Ogre::SceneNode* mSunNode; Ogre::SceneNode* mSunNode;
Ogre::SceneNode* mBBNode;
Ogre::SceneNode* mBBNodeReal; Ogre::SceneNode* mBBNodeReal;
float mSunVisibility; float mSunVisibility;

View File

@ -12,6 +12,8 @@
#include <OgreEntity.h> #include <OgreEntity.h>
#include <OgreSubEntity.h> #include <OgreSubEntity.h>
#include <OgreMeshManager.h>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <components/nifogre/ogrenifloader.hpp> #include <components/nifogre/ogrenifloader.hpp>
@ -41,25 +43,25 @@ BillboardObject::BillboardObject( const String& textureName,
static unsigned int bodyCount=0; static unsigned int bodyCount=0;
/// \todo These billboards are not 100% correct, might want to revisit them later mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material);
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1); mMaterial->setProperty("texture", sh::makeProperty(new sh::StringValue(textureName)));
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON); static Ogre::Mesh* plane = MeshManager::getSingleton().createPlane("billboard",
mBBSet->setCommonDirection( -position.normalisedCopy() ); 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();
mBBSet->setVisibilityFlags(RV_Sky); plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE);
mEntity = sceneMgr->createEntity("billboard");
mEntity->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
mEntity->setVisibilityFlags(RV_Sky);
mEntity->setCastShadows(false);
mNode = rootNode->createChildSceneNode(); mNode = rootNode->createChildSceneNode();
mNode->setPosition(finalPosition); mNode->setPosition(finalPosition);
mNode->attachObject(mBBSet); mNode->attachObject(mEntity);
mBBSet->createBillboard(0,0,0); mNode->setScale(Ogre::Vector3(550.f*initialSize));
mBBSet->setCastShadows(false); mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-position.normalisedCopy()));
mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material);
mMaterial->setProperty("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName)));
sh::Factory::getInstance().getMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount))->setListener(this); sh::Factory::getInstance().getMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount))->setListener(this);
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
bodyCount++; bodyCount++;
} }
@ -79,12 +81,12 @@ void BillboardObject::createdConfiguration (sh::MaterialInstance* m, const std::
void BillboardObject::setVisible(const bool visible) void BillboardObject::setVisible(const bool visible)
{ {
mBBSet->setVisible(visible); mEntity->setVisible(visible);
} }
void BillboardObject::setSize(const float size) 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) void BillboardObject::setVisibility(const float visibility)
@ -103,21 +105,18 @@ void BillboardObject::setPosition(const Vector3& pPosition)
{ {
Vector3 normalised = pPosition.normalisedCopy(); Vector3 normalised = pPosition.normalisedCopy();
Vector3 finalPosition = normalised * 1000.f; Vector3 finalPosition = normalised * 1000.f;
mNode->setOrientation(Ogre::Vector3::UNIT_Z.getRotationTo(-normalised));
mBBSet->setCommonDirection( -normalised );
mNode->setPosition(finalPosition); mNode->setPosition(finalPosition);
} }
Vector3 BillboardObject::getPosition() const Vector3 BillboardObject::getPosition() const
{ {
Vector3 p = mNode->_getDerivedPosition() - mNode->getParentSceneNode()->_getDerivedPosition(); return mNode->getPosition();
return p;
} }
void BillboardObject::setVisibilityFlags(int flags) void BillboardObject::setVisibilityFlags(int flags)
{ {
mBBSet->setVisibilityFlags(flags); mEntity->setVisibilityFlags(flags);
} }
void BillboardObject::setColour(const ColourValue& pColour) void BillboardObject::setColour(const ColourValue& pColour)
@ -134,7 +133,7 @@ void BillboardObject::setColour(const ColourValue& pColour)
void BillboardObject::setRenderQueue(unsigned int id) void BillboardObject::setRenderQueue(unsigned int id)
{ {
mBBSet->setRenderQueueGroup(id); mEntity->setRenderQueueGroup(id);
} }
SceneNode* BillboardObject::getNode() SceneNode* BillboardObject::getNode()
@ -218,7 +217,6 @@ SkyManager::SkyManager(Ogre::SceneNode *root, Ogre::Camera *pCamera)
, mSceneMgr(NULL) , mSceneMgr(NULL)
, mAtmosphereDay(NULL) , mAtmosphereDay(NULL)
, mAtmosphereNight(NULL) , mAtmosphereNight(NULL)
, mCloudFragmentShader()
, mClouds() , mClouds()
, mNextClouds() , mNextClouds()
, mCloudBlendFactor(0.0f) , mCloudBlendFactor(0.0f)
@ -283,8 +281,7 @@ void SkyManager::create()
mSunGlare->setRenderQueue(RQG_SkiesLate); mSunGlare->setRenderQueue(RQG_SkiesLate);
mSunGlare->setVisibilityFlags(RV_NoReflection); mSunGlare->setVisibilityFlags(RV_NoReflection);
Ogre::AxisAlignedBox aabInf; Ogre::AxisAlignedBox aabInf = Ogre::AxisAlignedBox::BOX_INFINITE;
aabInf.setInfinite ();
// Stars // Stars
mAtmosphereNight = mRootNode->createChildSceneNode(); mAtmosphereNight = mRootNode->createChildSceneNode();
@ -372,8 +369,6 @@ void SkyManager::update(float duration)
{ {
if (!mEnabled) return; if (!mEnabled) return;
const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback(); const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();
mCamera->getParentSceneNode ()->needUpdate ();
mRootNode->setPosition(mCamera->getDerivedPosition());
// UV Scroll the clouds // UV Scroll the clouds
mCloudAnimationTimer += duration * mCloudSpeed; mCloudAnimationTimer += duration * mCloudSpeed;
@ -407,8 +402,7 @@ void SkyManager::update(float duration)
Vector3 cam = mCamera->getRealDirection(); Vector3 cam = mCamera->getRealDirection();
const Degree angle = sun.angleBetween( cam ); const Degree angle = sun.angleBetween( cam );
float val = 1- (angle.valueDegrees() / 180.f); float val = 1- (angle.valueDegrees() / 180.f);
val = (val*val*val*val)*2; val = (val*val*val*val)*6;
mSunGlare->setSize(val * mGlareFade); mSunGlare->setSize(val * mGlareFade);
} }
@ -537,7 +531,7 @@ void SkyManager::setGlare(const float glare)
Vector3 SkyManager::getRealSunPos() Vector3 SkyManager::getRealSunPos()
{ {
if (!mCreated) return Vector3(0,0,0); if (!mCreated) return Vector3(0,0,0);
return mSun->getNode()->_getDerivedPosition(); return mSun->getNode()->getPosition() + mCamera->getRealPosition();
} }
void SkyManager::sunEnable() void SkyManager::sunEnable()
@ -644,22 +638,6 @@ Ogre::SceneNode* SkyManager::getSunNode()
return mSun->getNode(); 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) void SkyManager::setGlareEnabled (bool enabled)
{ {
if (!mCreated) if (!mCreated)

View File

@ -1,5 +1,5 @@
#ifndef _GAME_RENDER_SKY_H #ifndef GAME_RENDER_SKY_H
#define _GAME_RENDER_SKY_H #define GAME_RENDER_SKY_H
#include <vector> #include <vector>
@ -61,7 +61,7 @@ namespace MWRender
Ogre::ColourValue mColour; Ogre::ColourValue mColour;
Ogre::SceneNode* mNode; Ogre::SceneNode* mNode;
sh::MaterialInstance* mMaterial; sh::MaterialInstance* mMaterial;
Ogre::BillboardSet* mBBSet; Ogre::Entity* mEntity;
}; };
@ -117,9 +117,6 @@ namespace MWRender
void update(float duration); void update(float duration);
void create();
///< no need to call this, automatically done on first enable()
void enable(); void enable();
void disable(); void disable();
@ -173,11 +170,10 @@ namespace MWRender
void setGlareEnabled(bool enabled); void setGlareEnabled(bool enabled);
Ogre::Vector3 getRealSunPos(); Ogre::Vector3 getRealSunPos();
void setSkyPosition(const Ogre::Vector3& position);
void resetSkyPosition();
void scaleSky(float scale);
private: private:
void create();
///< no need to call this, automatically done on first enable()
bool mCreated; bool mCreated;
bool mMoonRed; bool mMoonRed;
@ -200,8 +196,6 @@ namespace MWRender
Ogre::SceneNode* mAtmosphereDay; Ogre::SceneNode* mAtmosphereDay;
Ogre::SceneNode* mAtmosphereNight; Ogre::SceneNode* mAtmosphereNight;
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
// remember some settings so we don't have to apply them again if they didnt change // remember some settings so we don't have to apply them again if they didnt change
Ogre::String mClouds; Ogre::String mClouds;
Ogre::String mNextClouds; Ogre::String mNextClouds;
@ -227,4 +221,4 @@ namespace MWRender
}; };
} }
#endif // _GAME_RENDER_SKY_H #endif // GAME_RENDER_SKY_H

View File

@ -136,9 +136,6 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
mCamera->setFOVy(mParentCamera->getFOVy()); mCamera->setFOVy(mParentCamera->getFOVy());
mRenderActive = true; mRenderActive = true;
Vector3 pos = mParentCamera->getRealPosition();
pos.y = (mWaterPlane).d*2 - pos.y;
mSky->setSkyPosition(pos);
mCamera->enableReflection(mWaterPlane); mCamera->enableReflection(mWaterPlane);
// for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane. // 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) void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
{ {
mSky->resetSkyPosition();
mCamera->disableReflection(); mCamera->disableReflection();
mCamera->disableCustomNearClipPlane(); mCamera->disableCustomNearClipPlane();
mRenderActive = false; mRenderActive = false;

View File

@ -333,14 +333,13 @@ namespace MWWorld
return result; return result;
} }
bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to) bool PhysicsSystem::castRay(const Vector3& from, const Vector3& to, bool raycastingObjectOnly,bool ignoreHeightMap)
{ {
btVector3 _from, _to; btVector3 _from, _to;
_from = btVector3(from.x, from.y, from.z); _from = btVector3(from.x, from.y, from.z);
_to = btVector3(to.x, to.y, to.z); _to = btVector3(to.x, to.y, to.z);
std::pair<std::string, float> result = mEngine->rayTest(_from, _to); std::pair<std::string, float> result = mEngine->rayTest(_from, _to, raycastingObjectOnly,ignoreHeightMap);
return !(result.first == ""); return !(result.first == "");
} }

View File

@ -62,8 +62,8 @@ namespace MWWorld
btVector3 getRayPoint(float extent, float mouseX, float mouseY); btVector3 getRayPoint(float extent, float mouseX, float mouseY);
// cast ray, return true if it hit something // 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 castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
std::pair<bool, Ogre::Vector3> std::pair<bool, Ogre::Vector3>
castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len); castRay(const Ogre::Vector3 &orig, const Ogre::Vector3 &dir, float len);

View File

@ -24,6 +24,7 @@ namespace
{ {
return x * (1-factor) + y * factor; return x * (1-factor) + y * factor;
} }
Ogre::ColourValue lerp (const Ogre::ColourValue& x, const Ogre::ColourValue& y, float factor) Ogre::ColourValue lerp (const Ogre::ColourValue& x, const Ogre::ColourValue& y, float factor)
{ {
return x * (1-factor) + y * factor; return x * (1-factor) + y * factor;
@ -61,13 +62,39 @@ void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name
mWeatherSettings[name] = weather; mWeatherSettings[name] = weather;
} }
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");
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) const
{
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) : WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0),
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0),
mRemainingTransitionTime(0), mMonth(0), mDay(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 //Globals
mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
mThunderSoundID1 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1"); mThunderSoundID1 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_1");
@ -78,10 +105,22 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa
mSunriseDuration = mFallback->getFallbackFloat("Weather_Sunrise_Duration"); mSunriseDuration = mFallback->getFallbackFloat("Weather_Sunrise_Duration");
mSunsetDuration = mFallback->getFallbackFloat("Weather_Sunset_Duration"); mSunsetDuration = mFallback->getFallbackFloat("Weather_Sunset_Duration");
mHoursBetweenWeatherChanges = mFallback->getFallbackFloat("Weather_Hours_Between_Weather_Changes"); mHoursBetweenWeatherChanges = mFallback->getFallbackFloat("Weather_Hours_Between_Weather_Changes");
mWeatherUpdateTime = mHoursBetweenWeatherChanges*3600; mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
mThunderFrequency = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency"); mThunderFrequency = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Frequency");
mThunderThreshold = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold"); mThunderThreshold = mFallback->getFallbackFloat("Weather_Thunderstorm_Thunder_Threshold");
mThunderSoundDelay = 0.25; 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
Weather clear; Weather clear;
clear.mCloudTexture = "tx_sky_clear.dds"; clear.mCloudTexture = "tx_sky_clear.dds";
@ -147,12 +186,12 @@ void WeatherManager::setWeather(const String& weather, bool instant)
if (mNextWeather != "") if (mNextWeather != "")
{ {
// transition more than 50% finished? // 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; mCurrentWeather = mNextWeather;
} }
mNextWeather = weather; mNextWeather = weather;
mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600; mRemainingTransitionTime = mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600;
} }
mFirstUpdate = false; mFirstUpdate = false;
} }
@ -170,13 +209,13 @@ WeatherResult WeatherManager::getResult(const String& weather)
result.mGlareView = current.mGlareView; result.mGlareView = current.mGlareView;
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
result.mSunColor = current.mSunDiscSunsetColor; 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; result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
// night // night
if (mHour <= 5.5f || mHour >= 21) if (mHour <= mNightEnd || mHour >= mNightStart + 1)
{ {
result.mFogColor = current.mFogNightColor; result.mFogColor = current.mFogNightColor;
result.mAmbientColor = current.mAmbientNightColor; result.mAmbientColor = current.mAmbientNightColor;
@ -186,12 +225,12 @@ WeatherResult WeatherManager::getResult(const String& weather)
} }
// sunrise // sunrise
else if (mHour >= 5.5f && mHour <= 9) else if (mHour >= mNightEnd && mHour <= mDayStart + 1)
{ {
if (mHour <= 6) if (mHour <= mSunriseTime)
{ {
// fade in // fade in
float advance = 6-mHour; float advance = mSunriseTime - mHour;
float factor = advance / 0.5f; float factor = advance / 0.5f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor); result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor);
@ -202,7 +241,7 @@ WeatherResult WeatherManager::getResult(const String& weather)
else //if (mHour >= 6) else //if (mHour >= 6)
{ {
// fade out // fade out
float advance = mHour-6; float advance = mHour - mSunriseTime;
float factor = advance / 3.f; float factor = advance / 3.f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor); result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor); result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor);
@ -212,7 +251,7 @@ WeatherResult WeatherManager::getResult(const String& weather)
} }
// day // day
else if (mHour >= 9 && mHour <= 17) else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1)
{ {
result.mFogColor = current.mFogDayColor; result.mFogColor = current.mFogDayColor;
result.mAmbientColor = current.mAmbientDayColor; result.mAmbientColor = current.mAmbientDayColor;
@ -221,12 +260,12 @@ WeatherResult WeatherManager::getResult(const String& weather)
} }
// sunset // sunset
else if (mHour >= 17 && mHour <= 21) else if (mHour >= mDayEnd - 1 && mHour <= mNightStart + 1)
{ {
if (mHour <= 19) if (mHour <= mDayEnd + 1)
{ {
// fade in // fade in
float advance = 19-mHour; float advance = (mDayEnd + 1) - mHour;
float factor = (advance / 2); float factor = (advance / 2);
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor); result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor);
@ -236,7 +275,7 @@ WeatherResult WeatherManager::getResult(const String& weather)
else //if (mHour >= 19) else //if (mHour >= 19)
{ {
// fade out // fade out
float advance = mHour-19; float advance = mHour - (mDayEnd + 1);
float factor = advance / 2.f; float factor = advance / 2.f;
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor); result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor); result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor);
@ -294,7 +333,7 @@ void WeatherManager::update(float duration)
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{ {
mCurrentRegion = regionstr; mCurrentRegion = regionstr;
mWeatherUpdateTime = mHoursBetweenWeatherChanges*3600; mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
std::string weather = "clear"; std::string weather = "clear";
@ -363,7 +402,7 @@ void WeatherManager::update(float duration)
} }
if (mNextWeather != "") if (mNextWeather != "")
result = transition(1-(mRemainingTransitionTime/(mWeatherSettings[mCurrentWeather].mTransitionDelta*24.f*3600))); result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600)));
else else
result = getResult(mCurrentWeather); result = getResult(mCurrentWeather);
@ -372,7 +411,7 @@ void WeatherManager::update(float duration)
mRendering->configureFog(result.mFogDepth, result.mFogColor); mRendering->configureFog(result.mFogDepth, result.mFogColor);
// disable sun during night // disable sun during night
if (mHour >= 20 || mHour <= 6.f) if (mHour >= mNightStart || mHour <= mSunriseTime)
mRendering->getSkyManager()->sunDisable(); mRendering->getSkyManager()->sunDisable();
else else
mRendering->getSkyManager()->sunEnable(); mRendering->getSkyManager()->sunEnable();
@ -380,28 +419,31 @@ void WeatherManager::update(float duration)
// sun angle // sun angle
float height; float height;
// rise at 6, set at 20 //Day duration
if (mHour >= 6 && mHour <= 20) float dayDuration = (mNightStart - 1) - mSunriseTime;
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);
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( Vector3 final(
-(1-height)*facing, -(1 - height) * facing,
-(1-height)*facing, -(1 - height) * facing,
height); height);
mRendering->setSunDirection(final); mRendering->setSunDirection(final);
// moon calculations // moon calculations
float night; float night;
if (mHour >= 14) if (mHour >= 14)
night = mHour-14; night = mHour - 14;
else if (mHour <= 10) else if (mHour <= 10)
night = mHour+10; night = mHour + 10;
else else
night = 0; night = 0;
@ -409,16 +451,16 @@ void WeatherManager::update(float duration)
if (night != 0) if (night != 0)
{ {
float moonHeight = 1-std::abs((night-0.5)*2); float moonHeight = 1 - std::abs((night - 0.5) * 2);
int facing = (mHour > 0.f && mHour<12.f) ? 1 : -1; int facing = (mHour > 0.f && mHour< 12.f) ? 1 : -1;
Vector3 masser( Vector3 masser(
(1-moonHeight)*facing, (1 - moonHeight) * facing,
(1-moonHeight)*facing, (1 - moonHeight) * facing,
moonHeight); moonHeight);
Vector3 secunda( Vector3 secunda(
(1-moonHeight)*facing*0.8, (1 - moonHeight) * facing * 0.8,
(1-moonHeight)*facing*1.25, (1 - moonHeight) * facing * 1.25,
moonHeight); moonHeight);
mRendering->getSkyManager()->setMasserDirection(masser); mRendering->getSkyManager()->setMasserDirection(masser);
@ -426,56 +468,17 @@ void WeatherManager::update(float duration)
mRendering->getSkyManager()->masserEnable(); mRendering->getSkyManager()->masserEnable();
mRendering->getSkyManager()->secundaEnable(); mRendering->getSkyManager()->secundaEnable();
float secunda_hour_fade; float angle = moonHeight * 90.f;
float secunda_fadeout_start=mFallback->getFallbackFloat("Moons_Secunda_Fade_Out_Start"); float masserHourFade = calculateHourFade("Masser");
float secunda_fadein_start=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Start"); float secundaHourFade = calculateHourFade("Secunda");
float secunda_fadein_finish=mFallback->getFallbackFloat("Moons_Secunda_Fade_In_Finish"); float masserAngleFade = calculateAngleFade("Masser", angle);
float secundaAngleFade = calculateAngleFade("Secunda", angle);
if (mHour >= secunda_fadeout_start && mHour <= secunda_fadein_start) masserAngleFade *= masserHourFade;
secunda_hour_fade = 1-(mHour-secunda_fadeout_start)/3.f; secundaAngleFade *= secundaHourFade;
else if (mHour >= secunda_fadein_start && mHour <= secunda_fadein_finish)
secunda_hour_fade = mHour-secunda_fadein_start;
else
secunda_hour_fade = 1;
float masser_hour_fade; mRendering->getSkyManager()->setMasserFade(masserAngleFade);
float masser_fadeout_start=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Start"); mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
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;
else
masser_hour_fade = 1;
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;
else
secunda_angle_fade = 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;
else
masser_angle_fade = 1.f;
masser_angle_fade *= masser_hour_fade;
secunda_angle_fade *= secunda_hour_fade;
mRendering->getSkyManager()->setMasserFade(masser_angle_fade);
mRendering->getSkyManager()->setSecundaFade(secunda_angle_fade);
} }
else else
{ {

View File

@ -174,6 +174,9 @@ namespace MWWorld
WeatherResult transition(const float factor); WeatherResult transition(const float factor);
WeatherResult getResult(const Ogre::String& weather); WeatherResult getResult(const Ogre::String& weather);
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); void setWeather(const Ogre::String& weather, bool instant=false);
float mSunriseTime; float mSunriseTime;
float mSunsetTime; float mSunsetTime;
@ -184,6 +187,10 @@ namespace MWWorld
float mThunderFrequency; float mThunderFrequency;
float mThunderThreshold; float mThunderThreshold;
float mThunderSoundDelay; float mThunderSoundDelay;
float mNightStart;
float mNightEnd;
float mDayStart;
float mDayEnd;
std::string mThunderSoundID0; std::string mThunderSoundID0;
std::string mThunderSoundID1; std::string mThunderSoundID1;
std::string mThunderSoundID2; std::string mThunderSoundID2;

View File

@ -1042,6 +1042,13 @@ namespace MWWorld
mPhysEngine->stepSimulation (duration); 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,true);
}
void World::processDoors(float duration) void World::processDoors(float duration)
{ {
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin(); std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin();

View File

@ -279,6 +279,9 @@ namespace MWWorld
virtual void doPhysics(const PtrMovementList &actors, float duration); virtual void doPhysics(const PtrMovementList &actors, float duration);
///< Run physics simulation and modify \a world accordingly. ///< 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(); virtual bool toggleCollisionMode();
///< Toggle collision mode for player. If disabled player object should ignore ///< Toggle collision mode for player. If disabled player object should ignore
/// collisions and gravity. /// collisions and gravity.

View File

@ -58,7 +58,7 @@ Sebastian Wick (swick)
Sergey Shambir Sergey Shambir
Sylvain Thesnieres (Garvek) Sylvain Thesnieres (Garvek)
Tom Mason (wheybags) Tom Mason (wheybags)
Torben Leif Carrington (TorbenC)
Packagers: Packagers:
Alexander Olofsson (Ace) - Windows Alexander Olofsson (Ace) - Windows

View File

@ -721,7 +721,6 @@ namespace sh
// delete any outdated shaders based on this shader set // delete any outdated shaders based on this shader set
if (removeCache (it->first)) if (removeCache (it->first))
removeBinaryCache = true; removeBinaryCache = true;
mShadersLastModified[sourceRelative] = lastModified;
} }
} }
else else
@ -730,11 +729,13 @@ namespace sh
// in both cases we can safely delete // in both cases we can safely delete
if (removeCache (it->first)) if (removeCache (it->first))
removeBinaryCache = true; removeBinaryCache = true;
mShadersLastModified[sourceRelative] = lastModified;
} }
mShaderSets.insert(std::make_pair(it->first, newSet)); mShaderSets.insert(std::make_pair(it->first, newSet));
} }
// new is now current
mShadersLastModified = mShadersLastModifiedNew;
return removeBinaryCache; return removeBinaryCache;
} }

View File

@ -3,13 +3,24 @@
#ifdef SH_VERTEX_SHADER #ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM 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) shOutput(float, alphaFade)
SH_START_PROGRAM 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; alphaFade = shInputPosition.z < 150.0 ? 0.0 : 1.0;
} }

View File

@ -3,15 +3,26 @@
#ifdef SH_VERTEX_SHADER #ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM 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) shVertexInput(float2, uv0)
shOutput(float2, UV) shOutput(float2, UV)
shOutput(float, alphaFade) shOutput(float, alphaFade)
SH_START_PROGRAM SH_START_PROGRAM
{ {
shOutputPosition = shMatrixMult(wvp, shInputPosition); float4x4 viewFixed = view;
UV = uv0; #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; alphaFade = (shInputPosition.z <= 200.f) ? ((shInputPosition.z <= 100.f) ? 0.0 : 0.25) : 1.0;
} }

View File

@ -3,14 +3,26 @@
#ifdef SH_VERTEX_SHADER #ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM 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) shVertexInput(float2, uv0)
shOutput(float2, UV) shOutput(float2, UV)
SH_START_PROGRAM SH_START_PROGRAM
{ {
shOutputPosition = shMatrixMult(wvp, shInputPosition); float4x4 viewFixed = view;
UV = uv0; #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 #else

View File

@ -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 material openmw_moon
{ {
allow_fixed_function false allow_fixed_function false
@ -5,7 +36,8 @@ material openmw_moon
{ {
vertex_program moon_vertex vertex_program moon_vertex
fragment_program moon_fragment fragment_program moon_fragment
cull_hardware none
polygon_mode_overrideable off polygon_mode_overrideable off
depth_write off depth_write off
depth_check off depth_check off
@ -92,6 +124,7 @@ material openmw_sun
{ {
vertex_program sun_vertex vertex_program sun_vertex
fragment_program sun_fragment fragment_program sun_fragment
cull_hardware none
polygon_mode_overrideable off polygon_mode_overrideable off

View File

@ -3,15 +3,26 @@
#ifdef SH_VERTEX_SHADER #ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM 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) shVertexInput(float2, uv0)
shOutput(float2, UV) shOutput(float2, UV)
shOutput(float, fade) shOutput(float, fade)
SH_START_PROGRAM 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; UV = uv0;
fade = (shInputPosition.z > 50) ? 1 : 0; fade = (shInputPosition.z > 50) ? 1 : 0;

View File

@ -3,14 +3,26 @@
#ifdef SH_VERTEX_SHADER #ifdef SH_VERTEX_SHADER
SH_BEGIN_PROGRAM 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) shVertexInput(float2, uv0)
shOutput(float2, UV) shOutput(float2, UV)
SH_START_PROGRAM SH_START_PROGRAM
{ {
shOutputPosition = shMatrixMult(wvp, shInputPosition); float4x4 viewFixed = view;
UV = uv0; #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 #else

View File

@ -8,25 +8,27 @@
<Property key="ImageTexture" value="textures\tx_menubook.dds"/> <Property key="ImageTexture" value="textures\tx_menubook.dds"/>
<Property key="ImageCoord" value="50 0 412 256"/> <Property key="ImageCoord" value="50 0 412 256"/>
<Widget type="ImageButton" skin="ImageBox" position="300 350 48 32" name="NextPageBTN"> <Widget type="Widget" position="0 0 282 390">
<Property key="ImageCoord" value="0 0 48 32"/> <Widget type="ImageButton" skin="ImageBox" position="205 350 48 32" name="PrevPageBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_next_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_prev_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_next_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_prev_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_next_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_prev_pressed.dds"/>
</Widget>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="220 350 48 32" name="PrevPageBTN"> <Widget type="Widget" position="282 0 282 390">
<Property key="ImageCoord" value="0 0 48 32"/> <Widget type="ImageButton" skin="ImageBox" position="18 350 48 32" name="NextPageBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_prev_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_next_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_prev_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_next_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_prev_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_next_pressed.dds"/>
</Widget>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="40 350 64 32" name="TakeButton"> <Widget type="ImageButton" skin="ImageBox" position="40 350 64 32" name="TakeButton">
<Property key="ImageHighlighted" value="textures\tx_menubook_take_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_take_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_take_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_take_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_take_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_take_pressed.dds"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="475 350 48 32" name="CloseButton"> <Widget type="ImageButton" skin="ImageBox" position="460 350 48 32" name="CloseButton">
<Property key="ImageCoord" value="0 0 48 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/>

View File

@ -8,6 +8,21 @@
<Property key="ImageTexture" value="textures\tx_menubook.dds"/> <Property key="ImageTexture" value="textures\tx_menubook.dds"/>
<Property key="ImageCoord" value="50 0 412 256"/> <Property key="ImageCoord" value="50 0 412 256"/>
<Widget type="Widget" position="0 0 282 390">
<Widget type="ImageButton" skin="ImageBox" position="205 350 48 32" name="PrevPageBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_prev_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_prev_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_prev_pressed.dds"/>
</Widget>
</Widget>
<Widget type="Widget" position="282 0 282 390">
<Widget type="ImageButton" skin="ImageBox" position="18 350 48 32" name="NextPageBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_next_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_next_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_next_pressed.dds"/>
</Widget>
</Widget>
<!-- buttons --> <!-- buttons -->
<Widget type="ImageButton" skin="ImageBox" position="40 350 64 32" name="OptionsBTN"> <Widget type="ImageButton" skin="ImageBox" position="40 350 64 32" name="OptionsBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_options_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_options_over.dds"/>
@ -17,29 +32,16 @@
<Widget type="TextBox" skin="NormalText" position="150 350 32 16" name="PageOneNum"> <Widget type="TextBox" skin="NormalText" position="150 350 32 16" name="PageOneNum">
<Property key="TextColour" value="0 0 0"/> <Property key="TextColour" value="0 0 0"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="220 350 48 32" name="PrevPageBTN">
<Property key="ImageCoord" value="0 0 48 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_prev_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_prev_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_prev_pressed.dds"/>
</Widget>
<Widget type="ImageButton" skin="ImageBox" position="300 350 48 32" name="NextPageBTN">
<Property key="ImageCoord" value="0 0 48 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_next_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_next_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_next_pressed.dds"/>
</Widget>
<Widget type="TextBox" skin="NormalText" position="410 350 32 16" name="PageTwoNum"> <Widget type="TextBox" skin="NormalText" position="410 350 32 16" name="PageTwoNum">
<Property key="TextColour" value="0 0 0"/> <Property key="TextColour" value="0 0 0"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="475 350 48 32" name="CloseBTN"> <Widget type="ImageButton" skin="ImageBox" position="460 350 48 32" name="CloseBTN">
<Property key="ImageCoord" value="0 0 48 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="460 350 64 32" name="JournalBTN"> <Widget type="ImageButton" skin="ImageBox" position="460 350 64 32" name="JournalBTN">
<Property key="ImageCoord" value="0 0 64 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_journal_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_journal_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_journal_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_journal_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_journal_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_journal_pressed.dds"/>
@ -62,6 +64,18 @@
<Widget type="BookPage" skin="MW_BookPage" position="20 15 92 250" name="LeftTopicIndex"/> <Widget type="BookPage" skin="MW_BookPage" position="20 15 92 250" name="LeftTopicIndex"/>
<Widget type="BookPage" skin="MW_BookPage" position="112 15 92 250" name="RightTopicIndex"/> <Widget type="BookPage" skin="MW_BookPage" position="112 15 92 250" name="RightTopicIndex"/>
<Widget type="ImageButton" skin="ImageBox" position="62 15 100 20" Align="Top|Left" name="ShowActiveBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_quests_active_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_quests_active_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_quests_active_pressed.dds"/>
</Widget>
<Widget type="ImageButton" skin="ImageBox" position="76 15 72 20" Align="Top|Left" name="ShowAllBTN">
<Property key="ImageHighlighted" value="textures\tx_menubook_quests_all_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_quests_all_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_quests_all_pressed.dds"/>
</Widget>
<Widget type="ScrollView" skin="MW_ScrollView" position="20 15 184 245" name="TopicsList" align="Right VStretch"> <Widget type="ScrollView" skin="MW_ScrollView" position="20 15 184 245" name="TopicsList" align="Right VStretch">
<Property key="CanvasAlign" value="Left Top"/> <Property key="CanvasAlign" value="Left Top"/>
<Widget type="BookPage" skin="MW_BookPage" position="0 0 30000 30000" name="TopicsPage"/> <Widget type="BookPage" skin="MW_BookPage" position="0 0 30000 30000" name="TopicsPage"/>
@ -72,36 +86,19 @@
<Widget type="BookPage" skin="MW_BookPage" position="0 0 30000 30000" name="QuestsPage"/> <Widget type="BookPage" skin="MW_BookPage" position="0 0 30000 30000" name="QuestsPage"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="62 15 100 20" Align="Top|Left" name="ShowActiveBTN"> <Widget type="ImageButton" skin="ImageBox" position="20 265 56 32" Align="Top|Left" name="TopicsBTN">
<Property key="ImageCoord" value="0 0 100 20"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_quests_active_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_quests_active_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_quests_active_pressed.dds"/>
</Widget>
<Widget type="ImageButton" skin="ImageBox" position="76 15 72 20" Align="Top|Left" name="ShowAllBTN">
<Property key="ImageCoord" value="0 0 72 20"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_quests_all_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_quests_all_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_quests_all_pressed.dds"/>
</Widget>
<Widget type="ImageButton" skin="ImageBox" position="40 265 56 32" Align="Top|Left" name="TopicsBTN">
<Property key="ImageCoord" value="0 0 56 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_topics_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_topics_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_topics_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_topics_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_topics_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_topics_pressed.dds"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="130 265 56 32" Align="Top|Left" name="QuestsBTN"> <Widget type="ImageButton" skin="ImageBox" position="130 265 56 32" Align="Top|Left" name="QuestsBTN">
<Property key="ImageCoord" value="0 0 56 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_quests_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_quests_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_quests_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_quests_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_quests_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_quests_pressed.dds"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="85 290 56 32" Align="Top|Left" name="CancelBTN"> <Widget type="ImageButton" skin="ImageBox" position="85 290 56 32" Align="Top|Left" name="CancelBTN">
<Property key="ImageCoord" value="0 0 56 32"/>
<Property key="ImageHighlighted" value="textures\tx_menubook_cancel_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_cancel_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_cancel_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_cancel_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_cancel_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_cancel_pressed.dds"/>

View File

@ -13,7 +13,7 @@
<Property key="ImagePushed" value="textures\tx_menubook_take_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_take_pressed.dds"/>
</Widget> </Widget>
<Widget type="ImageButton" skin="ImageBox" position="418 24 128 32" name="CloseButton"> <Widget type="ImageButton" skin="ImageBox" position="415 24 128 32" name="CloseButton">
<Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/> <Property key="ImageHighlighted" value="textures\tx_menubook_close_over.dds"/>
<Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/> <Property key="ImageNormal" value="textures\tx_menubook_close_idle.dds"/>
<Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/> <Property key="ImagePushed" value="textures\tx_menubook_close_pressed.dds"/>

View File

@ -28,7 +28,7 @@ namespace Physic
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true); mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true);
Ogre::Quaternion inverse = mBoxRotation.Inverse(); Ogre::Quaternion inverse = mBoxRotation.Inverse();
mBoxRotationInverse = btQuaternion(inverse.x, inverse.y, inverse.z,inverse.w); 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() PhysicActor::~PhysicActor()
@ -109,7 +109,7 @@ namespace Physic
//Create the newly scaled rigid body //Create the newly scaled rigid body
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot); mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot);
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, pos, rot, 0, 0, true); 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 Ogre::Vector3 PhysicActor::getHalfExtents() const
@ -331,8 +331,8 @@ namespace Physic
mHeightFieldMap [name] = hf; mHeightFieldMap [name] = hf;
dynamicsWorld->addRigidBody(body,CollisionType_World|CollisionType_Raycasting, dynamicsWorld->addRigidBody(body,CollisionType_HeightMap|CollisionType_Raycasting,
CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal|CollisionType_Raycasting); CollisionType_World|CollisionType_Actor|CollisionType_Raycasting);
} }
void PhysicEngine::removeHeightField(int x, int y) void PhysicEngine::removeHeightField(int x, int y)
@ -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) if(!body && !raycastingBody)
return; // nothing to do return; // nothing to do
const std::string& name = (body ? body->mName : raycastingBody->mName); const std::string& name = (body ? body->mName : raycastingBody->mName);
if (body) if (body){
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) if (raycastingBody)
dynamicsWorld->addRigidBody(raycastingBody,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_World); dynamicsWorld->addRigidBody(raycastingBody,CollisionType_Raycasting,CollisionType_Raycasting|CollisionType_World);
@ -603,14 +605,17 @@ namespace Physic
{ {
} }
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to) std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly,bool ignoreHeightMap)
{ {
std::string name = ""; std::string name = "";
float d = -1; float d = -1;
float d1 = 10000.; float d1 = 10000.;
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
resultCallback1.m_collisionFilterMask = CollisionType_Raycasting; 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); dynamicsWorld->rayTest(from, to, resultCallback1);
if (resultCallback1.hasHit()) if (resultCallback1.hasHit())
{ {
@ -641,7 +646,7 @@ namespace Physic
std::pair<bool, float> PhysicEngine::sphereCast (float radius, btVector3& from, btVector3& to) std::pair<bool, float> PhysicEngine::sphereCast (float radius, btVector3& from, btVector3& to)
{ {
OurClosestConvexResultCallback callback(from, 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); btSphereShape shape(radius);
const btQuaternion btrot(0.0f, 0.0f, 0.0f); const btQuaternion btrot(0.0f, 0.0f, 0.0f);

View File

@ -46,8 +46,8 @@ namespace Physic
enum CollisionType { enum CollisionType {
CollisionType_Nothing = 0, //<Collide with nothing CollisionType_Nothing = 0, //<Collide with nothing
CollisionType_World = 1<<0, //<Collide with world objects CollisionType_World = 1<<0, //<Collide with world objects
CollisionType_ActorInternal = 1<<1, //<Collide internal capsule Still Used? CollisionType_Actor = 1<<1, //<Collide sith actors
CollisionType_ActorExternal = 1<<2, //<collide with external capsule Still used? CollisionType_HeightMap = 1<<2, //<collide with heightmap
CollisionType_Raycasting = 1<<3 //Still used? CollisionType_Raycasting = 1<<3 //Still used?
}; };
@ -226,7 +226,7 @@ namespace Physic
/** /**
* Add a RigidBody to the simulation * 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. * 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). * Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
*/ */
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to); std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false);
/** /**
* Return all objects hit by a ray. * Return all objects hit by a ray.

View File

@ -27,7 +27,7 @@ void newtrace(traceResults *results, const Ogre::Quaternion& orient, const Ogre:
const btTransform to(btorient, btend); const btTransform to(btorient, btend);
btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend); btCollisionWorld::ClosestConvexResultCallback newTraceCallback(btstart, btend);
newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World; newTraceCallback.m_collisionFilterMask = OEngine::Physic::CollisionType_World|OEngine::Physic::CollisionType_HeightMap|OEngine::Physic::CollisionType_Actor;
enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback); enginePass->dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);