forked from mirror/openmw-tes3mp
Merge branch 'master' into move
This commit is contained in:
commit
6a2fe564ef
26 changed files with 304 additions and 82 deletions
|
@ -94,6 +94,7 @@ Programmers
|
||||||
Nolan Poe (nopoe)
|
Nolan Poe (nopoe)
|
||||||
Paul Cercueil (pcercuei)
|
Paul Cercueil (pcercuei)
|
||||||
Paul McElroy (Greendogo)
|
Paul McElroy (Greendogo)
|
||||||
|
Pi03k
|
||||||
Pieter van der Kloet (pvdk)
|
Pieter van der Kloet (pvdk)
|
||||||
pkubik
|
pkubik
|
||||||
Radu-Marius Popovici (rpopovici)
|
Radu-Marius Popovici (rpopovici)
|
||||||
|
|
|
@ -90,7 +90,7 @@ opencs_units (view/render
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
lighting lightingday lightingnight
|
lighting lightingday lightingnight
|
||||||
lightingbright object cell terrainstorage tagbase cellarrow cellmarker
|
lightingbright object cell terrainstorage tagbase cellarrow cellmarker cellborder
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
|
|
|
@ -47,7 +47,7 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
|
||||||
|
|
||||||
void CSVDoc::SubView::closeEvent (QCloseEvent *event)
|
void CSVDoc::SubView::closeEvent (QCloseEvent *event)
|
||||||
{
|
{
|
||||||
emit updateSubViewIndicies (this);
|
emit updateSubViewIndices (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CSVDoc::SubView::getTitle() const
|
std::string CSVDoc::SubView::getTitle() const
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace CSVDoc
|
||||||
|
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
|
|
||||||
void updateSubViewIndicies (SubView *view = 0);
|
void updateSubViewIndices (SubView *view = NULL);
|
||||||
|
|
||||||
void universalIdChanged (const CSMWorld::UniversalId& universalId);
|
void universalIdChanged (const CSMWorld::UniversalId& universalId);
|
||||||
|
|
||||||
|
|
|
@ -343,7 +343,7 @@ void CSVDoc::View::updateTitle()
|
||||||
setWindowTitle (QString::fromUtf8(stream.str().c_str()));
|
setWindowTitle (QString::fromUtf8(stream.str().c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVDoc::View::updateSubViewIndicies(SubView *view)
|
void CSVDoc::View::updateSubViewIndices(SubView *view)
|
||||||
{
|
{
|
||||||
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
|
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ void CSVDoc::View::updateSubViewIndicies(SubView *view)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete subView->titleBarWidget();
|
delete subView->titleBarWidget();
|
||||||
subView->setTitleBarWidget (0);
|
subView->setTitleBarWidget (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ void CSVDoc::View::updateActions()
|
||||||
|
|
||||||
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
|
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
|
||||||
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
|
||||||
mViewTotal (totalViews), mScroll(0), mScrollbarOnly(false)
|
mViewTotal (totalViews), mScroll(NULL), mScrollbarOnly(false)
|
||||||
{
|
{
|
||||||
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
|
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
|
||||||
|
|
||||||
|
@ -419,10 +419,7 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mScroll = new QScrollArea(this);
|
createScrollArea();
|
||||||
mScroll->setWidgetResizable(true);
|
|
||||||
mScroll->setWidget(&mSubViewWindow);
|
|
||||||
setCentralWidget(mScroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mOperations = new Operations;
|
mOperations = new Operations;
|
||||||
|
@ -570,36 +567,11 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
||||||
//
|
//
|
||||||
mScrollbarOnly = windows["mainwindow-scrollbar"].toString() == "Scrollbar Only";
|
mScrollbarOnly = windows["mainwindow-scrollbar"].toString() == "Scrollbar Only";
|
||||||
|
|
||||||
QDesktopWidget *dw = QApplication::desktop();
|
updateWidth(windows["grow-limit"].isTrue(), minWidth);
|
||||||
QRect rect;
|
|
||||||
if (windows["grow-limit"].isTrue())
|
|
||||||
rect = dw->screenGeometry(this);
|
|
||||||
else
|
|
||||||
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
|
|
||||||
|
|
||||||
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
|
|
||||||
{
|
|
||||||
int newWidth = width()+minWidth;
|
|
||||||
int frameWidth = frameGeometry().width() - width();
|
|
||||||
if (newWidth+frameWidth <= rect.width())
|
|
||||||
{
|
|
||||||
resize(newWidth, height());
|
|
||||||
// WARNING: below code assumes that new subviews are added to the right
|
|
||||||
if (x() > rect.width()-(newWidth+frameWidth))
|
|
||||||
move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// full width
|
|
||||||
resize(rect.width()-frameWidth, height());
|
|
||||||
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth);
|
|
||||||
move(0, y());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
|
||||||
|
|
||||||
updateSubViewIndicies();
|
updateSubViewIndices();
|
||||||
|
|
||||||
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
|
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
|
||||||
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
|
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
|
||||||
|
@ -608,8 +580,8 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
|
||||||
|
|
||||||
connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle()));
|
connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle()));
|
||||||
|
|
||||||
connect (view, SIGNAL (updateSubViewIndicies (SubView *)),
|
connect (view, SIGNAL (updateSubViewIndices (SubView *)),
|
||||||
this, SLOT (updateSubViewIndicies (SubView *)));
|
this, SLOT (updateSubViewIndices (SubView *)));
|
||||||
|
|
||||||
view->show();
|
view->show();
|
||||||
|
|
||||||
|
@ -631,7 +603,7 @@ void CSVDoc::View::moveScrollBarToEnd(int min, int max)
|
||||||
void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
|
void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
|
||||||
{
|
{
|
||||||
if (*setting=="Windows/hide-subview")
|
if (*setting=="Windows/hide-subview")
|
||||||
updateSubViewIndicies (0);
|
updateSubViewIndices (NULL);
|
||||||
else if (*setting=="Windows/mainwindow-scrollbar")
|
else if (*setting=="Windows/mainwindow-scrollbar")
|
||||||
{
|
{
|
||||||
if (setting->toString()!="Grow Only")
|
if (setting->toString()!="Grow Only")
|
||||||
|
@ -651,10 +623,7 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mScroll = new QScrollArea(this);
|
createScrollArea();
|
||||||
mScroll->setWidgetResizable(true);
|
|
||||||
mScroll->setWidget(&mSubViewWindow);
|
|
||||||
setCentralWidget(mScroll);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mScroll)
|
else if (mScroll)
|
||||||
|
@ -662,7 +631,7 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
|
||||||
mScroll->takeWidget();
|
mScroll->takeWidget();
|
||||||
setCentralWidget (&mSubViewWindow);
|
setCentralWidget (&mSubViewWindow);
|
||||||
mScroll->deleteLater();
|
mScroll->deleteLater();
|
||||||
mScroll = 0;
|
mScroll = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -959,3 +928,41 @@ void CSVDoc::View::merge()
|
||||||
{
|
{
|
||||||
emit mergeDocument (mDocument);
|
emit mergeDocument (mDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth)
|
||||||
|
{
|
||||||
|
QDesktopWidget *dw = QApplication::desktop();
|
||||||
|
QRect rect;
|
||||||
|
if (isGrowLimit)
|
||||||
|
rect = dw->screenGeometry(this);
|
||||||
|
else
|
||||||
|
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
|
||||||
|
|
||||||
|
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
|
||||||
|
{
|
||||||
|
int newWidth = width()+minSubViewWidth;
|
||||||
|
int frameWidth = frameGeometry().width() - width();
|
||||||
|
if (newWidth+frameWidth <= rect.width())
|
||||||
|
{
|
||||||
|
resize(newWidth, height());
|
||||||
|
// WARNING: below code assumes that new subviews are added to the right
|
||||||
|
if (x() > rect.width()-(newWidth+frameWidth))
|
||||||
|
move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// full width
|
||||||
|
resize(rect.width()-frameWidth, height());
|
||||||
|
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minSubViewWidth);
|
||||||
|
move(0, y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVDoc::View::createScrollArea()
|
||||||
|
{
|
||||||
|
mScroll = new QScrollArea(this);
|
||||||
|
mScroll->setWidgetResizable(true);
|
||||||
|
mScroll->setWidget(&mSubViewWindow);
|
||||||
|
setCentralWidget(mScroll);
|
||||||
|
}
|
||||||
|
|
|
@ -95,7 +95,8 @@ namespace CSVDoc
|
||||||
void resizeViewHeight (int height);
|
void resizeViewHeight (int height);
|
||||||
|
|
||||||
void updateScrollbar();
|
void updateScrollbar();
|
||||||
|
void updateWidth(bool isGrowLimit, int minSubViewWidth);
|
||||||
|
void createScrollArea();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
|
||||||
|
@ -143,7 +144,7 @@ namespace CSVDoc
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
|
|
||||||
// called when subviews are added or removed
|
// called when subviews are added or removed
|
||||||
void updateSubViewIndicies (SubView *view = 0);
|
void updateSubViewIndices (SubView *view = NULL);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,9 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
|
||||||
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Mask_Terrain));
|
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Mask_Terrain));
|
||||||
mTerrain->loadCell(esmLand.mX,
|
mTerrain->loadCell(esmLand.mX,
|
||||||
esmLand.mY);
|
esmLand.mY);
|
||||||
|
|
||||||
|
mCellBorder.reset(new CellBorder(mCellNode, mCoordinates));
|
||||||
|
mCellBorder->buildShape(esmLand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "object.hpp"
|
#include "object.hpp"
|
||||||
#include "cellarrow.hpp"
|
#include "cellarrow.hpp"
|
||||||
#include "cellmarker.hpp"
|
#include "cellmarker.hpp"
|
||||||
|
#include "cellborder.hpp"
|
||||||
|
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
||||||
|
@ -44,6 +45,7 @@ namespace CSVRender
|
||||||
CSMWorld::CellCoordinates mCoordinates;
|
CSMWorld::CellCoordinates mCoordinates;
|
||||||
std::auto_ptr<CellArrow> mCellArrows[4];
|
std::auto_ptr<CellArrow> mCellArrows[4];
|
||||||
std::auto_ptr<CellMarker> mCellMarker;
|
std::auto_ptr<CellMarker> mCellMarker;
|
||||||
|
std::auto_ptr<CellBorder> mCellBorder;
|
||||||
bool mDeleted;
|
bool mDeleted;
|
||||||
int mSubMode;
|
int mSubMode;
|
||||||
unsigned int mSubModeElementMask;
|
unsigned int mSubModeElementMask;
|
||||||
|
|
96
apps/opencs/view/render/cellborder.cpp
Normal file
96
apps/opencs/view/render/cellborder.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include "cellborder.hpp"
|
||||||
|
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
|
#include <components/esm/loadland.hpp>
|
||||||
|
|
||||||
|
#include "mask.hpp"
|
||||||
|
|
||||||
|
#include "../../model/world/cellcoordinates.hpp"
|
||||||
|
|
||||||
|
const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE;
|
||||||
|
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 3;
|
||||||
|
|
||||||
|
|
||||||
|
CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords)
|
||||||
|
: mParentNode(cellNode)
|
||||||
|
{
|
||||||
|
mBaseNode = new osg::PositionAttitudeTransform();
|
||||||
|
mBaseNode->setNodeMask(Mask_CellBorder);
|
||||||
|
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
|
||||||
|
|
||||||
|
mParentNode->addChild(mBaseNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::CellBorder::~CellBorder()
|
||||||
|
{
|
||||||
|
mParentNode->removeChild(mBaseNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand)
|
||||||
|
{
|
||||||
|
const ESM::Land::LandData* landData = esmLand.getLandData(ESM::Land::DATA_VHGT);
|
||||||
|
|
||||||
|
if (!landData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
|
||||||
|
|
||||||
|
// Vertices
|
||||||
|
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
|
||||||
|
|
||||||
|
int x = 0, y = 0;
|
||||||
|
for (; x < ESM::Land::LAND_SIZE; ++x)
|
||||||
|
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||||
|
|
||||||
|
x = ESM::Land::LAND_SIZE - 1;
|
||||||
|
for (; y < ESM::Land::LAND_SIZE; ++y)
|
||||||
|
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||||
|
|
||||||
|
y = ESM::Land::LAND_SIZE - 1;
|
||||||
|
for (; x >= 0; --x)
|
||||||
|
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
for (; y >= 0; --y)
|
||||||
|
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
|
||||||
|
|
||||||
|
geometry->setVertexArray(vertices);
|
||||||
|
|
||||||
|
// Color
|
||||||
|
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
|
||||||
|
colors->push_back(osg::Vec4f(0.f, 0.5f, 0.f, 1.f));
|
||||||
|
|
||||||
|
geometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
|
||||||
|
|
||||||
|
// Primitive
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> primitives =
|
||||||
|
new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount+1);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < VertexCount; ++i)
|
||||||
|
primitives->setElement(i, i);
|
||||||
|
|
||||||
|
primitives->setElement(VertexCount, 0);
|
||||||
|
|
||||||
|
geometry->addPrimitiveSet(primitives);
|
||||||
|
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
|
||||||
|
geode->addDrawable(geometry);
|
||||||
|
mBaseNode->addChild(geode);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CSVRender::CellBorder::landIndex(int x, int y)
|
||||||
|
{
|
||||||
|
return y * ESM::Land::LAND_SIZE + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CSVRender::CellBorder::scaleToWorld(int value)
|
||||||
|
{
|
||||||
|
return (CellSize + 128) * (float)value / ESM::Land::LAND_SIZE;
|
||||||
|
}
|
54
apps/opencs/view/render/cellborder.hpp
Normal file
54
apps/opencs/view/render/cellborder.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef OPENCS_VIEW_CELLBORDER_H
|
||||||
|
#define OPENCS_VIEW_CELLBORDER_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
namespace osg
|
||||||
|
{
|
||||||
|
class Group;
|
||||||
|
class PositionAttitudeTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct Land;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class CellCoordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
|
||||||
|
class CellBorder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords);
|
||||||
|
~CellBorder();
|
||||||
|
|
||||||
|
void buildShape(const ESM::Land& esmLand);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const int CellSize;
|
||||||
|
static const int VertexCount;
|
||||||
|
|
||||||
|
size_t landIndex(int x, int y);
|
||||||
|
float scaleToWorld(int val);
|
||||||
|
|
||||||
|
// unimplemented
|
||||||
|
CellBorder(const CellBorder&);
|
||||||
|
CellBorder& operator=(const CellBorder&);
|
||||||
|
|
||||||
|
osg::Group* mParentNode;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -598,7 +598,7 @@ CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibil
|
||||||
mControlElements->addButton (":placeholder", Mask_CellMarker, ":placeholder",
|
mControlElements->addButton (":placeholder", Mask_CellMarker, ":placeholder",
|
||||||
"Cell marker");
|
"Cell marker");
|
||||||
mControlElements->addButton (":placeholder", Mask_CellArrow, ":placeholder", "Cell arrows");
|
mControlElements->addButton (":placeholder", Mask_CellArrow, ":placeholder", "Cell arrows");
|
||||||
mControlElements->addButton (":placeholder", Mask_CellBorder, ":placeholder", "Cell border");
|
mControlElements->addButton (":scenetoolbar/grid", Mask_CellBorder, ":scenetoolbar/grid-small", "Cell border");
|
||||||
|
|
||||||
mControlElements->setSelectionMask (0xffffffff);
|
mControlElements->setSelectionMask (0xffffffff);
|
||||||
|
|
||||||
|
|
|
@ -1363,6 +1363,7 @@ namespace MWRender
|
||||||
foundKeyframeCtrl = true;
|
foundKeyframeCtrl = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
cb = cb->getNestedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundKeyframeCtrl)
|
if (foundKeyframeCtrl)
|
||||||
|
|
|
@ -182,23 +182,30 @@ void WeaponAnimation::deleteControllers()
|
||||||
|
|
||||||
void WeaponAnimation::configureControllers(float characterPitchRadians)
|
void WeaponAnimation::configureControllers(float characterPitchRadians)
|
||||||
{
|
{
|
||||||
if (!mSpineControllers[0])
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mPitchFactor == 0.f || characterPitchRadians == 0.f)
|
if (mPitchFactor == 0.f || characterPitchRadians == 0.f)
|
||||||
{
|
{
|
||||||
for (int i=0; i<2; ++i)
|
setControllerEnabled(false);
|
||||||
mSpineControllers[i]->setEnabled(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pitch = characterPitchRadians * mPitchFactor;
|
float pitch = characterPitchRadians * mPitchFactor;
|
||||||
osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0));
|
osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0));
|
||||||
for (int i=0; i<2; ++i)
|
setControllerRotate(rotate);
|
||||||
{
|
setControllerEnabled(true);
|
||||||
mSpineControllers[i]->setRotate(rotate);
|
|
||||||
mSpineControllers[i]->setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WeaponAnimation::setControllerRotate(const osg::Quat& rotate)
|
||||||
|
{
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
if (mSpineControllers[i])
|
||||||
|
mSpineControllers[i]->setRotate(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeaponAnimation::setControllerEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
for (int i=0; i<2; ++i)
|
||||||
|
if (mSpineControllers[i])
|
||||||
|
mSpineControllers[i]->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ namespace MWRender
|
||||||
|
|
||||||
osg::ref_ptr<RotateController> mSpineControllers[2];
|
osg::ref_ptr<RotateController> mSpineControllers[2];
|
||||||
|
|
||||||
|
void setControllerRotate(const osg::Quat& rotate);
|
||||||
|
void setControllerEnabled(bool enabled);
|
||||||
|
|
||||||
virtual osg::Group* getArrowBone() = 0;
|
virtual osg::Group* getArrowBone() = 0;
|
||||||
virtual osg::Node* getWeaponNode() = 0;
|
virtual osg::Node* getWeaponNode() = 0;
|
||||||
virtual Resource::ResourceSystem* getResourceSystem() = 0;
|
virtual Resource::ResourceSystem* getResourceSystem() = 0;
|
||||||
|
|
|
@ -2039,7 +2039,7 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const
|
bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const
|
||||||
{
|
{
|
||||||
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
if (!(cell->getCell()->hasWater())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pos.z() < cell->getWaterLevel();
|
return pos.z() < cell->getWaterLevel();
|
||||||
|
|
|
@ -141,7 +141,7 @@ struct Cell
|
||||||
|
|
||||||
bool hasWater() const
|
bool hasWater() const
|
||||||
{
|
{
|
||||||
return (mData.mFlags&HasWater) != 0;
|
return ((mData.mFlags&HasWater) != 0) || isExterior();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the given reader to the stored position. Will try to open
|
// Restore the given reader to the stored position. Will try to open
|
||||||
|
|
|
@ -470,7 +470,7 @@ namespace NifOsg
|
||||||
const Nif::NiTextureEffect* textureEffect = static_cast<const Nif::NiTextureEffect*>(nifNode);
|
const Nif::NiTextureEffect* textureEffect = static_cast<const Nif::NiTextureEffect*>(nifNode);
|
||||||
if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map)
|
if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map)
|
||||||
{
|
{
|
||||||
std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << std::endl;
|
std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " << mFilename << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ namespace NifOsg
|
||||||
texGen->setMode(osg::TexGen::SPHERE_MAP);
|
texGen->setMode(osg::TexGen::SPHERE_MAP);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << std::endl;
|
std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << " in " << mFilename << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,17 +1374,15 @@ namespace NifOsg
|
||||||
case Nif::NiTexturingProperty::DarkTexture:
|
case Nif::NiTexturingProperty::DarkTexture:
|
||||||
case Nif::NiTexturingProperty::BumpTexture:
|
case Nif::NiTexturingProperty::BumpTexture:
|
||||||
case Nif::NiTexturingProperty::DetailTexture:
|
case Nif::NiTexturingProperty::DetailTexture:
|
||||||
|
case Nif::NiTexturingProperty::DecalTexture:
|
||||||
break;
|
break;
|
||||||
case Nif::NiTexturingProperty::GlossTexture:
|
case Nif::NiTexturingProperty::GlossTexture:
|
||||||
{
|
{
|
||||||
|
// Not used by the vanilla engine. MCP (Morrowind Code Patch) adds an option to use Gloss maps:
|
||||||
|
// "- Gloss map fix. Morrowind removed gloss map entries from model files after loading them. This stops Morrowind from removing them."
|
||||||
std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl;
|
std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case Nif::NiTexturingProperty::DecalTexture:
|
|
||||||
{
|
|
||||||
std::cerr << "NiTexturingProperty::DecalTexture in " << mFilename << " not currently used." << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
std::cerr << "Warning: unhandled texture stage " << i << " in " << mFilename << std::endl;
|
std::cerr << "Warning: unhandled texture stage " << i << " in " << mFilename << std::endl;
|
||||||
|
@ -1435,16 +1433,16 @@ namespace NifOsg
|
||||||
{
|
{
|
||||||
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
|
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
|
||||||
texEnv->setScale_RGB(2.f);
|
texEnv->setScale_RGB(2.f);
|
||||||
texEnv->setCombine_Alpha(GL_MODULATE);
|
texEnv->setCombine_Alpha(osg::TexEnvCombine::MODULATE);
|
||||||
texEnv->setOperand0_Alpha(GL_SRC_ALPHA);
|
texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA);
|
||||||
texEnv->setOperand1_Alpha(GL_SRC_ALPHA);
|
texEnv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA);
|
||||||
texEnv->setSource0_Alpha(GL_PREVIOUS_ARB);
|
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
||||||
texEnv->setSource1_Alpha(GL_TEXTURE);
|
texEnv->setSource1_Alpha(osg::TexEnvCombine::TEXTURE);
|
||||||
texEnv->setCombine_RGB(GL_MODULATE);
|
texEnv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
|
||||||
texEnv->setOperand0_RGB(GL_SRC_COLOR);
|
texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
|
||||||
texEnv->setOperand1_RGB(GL_SRC_COLOR);
|
texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
|
||||||
texEnv->setSource0_RGB(GL_PREVIOUS_ARB);
|
texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
||||||
texEnv->setSource1_RGB(GL_TEXTURE);
|
texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
|
||||||
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
else if (i == Nif::NiTexturingProperty::BumpTexture)
|
else if (i == Nif::NiTexturingProperty::BumpTexture)
|
||||||
|
@ -1452,6 +1450,21 @@ namespace NifOsg
|
||||||
// Set this texture to Off by default since we can't render it with the fixed-function pipeline
|
// Set this texture to Off by default since we can't render it with the fixed-function pipeline
|
||||||
stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
|
||||||
}
|
}
|
||||||
|
else if (i == Nif::NiTexturingProperty::DecalTexture)
|
||||||
|
{
|
||||||
|
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
|
||||||
|
texEnv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
|
||||||
|
texEnv->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
|
||||||
|
texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
|
||||||
|
texEnv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS);
|
||||||
|
texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
|
||||||
|
texEnv->setSource2_RGB(osg::TexEnvCombine::TEXTURE);
|
||||||
|
texEnv->setOperand2_RGB(osg::TexEnvCombine::SRC_ALPHA);
|
||||||
|
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
||||||
|
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
||||||
|
texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA);
|
||||||
|
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
||||||
|
}
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
|
@ -1470,6 +1483,9 @@ namespace NifOsg
|
||||||
case Nif::NiTexturingProperty::DetailTexture:
|
case Nif::NiTexturingProperty::DetailTexture:
|
||||||
texture2d->setName("detailMap");
|
texture2d->setName("detailMap");
|
||||||
break;
|
break;
|
||||||
|
case Nif::NiTexturingProperty::DecalTexture:
|
||||||
|
texture2d->setName("decalMap");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@ namespace Resource
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResourceManager::~ResourceManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceManager::updateCache(double referenceTime)
|
void ResourceManager::updateCache(double referenceTime)
|
||||||
{
|
{
|
||||||
mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime);
|
mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime);
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Resource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResourceManager(const VFS::Manager* vfs);
|
ResourceManager(const VFS::Manager* vfs);
|
||||||
|
virtual ~ResourceManager();
|
||||||
|
|
||||||
/// Clear cache entries that have not been referenced for longer than expiryDelay.
|
/// Clear cache entries that have not been referenced for longer than expiryDelay.
|
||||||
virtual void updateCache(double referenceTime);
|
virtual void updateCache(double referenceTime);
|
||||||
|
|
|
@ -102,9 +102,15 @@ namespace SceneUtil
|
||||||
// Need to invert culling because of the negative scale
|
// Need to invert culling because of the negative scale
|
||||||
// Note: for absolute correctness we would need to check the current front face for every mesh then invert it
|
// Note: for absolute correctness we would need to check the current front face for every mesh then invert it
|
||||||
// However MW isn't doing this either, so don't. Assuming all meshes are using backface culling is more efficient.
|
// However MW isn't doing this either, so don't. Assuming all meshes are using backface culling is more efficient.
|
||||||
|
static osg::ref_ptr<osg::StateSet> frontFaceStateSet;
|
||||||
|
if (!frontFaceStateSet)
|
||||||
|
{
|
||||||
|
frontFaceStateSet = new osg::StateSet;
|
||||||
osg::FrontFace* frontFace = new osg::FrontFace;
|
osg::FrontFace* frontFace = new osg::FrontFace;
|
||||||
frontFace->setMode(osg::FrontFace::CLOCKWISE);
|
frontFace->setMode(osg::FrontFace::CLOCKWISE);
|
||||||
trans->getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON);
|
frontFaceStateSet->setAttributeAndModes(frontFace, osg::StateAttribute::ON);
|
||||||
|
}
|
||||||
|
trans->setStateSet(frontFaceStateSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trans)
|
if (trans)
|
||||||
|
|
|
@ -88,11 +88,11 @@ namespace Shader
|
||||||
return newStateSet.get();
|
return newStateSet.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap" };
|
const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap", "decalMap" };
|
||||||
bool isTextureNameRecognized(const std::string& name)
|
bool isTextureNameRecognized(const std::string& name)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<sizeof(defaultTextures)/sizeof(defaultTextures[0]); ++i)
|
for (unsigned int i=0; i<sizeof(defaultTextures)/sizeof(defaultTextures[0]); ++i)
|
||||||
if (name.c_str() == defaultTextures[i])
|
if (name == defaultTextures[i])
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
BIN
files/opencs/grid-view-small.png
Normal file
BIN
files/opencs/grid-view-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 472 B |
BIN
files/opencs/grid-view.png
Normal file
BIN
files/opencs/grid-view.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 210 B |
|
@ -80,6 +80,8 @@
|
||||||
<file alias="free-camera">flying eye.png</file>
|
<file alias="free-camera">flying eye.png</file>
|
||||||
<file alias="orbiting-camera">orbit2.png</file>
|
<file alias="orbiting-camera">orbit2.png</file>
|
||||||
<file alias="play">scene-play.png</file>
|
<file alias="play">scene-play.png</file>
|
||||||
|
<file alias="grid">grid-view.png</file>
|
||||||
|
<file alias="grid-small">grid-view-small.png</file>
|
||||||
<file alias="scene-view-1">scene-view-references.png</file>
|
<file alias="scene-view-1">scene-view-references.png</file>
|
||||||
<file alias="scene-view-16">scene-view-terrain.png</file>
|
<file alias="scene-view-16">scene-view-terrain.png</file>
|
||||||
<file alias="scene-view-4">scene-view-water.png</file>
|
<file alias="scene-view-4">scene-view-water.png</file>
|
||||||
|
|
|
@ -15,6 +15,11 @@ uniform sampler2D detailMap;
|
||||||
varying vec2 detailMapUV;
|
varying vec2 detailMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if @decalMap
|
||||||
|
uniform sampler2D decalMap;
|
||||||
|
varying vec2 decalMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if @emissiveMap
|
#if @emissiveMap
|
||||||
uniform sampler2D emissiveMap;
|
uniform sampler2D emissiveMap;
|
||||||
varying vec2 emissiveMapUV;
|
varying vec2 emissiveMapUV;
|
||||||
|
@ -67,6 +72,11 @@ void main()
|
||||||
gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz;
|
gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if @decalMap
|
||||||
|
vec4 decalTex = texture2D(decalMap, decalMapUV);
|
||||||
|
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
|
||||||
|
#endif
|
||||||
|
|
||||||
vec3 viewNormal = passViewNormal;
|
vec3 viewNormal = passViewNormal;
|
||||||
|
|
||||||
#if @normalMap
|
#if @normalMap
|
||||||
|
|
|
@ -12,6 +12,10 @@ varying vec2 darkMapUV;
|
||||||
varying vec2 detailMapUV;
|
varying vec2 detailMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if @decalMap
|
||||||
|
varying vec2 decalMapUV;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if @emissiveMap
|
#if @emissiveMap
|
||||||
varying vec2 emissiveMapUV;
|
varying vec2 emissiveMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,7 +72,11 @@ void main(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if @detailMap
|
#if @detailMap
|
||||||
detailMapUV = (gl_TextureMatrix[@detailMap] * gl_MultiTexCoord@detailMap).xy;
|
detailMapUV = (gl_TextureMatrix[@detailMapUV] * gl_MultiTexCoord@detailMapUV).xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @decalMap
|
||||||
|
decalMapUV = (gl_TextureMatrix[@decalMapUV] * gl_MultiTexCoord@decalMapUV).xy;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if @emissiveMap
|
#if @emissiveMap
|
||||||
|
|
Loading…
Reference in a new issue