|
|
|
@ -2,6 +2,7 @@
|
|
|
|
|
#include "renderingmanager.hpp"
|
|
|
|
|
|
|
|
|
|
#include "../mwworld/environment.hpp"
|
|
|
|
|
#include "../mwworld/world.hpp"
|
|
|
|
|
#include "../mwgui/window_manager.hpp"
|
|
|
|
|
|
|
|
|
|
#include <OgreOverlayManager.h>
|
|
|
|
@ -10,16 +11,24 @@
|
|
|
|
|
using namespace MWRender;
|
|
|
|
|
using namespace Ogre;
|
|
|
|
|
|
|
|
|
|
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWWorld::Environment* env)
|
|
|
|
|
LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManager* rendering, MWWorld::Environment* env) :
|
|
|
|
|
mInterior(false), mCellX(0), mCellY(0)
|
|
|
|
|
{
|
|
|
|
|
mRendering = rend;
|
|
|
|
|
mRenderingManager = rendering;
|
|
|
|
|
mEnvironment = env;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mCameraPosNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode();
|
|
|
|
|
mCameraRotNode = mCameraPosNode->createChildSceneNode();
|
|
|
|
|
mCameraNode = mCameraRotNode->createChildSceneNode();
|
|
|
|
|
|
|
|
|
|
mCellCamera = mRendering->getScene()->createCamera("CellCamera");
|
|
|
|
|
mCellCamera->setProjectionType(PT_ORTHOGRAPHIC);
|
|
|
|
|
// look down -y
|
|
|
|
|
const float sqrt0pt5 = 0.707106781;
|
|
|
|
|
mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0));
|
|
|
|
|
|
|
|
|
|
mCameraNode->attachObject(mCellCamera);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LocalMap::~LocalMap()
|
|
|
|
@ -27,6 +36,12 @@ LocalMap::~LocalMap()
|
|
|
|
|
deleteBuffers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ogre::Vector2 LocalMap::rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle)
|
|
|
|
|
{
|
|
|
|
|
return Vector2( Math::Cos(angle) * (p.x - c.x) - Math::Sin(angle) * (p.y - c.y) + c.x,
|
|
|
|
|
Math::Sin(angle) * (p.x - c.x) + Math::Cos(angle) * (p.y - c.y) + c.y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LocalMap::deleteBuffers()
|
|
|
|
|
{
|
|
|
|
|
mBuffers.clear();
|
|
|
|
@ -65,9 +80,6 @@ void LocalMap::saveFogOfWar(MWWorld::Ptr::CellStore* cell)
|
|
|
|
|
{
|
|
|
|
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
|
|
|
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
|
|
|
|
|
/// \todo why is this workaround needed?
|
|
|
|
|
min *= 1.3;
|
|
|
|
|
max *= 1.3;
|
|
|
|
|
Vector2 length = max-min;
|
|
|
|
|
|
|
|
|
|
// divide into segments
|
|
|
|
@ -90,11 +102,15 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell)
|
|
|
|
|
{
|
|
|
|
|
mInterior = false;
|
|
|
|
|
|
|
|
|
|
mCameraRotNode->setOrientation(Quaternion::IDENTITY);
|
|
|
|
|
|
|
|
|
|
std::string name = "Cell_"+coordStr(cell->cell->data.gridX, cell->cell->data.gridY);
|
|
|
|
|
|
|
|
|
|
int x = cell->cell->data.gridX;
|
|
|
|
|
int y = cell->cell->data.gridY;
|
|
|
|
|
|
|
|
|
|
mCameraPosNode->setPosition(Vector3(0,0,0));
|
|
|
|
|
|
|
|
|
|
render((x+0.5)*sSize, (-y-0.5)*sSize, -10000, 10000, sSize, sSize, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -103,17 +119,29 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
|
|
|
|
|
{
|
|
|
|
|
mInterior = true;
|
|
|
|
|
mBounds = bounds;
|
|
|
|
|
|
|
|
|
|
Vector2 z(bounds.getMaximum().y, bounds.getMinimum().y);
|
|
|
|
|
Vector2 min(bounds.getMinimum().x, bounds.getMinimum().z);
|
|
|
|
|
Vector2 max(bounds.getMaximum().x, bounds.getMaximum().z);
|
|
|
|
|
|
|
|
|
|
/// \todo why is this workaround needed?
|
|
|
|
|
min *= 1.3;
|
|
|
|
|
max *= 1.3;
|
|
|
|
|
Vector2 z(mBounds.getMaximum().y, mBounds.getMinimum().y);
|
|
|
|
|
|
|
|
|
|
const Vector2& north = mEnvironment->mWorld->getNorthVector(cell);
|
|
|
|
|
Radian angle(std::atan2(-north.x, -north.y));
|
|
|
|
|
mAngle = angle.valueRadians();
|
|
|
|
|
mCameraRotNode->setOrientation(Quaternion(Math::Cos(angle/2.f), 0, Math::Sin(angle/2.f), 0));
|
|
|
|
|
|
|
|
|
|
mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_LEFT_BOTTOM)));
|
|
|
|
|
mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::FAR_LEFT_BOTTOM)));
|
|
|
|
|
mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::NEAR_RIGHT_BOTTOM)));
|
|
|
|
|
mBounds.merge(mCameraRotNode->convertWorldToLocalPosition(bounds.getCorner(AxisAlignedBox::FAR_RIGHT_BOTTOM)));
|
|
|
|
|
|
|
|
|
|
mBounds.scale(Vector3(2,2,2));
|
|
|
|
|
|
|
|
|
|
Vector2 center(mBounds.getCenter().x, mBounds.getCenter().z);
|
|
|
|
|
|
|
|
|
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
|
|
|
Vector2 max(mBounds.getMaximum().x, mBounds.getMaximum().z);
|
|
|
|
|
|
|
|
|
|
Vector2 length = max-min;
|
|
|
|
|
Vector2 center(bounds.getCenter().x, bounds.getCenter().z);
|
|
|
|
|
|
|
|
|
|
mCameraPosNode->setPosition(Vector3(center.x, 0, center.y));
|
|
|
|
|
|
|
|
|
|
// divide into segments
|
|
|
|
|
const int segsX = std::ceil( length.x / sSize );
|
|
|
|
@ -128,7 +156,7 @@ void LocalMap::requestMap(MWWorld::Ptr::CellStore* cell,
|
|
|
|
|
Vector2 start = min + Vector2(sSize*x,sSize*y);
|
|
|
|
|
Vector2 newcenter = start + 4096;
|
|
|
|
|
|
|
|
|
|
render(newcenter.x, newcenter.y, z.y, z.x, sSize, sSize,
|
|
|
|
|
render(newcenter.x - center.x, newcenter.y - center.y, z.y, z.x, sSize, sSize,
|
|
|
|
|
cell->cell->name + "_" + coordStr(x,y));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -147,8 +175,9 @@ void LocalMap::render(const float x, const float y,
|
|
|
|
|
|
|
|
|
|
// make everything visible
|
|
|
|
|
mRendering->getScene()->setAmbientLight(ColourValue(1,1,1));
|
|
|
|
|
mRenderingManager->disableLights();
|
|
|
|
|
|
|
|
|
|
mCellCamera->setPosition(Vector3(x, zhigh+100000, y));
|
|
|
|
|
mCameraNode->setPosition(Vector3(x, zhigh+100000, y));
|
|
|
|
|
//mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 );
|
|
|
|
|
mCellCamera->setFarClipDistance(0); // infinite
|
|
|
|
|
|
|
|
|
@ -215,13 +244,14 @@ void LocalMap::render(const float x, const float y,
|
|
|
|
|
//rtt->writeContentsToFile("./" + texture + ".jpg");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mRenderingManager->enableLights();
|
|
|
|
|
|
|
|
|
|
// re-enable fog
|
|
|
|
|
mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3& direction)
|
|
|
|
|
void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaternion& orientation)
|
|
|
|
|
{
|
|
|
|
|
if (sFogOfWarSkip != 0)
|
|
|
|
|
{
|
|
|
|
@ -232,7 +262,19 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
|
|
|
|
|
|
|
|
|
// retrieve the x,y grid coordinates the player is in
|
|
|
|
|
int x,y;
|
|
|
|
|
Vector2 pos(position.x, position.z);
|
|
|
|
|
Vector3 _pos(position.x, 0, position.z);
|
|
|
|
|
Vector2 pos(_pos.x, _pos.z);
|
|
|
|
|
|
|
|
|
|
if (mInterior)
|
|
|
|
|
{
|
|
|
|
|
pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Vector3 playerdirection = -mCameraRotNode->convertWorldToLocalOrientation(orientation).zAxis();
|
|
|
|
|
|
|
|
|
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
|
|
|
|
|
|
|
|
if (!mInterior)
|
|
|
|
|
{
|
|
|
|
|
x = std::ceil(pos.x / sSize)-1;
|
|
|
|
@ -242,9 +284,6 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
|
|
|
min *= 1.3;
|
|
|
|
|
|
|
|
|
|
x = std::ceil((pos.x - min.x)/sSize)-1;
|
|
|
|
|
y = std::ceil((pos.y - min.y)/sSize)-1;
|
|
|
|
|
|
|
|
|
@ -259,20 +298,17 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Vector3&
|
|
|
|
|
u = std::abs((pos.x - (sSize*x))/sSize);
|
|
|
|
|
v = 1-std::abs((pos.y + (sSize*y))/sSize);
|
|
|
|
|
texName = "Cell_"+coordStr(x,y);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Vector2 min(mBounds.getMinimum().x, mBounds.getMinimum().z);
|
|
|
|
|
min *= 1.3;
|
|
|
|
|
|
|
|
|
|
u = (pos.x - min.x - sSize*x)/sSize;
|
|
|
|
|
v = (pos.y - min.y - sSize*y)/sSize;
|
|
|
|
|
|
|
|
|
|
texName = mInteriorName + "_" + coordStr(x,y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mEnvironment->mWindowManager->setPlayerPos(u, v);
|
|
|
|
|
mEnvironment->mWindowManager->setPlayerDir(direction.x, -direction.z);
|
|
|
|
|
mEnvironment->mWindowManager->setPlayerDir(playerdirection.x, -playerdirection.z);
|
|
|
|
|
|
|
|
|
|
// explore radius (squared)
|
|
|
|
|
const float sqrExploreRadius = 0.01 * sFogOfWarResolution*sFogOfWarResolution;
|
|
|
|
|