mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:23:52 +00:00
Port CharacterPreview
This commit is contained in:
parent
820f4a2688
commit
72c1f37527
12 changed files with 389 additions and 366 deletions
|
@ -22,10 +22,10 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
actors objects renderingmanager animation sky npcanimation vismask
|
actors objects renderingmanager animation sky npcanimation vismask
|
||||||
creatureanimation effectmanager util renderinginterface pathgrid rendermode
|
creatureanimation effectmanager util renderinginterface pathgrid rendermode
|
||||||
bulletdebugdraw globalmap
|
bulletdebugdraw globalmap characterpreview
|
||||||
# camera
|
# camera
|
||||||
# localmap occlusionquery water shadows
|
# localmap occlusionquery water shadows
|
||||||
# characterpreview ripplesimulation refraction
|
# ripplesimulation refraction
|
||||||
# terrainstorage weaponanimation
|
# terrainstorage weaponanimation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,10 @@ namespace
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
CharacterCreation::CharacterCreation()
|
CharacterCreation::CharacterCreation(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem)
|
||||||
: mNameDialog(0)
|
: mViewer(viewer)
|
||||||
|
, mResourceSystem(resourceSystem)
|
||||||
|
, mNameDialog(0)
|
||||||
, mRaceDialog(0)
|
, mRaceDialog(0)
|
||||||
, mClassChoiceDialog(0)
|
, mClassChoiceDialog(0)
|
||||||
, mGenerateClassQuestionDialog(0)
|
, mGenerateClassQuestionDialog(0)
|
||||||
|
@ -146,7 +148,7 @@ namespace MWGui
|
||||||
case GM_Race:
|
case GM_Race:
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog);
|
MWBase::Environment::get().getWindowManager()->removeDialog(mRaceDialog);
|
||||||
mRaceDialog = 0;
|
mRaceDialog = 0;
|
||||||
mRaceDialog = new RaceDialog();
|
mRaceDialog = new RaceDialog(mViewer, mResourceSystem);
|
||||||
mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen);
|
mRaceDialog->setNextButtonShow(mCreationStage >= CSE_RaceChosen);
|
||||||
mRaceDialog->setRaceId(mPlayerRaceId);
|
mRaceDialog->setRaceId(mPlayerRaceId);
|
||||||
mRaceDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone);
|
mRaceDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onRaceDialogDone);
|
||||||
|
@ -261,12 +263,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterCreation::doRenderUpdate()
|
|
||||||
{
|
|
||||||
if (mRaceDialog)
|
|
||||||
mRaceDialog->doRenderUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
|
void CharacterCreation::onReviewDialogDone(WindowBase* parWindow)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
|
MWBase::Environment::get().getWindowManager()->removeDialog(mReviewDialog);
|
||||||
|
|
|
@ -8,6 +8,16 @@
|
||||||
|
|
||||||
#include "../mwmechanics/stat.hpp"
|
#include "../mwmechanics/stat.hpp"
|
||||||
|
|
||||||
|
namespace osgViewer
|
||||||
|
{
|
||||||
|
class Viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
class ResourceSystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class WindowBase;
|
class WindowBase;
|
||||||
|
@ -29,7 +39,7 @@ namespace MWGui
|
||||||
public:
|
public:
|
||||||
typedef std::vector<int> SkillList;
|
typedef std::vector<int> SkillList;
|
||||||
|
|
||||||
CharacterCreation();
|
CharacterCreation(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem);
|
||||||
~CharacterCreation();
|
~CharacterCreation();
|
||||||
|
|
||||||
//Show a dialog
|
//Show a dialog
|
||||||
|
@ -39,9 +49,11 @@ namespace MWGui
|
||||||
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
|
||||||
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value);
|
void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value);
|
||||||
void configureSkills (const SkillList& major, const SkillList& minor);
|
void configureSkills (const SkillList& major, const SkillList& minor);
|
||||||
void doRenderUpdate();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
osgViewer::Viewer* mViewer;
|
||||||
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
|
||||||
//Dialogs
|
//Dialogs
|
||||||
TextInputDialog* mNameDialog;
|
TextInputDialog* mNameDialog;
|
||||||
RaceDialog* mRaceDialog;
|
RaceDialog* mRaceDialog;
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
#include <MyGUI_InputManager.h>
|
#include <MyGUI_InputManager.h>
|
||||||
#include <MyGUI_Button.h>
|
#include <MyGUI_Button.h>
|
||||||
|
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
|
#include <components/myguiplatform/myguitexture.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -48,22 +52,23 @@ namespace
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop)
|
InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop, osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem)
|
||||||
: WindowPinnableBase("openmw_inventory_window.layout")
|
: WindowPinnableBase("openmw_inventory_window.layout")
|
||||||
, mTrading(false)
|
, mTrading(false)
|
||||||
, mLastXSize(0)
|
, mLastXSize(0)
|
||||||
, mLastYSize(0)
|
, mLastYSize(0)
|
||||||
#if 0
|
, mViewer(viewer)
|
||||||
, mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()))
|
, mResourceSystem(resourceSystem)
|
||||||
#endif
|
, mPreview(new MWRender::InventoryPreview(viewer, resourceSystem, MWBase::Environment::get().getWorld()->getPlayerPtr()))
|
||||||
, mPreviewDirty(true)
|
|
||||||
, mPreviewResize(true)
|
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(dragAndDrop)
|
||||||
, mSortModel(NULL)
|
, mSortModel(NULL)
|
||||||
, mTradeModel(NULL)
|
, mTradeModel(NULL)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
, mGuiMode(GM_Inventory)
|
, mGuiMode(GM_Inventory)
|
||||||
{
|
{
|
||||||
|
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture()));
|
||||||
|
mPreview->rebuild();
|
||||||
|
|
||||||
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
||||||
|
|
||||||
getWidget(mAvatar, "Avatar");
|
getWidget(mAvatar, "Avatar");
|
||||||
|
@ -79,6 +84,8 @@ namespace MWGui
|
||||||
getWidget(mArmorRating, "ArmorRating");
|
getWidget(mArmorRating, "ArmorRating");
|
||||||
|
|
||||||
mAvatarImage->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
mAvatarImage->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked);
|
||||||
|
mAvatarImage->setRenderItemTexture(mPreviewTexture.get());
|
||||||
|
mAvatarImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
|
||||||
|
|
||||||
getWidget(mItemView, "ItemView");
|
getWidget(mItemView, "ItemView");
|
||||||
mItemView->eventItemClicked += MyGUI::newDelegate(this, &InventoryWindow::onItemSelected);
|
mItemView->eventItemClicked += MyGUI::newDelegate(this, &InventoryWindow::onItemSelected);
|
||||||
|
@ -115,17 +122,13 @@ namespace MWGui
|
||||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||||
mItemView->setModel(mSortModel);
|
mItemView->setModel(mSortModel);
|
||||||
|
|
||||||
mPreview.reset(NULL);
|
mPreview->updatePtr(mPtr);
|
||||||
mAvatarImage->setImageTexture("");
|
mPreview->rebuild();
|
||||||
#if 0
|
mPreview->update();
|
||||||
MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().getTexture("CharacterPreview");
|
|
||||||
if (tex)
|
dirtyPreview();
|
||||||
MyGUI::RenderManager::getInstance().destroyTexture(tex);
|
|
||||||
mPreview.reset(new MWRender::InventoryPreview(mPtr));
|
updatePreviewSize();
|
||||||
mPreview->setup();
|
|
||||||
#endif
|
|
||||||
mPreviewDirty = true;
|
|
||||||
mPreviewResize = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::setGuiMode(GuiMode mode)
|
void InventoryWindow::setGuiMode(GuiMode mode)
|
||||||
|
@ -158,7 +161,7 @@ namespace MWGui
|
||||||
static_cast<int>(Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height));
|
static_cast<int>(Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height));
|
||||||
|
|
||||||
if (size.width != mMainWidget->getWidth() || size.height != mMainWidget->getHeight())
|
if (size.width != mMainWidget->getWidth() || size.height != mMainWidget->getHeight())
|
||||||
mPreviewResize = true;
|
updatePreviewSize();
|
||||||
|
|
||||||
mMainWidget->setPosition(pos);
|
mMainWidget->setPosition(pos);
|
||||||
mMainWidget->setSize(size);
|
mMainWidget->setSize(size);
|
||||||
|
@ -319,7 +322,8 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
|
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
|
||||||
|
|
||||||
mItemView->update();
|
mItemView->update();
|
||||||
mPreviewDirty = true;
|
|
||||||
|
dirtyPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::open()
|
void InventoryWindow::open()
|
||||||
|
@ -366,10 +370,31 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
mLastXSize = mMainWidget->getSize().width;
|
mLastXSize = mMainWidget->getSize().width;
|
||||||
mLastYSize = mMainWidget->getSize().height;
|
mLastYSize = mMainWidget->getSize().height;
|
||||||
mPreviewResize = true;
|
|
||||||
|
updatePreviewSize();
|
||||||
|
updateArmorRating();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InventoryWindow::updateArmorRating()
|
||||||
|
{
|
||||||
|
mArmorRating->setCaptionWithReplacing ("#{sArmor}: "
|
||||||
|
+ MyGUI::utility::toString(static_cast<int>(mPtr.getClass().getArmorRating(mPtr))));
|
||||||
|
if (mArmorRating->getTextSize().width > mArmorRating->getSize().width)
|
||||||
|
mArmorRating->setCaptionWithReplacing (MyGUI::utility::toString(static_cast<int>(mPtr.getClass().getArmorRating(mPtr))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void InventoryWindow::updatePreviewSize()
|
||||||
|
{
|
||||||
|
MyGUI::IntSize size = mAvatarImage->getSize();
|
||||||
|
int width = std::min(mPreview->getTextureWidth(), size.width);
|
||||||
|
int height = std::min(mPreview->getTextureHeight(), size.height);
|
||||||
|
mPreview->setViewport(width, height);
|
||||||
|
|
||||||
|
mAvatarImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, height/float(mPreview->getTextureHeight()),
|
||||||
|
width/float(mPreview->getTextureWidth()), 0.f));
|
||||||
|
}
|
||||||
|
|
||||||
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
if (_sender == mFilterAll)
|
if (_sender == mFilterAll)
|
||||||
|
@ -483,8 +508,6 @@ namespace MWGui
|
||||||
|
|
||||||
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
|
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
|
||||||
{
|
{
|
||||||
return MWWorld::Ptr();
|
|
||||||
#if 0
|
|
||||||
int slot = mPreview->getSlotSelected (x, y);
|
int slot = mPreview->getSlotSelected (x, y);
|
||||||
|
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
|
@ -503,7 +526,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
return MWWorld::Ptr();
|
return MWWorld::Ptr();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::updateEncumbranceBar()
|
void InventoryWindow::updateEncumbranceBar()
|
||||||
|
@ -529,36 +551,11 @@ namespace MWGui
|
||||||
mTrading = trading;
|
mTrading = trading;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::doRenderUpdate ()
|
void InventoryWindow::dirtyPreview()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
mPreview->onFrame();
|
|
||||||
|
|
||||||
if (mPreviewResize || mPreviewDirty)
|
|
||||||
{
|
|
||||||
mArmorRating->setCaptionWithReplacing ("#{sArmor}: "
|
|
||||||
+ MyGUI::utility::toString(static_cast<int>(mPtr.getClass().getArmorRating(mPtr))));
|
|
||||||
if (mArmorRating->getTextSize().width > mArmorRating->getSize().width)
|
|
||||||
mArmorRating->setCaptionWithReplacing (MyGUI::utility::toString(static_cast<int>(mPtr.getClass().getArmorRating(mPtr))));
|
|
||||||
}
|
|
||||||
if (mPreviewResize)
|
|
||||||
{
|
|
||||||
mPreviewResize = false;
|
|
||||||
MyGUI::IntSize size = mAvatarImage->getSize();
|
|
||||||
mPreview->resize(size.width, size.height);
|
|
||||||
|
|
||||||
mAvatarImage->setImageTexture("CharacterPreview");
|
|
||||||
mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height)));
|
|
||||||
mAvatarImage->setImageTile(MyGUI::IntSize(std::min(512, size.width), std::min(1024, size.height)));
|
|
||||||
}
|
|
||||||
if (mPreviewDirty)
|
|
||||||
{
|
|
||||||
mPreviewDirty = false;
|
|
||||||
mPreview->update();
|
mPreview->update();
|
||||||
|
|
||||||
mAvatarImage->setImageTexture("CharacterPreview");
|
updateArmorRating();
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::notifyContentChanged()
|
void InventoryWindow::notifyContentChanged()
|
||||||
|
@ -569,7 +566,7 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(
|
MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(
|
||||||
MWBase::Environment::get().getWorld()->getPlayerPtr());
|
MWBase::Environment::get().getWorld()->getPlayerPtr());
|
||||||
|
|
||||||
mPreviewDirty = true;
|
dirtyPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::pickUpObject (MWWorld::Ptr object)
|
void InventoryWindow::pickUpObject (MWWorld::Ptr object)
|
||||||
|
@ -675,8 +672,6 @@ namespace MWGui
|
||||||
|
|
||||||
void InventoryWindow::rebuildAvatar()
|
void InventoryWindow::rebuildAvatar()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
mPreview->rebuild();
|
mPreview->rebuild();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,16 @@
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
namespace osgViewer
|
||||||
|
{
|
||||||
|
class Viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
class ResourceSystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class InventoryPreview;
|
class InventoryPreview;
|
||||||
|
@ -27,12 +37,10 @@ namespace MWGui
|
||||||
class InventoryWindow : public WindowPinnableBase
|
class InventoryWindow : public WindowPinnableBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InventoryWindow(DragAndDrop* dragAndDrop);
|
InventoryWindow(DragAndDrop* dragAndDrop, osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem);
|
||||||
|
|
||||||
virtual void open();
|
virtual void open();
|
||||||
|
|
||||||
void doRenderUpdate();
|
|
||||||
|
|
||||||
/// start trading, disables item drag&drop
|
/// start trading, disables item drag&drop
|
||||||
void setTrading(bool trading);
|
void setTrading(bool trading);
|
||||||
|
|
||||||
|
@ -62,8 +70,6 @@ namespace MWGui
|
||||||
private:
|
private:
|
||||||
DragAndDrop* mDragAndDrop;
|
DragAndDrop* mDragAndDrop;
|
||||||
|
|
||||||
bool mPreviewDirty;
|
|
||||||
bool mPreviewResize;
|
|
||||||
int mSelectedItem;
|
int mSelectedItem;
|
||||||
|
|
||||||
MWWorld::Ptr mPtr;
|
MWWorld::Ptr mPtr;
|
||||||
|
@ -93,6 +99,10 @@ namespace MWGui
|
||||||
int mLastXSize;
|
int mLastXSize;
|
||||||
int mLastYSize;
|
int mLastYSize;
|
||||||
|
|
||||||
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
osgViewer::Viewer* mViewer;
|
||||||
|
|
||||||
|
std::auto_ptr<MyGUI::ITexture> mPreviewTexture;
|
||||||
std::auto_ptr<MWRender::InventoryPreview> mPreview;
|
std::auto_ptr<MWRender::InventoryPreview> mPreview;
|
||||||
|
|
||||||
bool mTrading;
|
bool mTrading;
|
||||||
|
@ -113,6 +123,9 @@ namespace MWGui
|
||||||
|
|
||||||
void updateEncumbranceBar();
|
void updateEncumbranceBar();
|
||||||
void notifyContentChanged();
|
void notifyContentChanged();
|
||||||
|
void dirtyPreview();
|
||||||
|
void updatePreviewSize();
|
||||||
|
void updateArmorRating();
|
||||||
|
|
||||||
void adjustPanes();
|
void adjustPanes();
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,12 @@
|
||||||
#include <MyGUI_RenderManager.h>
|
#include <MyGUI_RenderManager.h>
|
||||||
#include <MyGUI_Gui.h>
|
#include <MyGUI_Gui.h>
|
||||||
|
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
|
#include <components/myguiplatform/myguitexture.hpp>
|
||||||
|
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
@ -37,8 +41,10 @@ namespace
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
|
|
||||||
RaceDialog::RaceDialog()
|
RaceDialog::RaceDialog(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem)
|
||||||
: WindowModal("openmw_chargen_race.layout")
|
: WindowModal("openmw_chargen_race.layout")
|
||||||
|
, mViewer(viewer)
|
||||||
|
, mResourceSystem(resourceSystem)
|
||||||
, mGenderIndex(0)
|
, mGenderIndex(0)
|
||||||
, mFaceIndex(0)
|
, mFaceIndex(0)
|
||||||
, mHairIndex(0)
|
, mHairIndex(0)
|
||||||
|
@ -125,19 +131,20 @@ namespace MWGui
|
||||||
updateSkills();
|
updateSkills();
|
||||||
updateSpellPowers();
|
updateSpellPowers();
|
||||||
|
|
||||||
//mPreview.reset(NULL);
|
mPreviewImage->setRenderItemTexture(NULL);
|
||||||
|
|
||||||
mPreviewImage->setImageTexture("");
|
mPreview.reset(NULL);
|
||||||
|
mPreviewTexture.reset(NULL);
|
||||||
|
|
||||||
const std::string textureName = "CharacterHeadPreview";
|
mPreview.reset(new MWRender::RaceSelectionPreview(mViewer, mResourceSystem));
|
||||||
MyGUI::RenderManager::getInstance().destroyTexture(MyGUI::RenderManager::getInstance().getTexture(textureName));
|
mPreview->rebuild();
|
||||||
|
mPreview->setAngle (mCurrentAngle);
|
||||||
|
|
||||||
//mPreview.reset(new MWRender::RaceSelectionPreview());
|
mPreviewTexture.reset(new osgMyGUI::OSGTexture(mPreview->getTexture()));
|
||||||
//mPreview->setup();
|
mPreviewImage->setRenderItemTexture(mPreviewTexture.get());
|
||||||
//mPreview->update (mCurrentAngle);
|
mPreviewImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f));
|
||||||
|
|
||||||
//const ESM::NPC& proto = mPreview->getPrototype();
|
const ESM::NPC& proto = mPreview->getPrototype();
|
||||||
ESM::NPC proto;
|
|
||||||
setRaceId(proto.mRace);
|
setRaceId(proto.mRace);
|
||||||
recountParts();
|
recountParts();
|
||||||
|
|
||||||
|
@ -153,8 +160,6 @@ namespace MWGui
|
||||||
mHairIndex = i;
|
mHairIndex = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPreviewImage->setImageTexture (textureName);
|
|
||||||
|
|
||||||
mPreviewDirty = true;
|
mPreviewDirty = true;
|
||||||
|
|
||||||
size_t initialPos = mHeadRotate->getScrollRange()/2+mHeadRotate->getScrollRange()/10;
|
size_t initialPos = mHeadRotate->getScrollRange()/2+mHeadRotate->getScrollRange()/10;
|
||||||
|
@ -182,10 +187,10 @@ namespace MWGui
|
||||||
|
|
||||||
void RaceDialog::close()
|
void RaceDialog::close()
|
||||||
{
|
{
|
||||||
mPreviewImage->setImageTexture("");
|
mPreviewImage->setRenderItemTexture(NULL);
|
||||||
const std::string textureName = "CharacterHeadPreview";
|
|
||||||
MyGUI::RenderManager::getInstance().destroyTexture(MyGUI::RenderManager::getInstance().getTexture(textureName));
|
mPreviewTexture.reset(NULL);
|
||||||
//mPreview.reset(NULL);
|
mPreview.reset(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// widget controls
|
// widget controls
|
||||||
|
@ -205,8 +210,8 @@ namespace MWGui
|
||||||
void RaceDialog::onHeadRotate(MyGUI::ScrollBar* scroll, size_t _position)
|
void RaceDialog::onHeadRotate(MyGUI::ScrollBar* scroll, size_t _position)
|
||||||
{
|
{
|
||||||
float angle = (float(_position) / (scroll->getScrollRange()-1) - 0.5f) * 3.14f * 2;
|
float angle = (float(_position) / (scroll->getScrollRange()-1) - 0.5f) * 3.14f * 2;
|
||||||
//mPreview->update (angle);
|
mPreview->setAngle (angle);
|
||||||
mPreviewDirty = true;
|
|
||||||
mCurrentAngle = angle;
|
mCurrentAngle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +322,7 @@ namespace MWGui
|
||||||
|
|
||||||
void RaceDialog::updatePreview()
|
void RaceDialog::updatePreview()
|
||||||
{
|
{
|
||||||
ESM::NPC record;// = mPreview->getPrototype();
|
ESM::NPC record = mPreview->getPrototype();
|
||||||
record.mRace = mCurrentRaceId;
|
record.mRace = mCurrentRaceId;
|
||||||
record.setIsMale(mGenderIndex == 0);
|
record.setIsMale(mGenderIndex == 0);
|
||||||
|
|
||||||
|
@ -326,27 +331,12 @@ namespace MWGui
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//mPreview->setPrototype(record);
|
mPreview->setPrototype(record);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Error creating preview: " << e.what() << std::endl;
|
std::cerr << "Error creating preview: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPreviewDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RaceDialog::doRenderUpdate()
|
|
||||||
{
|
|
||||||
//if (!mPreview.get())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//mPreview->onFrame();
|
|
||||||
if (mPreviewDirty)
|
|
||||||
{
|
|
||||||
//mPreview->render();
|
|
||||||
mPreviewDirty = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceDialog::updateRaces()
|
void RaceDialog::updateRaces()
|
||||||
|
@ -451,8 +441,6 @@ namespace MWGui
|
||||||
|
|
||||||
const ESM::NPC& RaceDialog::getResult() const
|
const ESM::NPC& RaceDialog::getResult() const
|
||||||
{
|
{
|
||||||
static ESM::NPC result;
|
return mPreview->getPrototype();
|
||||||
return result;
|
|
||||||
//return mPreview->getPrototype();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,22 @@ namespace ESM
|
||||||
struct NPC;
|
struct NPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace osgViewer
|
||||||
|
{
|
||||||
|
class Viewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
class ResourceSystem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class RaceDialog : public WindowModal
|
class RaceDialog : public WindowModal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RaceDialog();
|
RaceDialog(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem);
|
||||||
|
|
||||||
enum Gender
|
enum Gender
|
||||||
{
|
{
|
||||||
|
@ -35,13 +45,9 @@ namespace MWGui
|
||||||
const ESM::NPC &getResult() const;
|
const ESM::NPC &getResult() const;
|
||||||
const std::string &getRaceId() const { return mCurrentRaceId; }
|
const std::string &getRaceId() const { return mCurrentRaceId; }
|
||||||
Gender getGender() const { return mGenderIndex == 0 ? GM_Male : GM_Female; }
|
Gender getGender() const { return mGenderIndex == 0 ? GM_Male : GM_Female; }
|
||||||
// getFace()
|
|
||||||
// getHair()
|
|
||||||
|
|
||||||
void setRaceId(const std::string &raceId);
|
void setRaceId(const std::string &raceId);
|
||||||
void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; }
|
void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; }
|
||||||
// setFace()
|
|
||||||
// setHair()
|
|
||||||
|
|
||||||
void setNextButtonShow(bool shown);
|
void setNextButtonShow(bool shown);
|
||||||
virtual void open();
|
virtual void open();
|
||||||
|
@ -60,8 +66,6 @@ namespace MWGui
|
||||||
*/
|
*/
|
||||||
EventHandle_WindowBase eventDone;
|
EventHandle_WindowBase eventDone;
|
||||||
|
|
||||||
void doRenderUpdate();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position);
|
void onHeadRotate(MyGUI::ScrollBar* _sender, size_t _position);
|
||||||
|
|
||||||
|
@ -89,6 +93,9 @@ namespace MWGui
|
||||||
|
|
||||||
void getBodyParts (int part, std::vector<std::string>& out);
|
void getBodyParts (int part, std::vector<std::string>& out);
|
||||||
|
|
||||||
|
osgViewer::Viewer* mViewer;
|
||||||
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
|
||||||
std::vector<std::string> mAvailableHeads;
|
std::vector<std::string> mAvailableHeads;
|
||||||
std::vector<std::string> mAvailableHairs;
|
std::vector<std::string> mAvailableHairs;
|
||||||
|
|
||||||
|
@ -108,7 +115,8 @@ namespace MWGui
|
||||||
|
|
||||||
float mCurrentAngle;
|
float mCurrentAngle;
|
||||||
|
|
||||||
//std::auto_ptr<MWRender::RaceSelectionPreview> mPreview;
|
std::auto_ptr<MWRender::RaceSelectionPreview> mPreview;
|
||||||
|
std::auto_ptr<MyGUI::ITexture> mPreviewTexture;
|
||||||
|
|
||||||
bool mPreviewDirty;
|
bool mPreviewDirty;
|
||||||
};
|
};
|
||||||
|
|
|
@ -275,7 +275,7 @@ namespace MWGui
|
||||||
mJournal = JournalWindow::create(JournalViewModel::create ());
|
mJournal = JournalWindow::create(JournalViewModel::create ());
|
||||||
mMessageBoxManager = new MessageBoxManager(
|
mMessageBoxManager = new MessageBoxManager(
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fMessageTimePerChar")->getFloat());
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fMessageTimePerChar")->getFloat());
|
||||||
mInventoryWindow = new InventoryWindow(mDragAndDrop);
|
mInventoryWindow = new InventoryWindow(mDragAndDrop, mViewer, mResourceSystem);
|
||||||
mTradeWindow = new TradeWindow();
|
mTradeWindow = new TradeWindow();
|
||||||
trackWindow(mTradeWindow, "barter");
|
trackWindow(mTradeWindow, "barter");
|
||||||
mSpellBuyingWindow = new SpellBuyingWindow();
|
mSpellBuyingWindow = new SpellBuyingWindow();
|
||||||
|
@ -324,7 +324,7 @@ namespace MWGui
|
||||||
|
|
||||||
mHud->setVisible(mHudEnabled);
|
mHud->setVisible(mHudEnabled);
|
||||||
|
|
||||||
mCharGen = new CharacterCreation();
|
mCharGen = new CharacterCreation(mViewer, mResourceSystem);
|
||||||
|
|
||||||
// Setup player stats
|
// Setup player stats
|
||||||
for (int i = 0; i < ESM::Attribute::Length; ++i)
|
for (int i = 0; i < ESM::Attribute::Length; ++i)
|
||||||
|
@ -358,7 +358,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
disallowAll();
|
disallowAll();
|
||||||
delete mCharGen;
|
delete mCharGen;
|
||||||
mCharGen = new CharacterCreation();
|
mCharGen = new CharacterCreation(mViewer, mResourceSystem);
|
||||||
mGuiModes.clear();
|
mGuiModes.clear();
|
||||||
MWBase::Environment::get().getInputManager()->changeInputMode(false);
|
MWBase::Environment::get().getInputManager()->changeInputMode(false);
|
||||||
mHud->unsetSelectedWeapon();
|
mHud->unsetSelectedWeapon();
|
||||||
|
|
|
@ -1081,12 +1081,21 @@ namespace MWRender
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Animation::hasNode(const std::string &name)
|
bool Animation::hasNode(const std::string &name) const
|
||||||
{
|
{
|
||||||
std::string lowerName = Misc::StringUtils::lowerCase(name);
|
std::string lowerName = Misc::StringUtils::lowerCase(name);
|
||||||
return (mNodeMap.find(lowerName) != mNodeMap.end());
|
return (mNodeMap.find(lowerName) != mNodeMap.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const osg::Node* Animation::getNode(const std::string &name) const
|
||||||
|
{
|
||||||
|
std::string lowerName = Misc::StringUtils::lowerCase(name);
|
||||||
|
NodeMap::const_iterator found = mNodeMap.find(lowerName);
|
||||||
|
if (found == mNodeMap.end())
|
||||||
|
throw std::runtime_error("Can't find node " + name);
|
||||||
|
return found->second;
|
||||||
|
}
|
||||||
|
|
||||||
float Animation::AnimationTime::getValue(osg::NodeVisitor*)
|
float Animation::AnimationTime::getValue(osg::NodeVisitor*)
|
||||||
{
|
{
|
||||||
if (mTimePtr)
|
if (mTimePtr)
|
||||||
|
|
|
@ -354,7 +354,11 @@ public:
|
||||||
|
|
||||||
/// Is there a node with the specified name?
|
/// Is there a node with the specified name?
|
||||||
/// @note The matching is case-insensitive.
|
/// @note The matching is case-insensitive.
|
||||||
bool hasNode(const std::string& name);
|
bool hasNode(const std::string& name) const;
|
||||||
|
|
||||||
|
/// Return a node with the specified name, throws an exception if the node is not found.
|
||||||
|
/// @note The matching is case-insensitive.
|
||||||
|
const osg::Node* getNode(const std::string& name) const;
|
||||||
|
|
||||||
virtual void showWeapons(bool showWeapon) {}
|
virtual void showWeapons(bool showWeapon) {}
|
||||||
virtual void showCarriedLeft(bool show) {}
|
virtual void showCarriedLeft(bool show) {}
|
||||||
|
|
|
@ -1,189 +1,186 @@
|
||||||
#include "characterpreview.hpp"
|
#include "characterpreview.hpp"
|
||||||
|
|
||||||
#include <OgreSceneManager.h>
|
#include <osg/Texture2D>
|
||||||
#include <OgreRoot.h>
|
#include <osg/Camera>
|
||||||
#include <OgreHardwarePixelBuffer.h>
|
#include <osg/PositionAttitudeTransform>
|
||||||
#include <OgreCamera.h>
|
#include <osgViewer/Viewer>
|
||||||
#include <OgreSceneNode.h>
|
#include <osg/LightModel>
|
||||||
#include <OgreTextureManager.h>
|
|
||||||
#include <OgreViewport.h>
|
|
||||||
#include <OgreRenderTexture.h>
|
|
||||||
|
|
||||||
#include <libs/openengine/ogre/selectionbuffer.hpp>
|
|
||||||
|
|
||||||
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
|
|
||||||
#include "renderconst.hpp"
|
|
||||||
#include "npcanimation.hpp"
|
#include "npcanimation.hpp"
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
CharacterPreview::CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name,
|
class DrawOnceCallback : public osg::NodeCallback
|
||||||
Ogre::Vector3 position, Ogre::Vector3 lookAt)
|
{
|
||||||
: mRecover(false)
|
public:
|
||||||
, mRenderTarget(NULL)
|
DrawOnceCallback ()
|
||||||
, mViewport(NULL)
|
: mRendered(false)
|
||||||
, mCamera(NULL)
|
{
|
||||||
, mSceneMgr (0)
|
}
|
||||||
, mNode(NULL)
|
|
||||||
|
virtual void operator () (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
if (!mRendered)
|
||||||
|
{
|
||||||
|
mRendered = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->setNodeMask(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
traverse(node, nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void redrawNextFrame()
|
||||||
|
{
|
||||||
|
mRendered = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mRendered;
|
||||||
|
};
|
||||||
|
|
||||||
|
CharacterPreview::CharacterPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem,
|
||||||
|
MWWorld::Ptr character, int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt)
|
||||||
|
: mViewer(viewer)
|
||||||
|
, mResourceSystem(resourceSystem)
|
||||||
, mPosition(position)
|
, mPosition(position)
|
||||||
, mLookAt(lookAt)
|
, mLookAt(lookAt)
|
||||||
, mCharacter(character)
|
, mCharacter(character)
|
||||||
, mAnimation(NULL)
|
, mAnimation(NULL)
|
||||||
, mName(name)
|
|
||||||
, mSizeX(sizeX)
|
, mSizeX(sizeX)
|
||||||
, mSizeY(sizeY)
|
, mSizeY(sizeY)
|
||||||
{
|
{
|
||||||
|
mTexture = new osg::Texture2D;
|
||||||
|
mTexture->setTextureSize(sizeX, sizeY);
|
||||||
|
mTexture->setInternalFormat(GL_RGBA);
|
||||||
|
mTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
||||||
|
mTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||||
|
|
||||||
|
mCamera = new osg::Camera;
|
||||||
|
// hints that the camera is not relative to the master camera
|
||||||
|
mCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||||
|
mCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT);
|
||||||
|
mCamera->setClearColor(osg::Vec4(0.f, 0.f, 0.f, 0.f));
|
||||||
|
mCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
const float fovYDegrees = 12.3f;
|
||||||
|
mCamera->setProjectionMatrixAsPerspective(fovYDegrees, sizeX/static_cast<float>(sizeY), 0.1f, 10000.f); // zNear and zFar are autocomputed
|
||||||
|
mCamera->setViewport(0, 0, sizeX, sizeY);
|
||||||
|
mCamera->setRenderOrder(osg::Camera::PRE_RENDER);
|
||||||
|
mCamera->attach(osg::Camera::COLOR_BUFFER, mTexture);
|
||||||
|
mCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
|
||||||
|
|
||||||
|
osg::ref_ptr<SceneUtil::LightManager> lightManager = new SceneUtil::LightManager;
|
||||||
|
lightManager->setStartLight(1);
|
||||||
|
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
|
||||||
|
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
|
||||||
|
stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
||||||
|
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::LightModel> lightmodel = new osg::LightModel;
|
||||||
|
lightmodel->setAmbientIntensity(osg::Vec4(0.25, 0.25, 0.25, 1.0));
|
||||||
|
stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
/// \todo Read the fallback values from INIImporter (Inventory:Directional*) ?
|
||||||
|
osg::ref_ptr<osg::Light> light = new osg::Light;
|
||||||
|
light->setPosition(osg::Vec4(-0.3,0.3,0.7, 0.0));
|
||||||
|
light->setDiffuse(osg::Vec4(1,1,1,1));
|
||||||
|
light->setAmbient(osg::Vec4(0,0,0,1));
|
||||||
|
light->setSpecular(osg::Vec4(0,0,0,0));
|
||||||
|
light->setLightNum(0);
|
||||||
|
light->setConstantAttenuation(1.f);
|
||||||
|
light->setLinearAttenuation(0.f);
|
||||||
|
light->setQuadraticAttenuation(0.f);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource;
|
||||||
|
lightSource->setLight(light);
|
||||||
|
|
||||||
|
lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
lightManager->setStateSet(stateset);
|
||||||
|
lightManager->addChild(lightSource);
|
||||||
|
|
||||||
|
mCamera->addChild(lightManager);
|
||||||
|
|
||||||
|
mNode = new osg::PositionAttitudeTransform;
|
||||||
|
lightManager->addChild(mNode);
|
||||||
|
|
||||||
|
mDrawOnceCallback = new DrawOnceCallback;
|
||||||
|
mCamera->addUpdateCallback(mDrawOnceCallback);
|
||||||
|
|
||||||
|
mViewer->getSceneData()->asGroup()->addChild(mCamera);
|
||||||
|
|
||||||
mCharacter.mCell = NULL;
|
mCharacter.mCell = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterPreview::onSetup()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterPreview::onFrame()
|
|
||||||
{
|
|
||||||
if (mRecover)
|
|
||||||
{
|
|
||||||
setupRenderTarget();
|
|
||||||
mRenderTarget->update();
|
|
||||||
mRecover = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterPreview::setup ()
|
|
||||||
{
|
|
||||||
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
|
|
||||||
|
|
||||||
// This is a dummy light to turn off shadows without having to use a separate set of shaders
|
|
||||||
Ogre::Light* l = mSceneMgr->createLight();
|
|
||||||
l->setType (Ogre::Light::LT_DIRECTIONAL);
|
|
||||||
l->setDiffuseColour (Ogre::ColourValue(0,0,0));
|
|
||||||
|
|
||||||
/// \todo Read the fallback values from INIImporter (Inventory:Directional*)
|
|
||||||
l = mSceneMgr->createLight();
|
|
||||||
l->setType (Ogre::Light::LT_DIRECTIONAL);
|
|
||||||
l->setDirection (Ogre::Vector3(0.3f, -0.7f, 0.3f));
|
|
||||||
l->setDiffuseColour (Ogre::ColourValue(1,1,1));
|
|
||||||
|
|
||||||
mSceneMgr->setAmbientLight (Ogre::ColourValue(0.25, 0.25, 0.25));
|
|
||||||
|
|
||||||
mCamera = mSceneMgr->createCamera (mName);
|
|
||||||
mCamera->setFOVy(Ogre::Degree(12.3f));
|
|
||||||
mCamera->setAspectRatio (float(mSizeX) / float(mSizeY));
|
|
||||||
|
|
||||||
Ogre::SceneNode* renderRoot = mSceneMgr->getRootSceneNode()->createChildSceneNode("renderRoot");
|
|
||||||
|
|
||||||
// leftover of old coordinate system. TODO: remove this and adjust positions/orientations to match
|
|
||||||
renderRoot->pitch(Ogre::Degree(-90));
|
|
||||||
|
|
||||||
mNode = renderRoot->createChildSceneNode();
|
|
||||||
|
|
||||||
mAnimation = new NpcAnimation(mCharacter, mNode,
|
|
||||||
0, true, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
|
|
||||||
|
|
||||||
Ogre::Vector3 scale = mNode->getScale();
|
|
||||||
mCamera->setPosition(mPosition * scale);
|
|
||||||
mCamera->lookAt(mLookAt * scale);
|
|
||||||
|
|
||||||
mCamera->setNearClipDistance (1);
|
|
||||||
mCamera->setFarClipDistance (1000);
|
|
||||||
|
|
||||||
mTexture = Ogre::TextureManager::getSingleton().createManual(mName,
|
|
||||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mSizeX, mSizeY, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET, this);
|
|
||||||
|
|
||||||
setupRenderTarget();
|
|
||||||
|
|
||||||
onSetup ();
|
|
||||||
}
|
|
||||||
|
|
||||||
CharacterPreview::~CharacterPreview ()
|
CharacterPreview::~CharacterPreview ()
|
||||||
{
|
{
|
||||||
if (mSceneMgr)
|
mViewer->getSceneData()->asGroup()->removeChild(mCamera);
|
||||||
{
|
|
||||||
mSceneMgr->destroyAllCameras();
|
|
||||||
delete mAnimation;
|
|
||||||
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
|
|
||||||
Ogre::TextureManager::getSingleton().remove(mName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CharacterPreview::getTextureWidth() const
|
||||||
|
{
|
||||||
|
return mSizeX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CharacterPreview::getTextureHeight() const
|
||||||
|
{
|
||||||
|
return mSizeY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharacterPreview::onSetup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Texture2D> CharacterPreview::getTexture()
|
||||||
|
{
|
||||||
|
return mTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterPreview::rebuild()
|
void CharacterPreview::rebuild()
|
||||||
{
|
{
|
||||||
delete mAnimation;
|
delete mAnimation;
|
||||||
mAnimation = NULL;
|
mAnimation = NULL;
|
||||||
mAnimation = new NpcAnimation(mCharacter, mNode,
|
|
||||||
0, true, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
|
|
||||||
|
|
||||||
float scale=1.f;
|
mAnimation = new NpcAnimation(mCharacter, mNode, mResourceSystem, 0, true, true,
|
||||||
mCharacter.getClass().adjustScale(mCharacter, scale);
|
(renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
|
||||||
mNode->setScale(Ogre::Vector3(scale));
|
|
||||||
|
|
||||||
mCamera->setPosition(mPosition * mNode->getScale());
|
|
||||||
mCamera->lookAt(mLookAt * mNode->getScale());
|
|
||||||
|
|
||||||
onSetup();
|
onSetup();
|
||||||
|
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharacterPreview::loadResource(Ogre::Resource *resource)
|
void CharacterPreview::redraw()
|
||||||
{
|
{
|
||||||
Ogre::Texture* tex = dynamic_cast<Ogre::Texture*>(resource);
|
mCamera->setNodeMask(~0);
|
||||||
if (!tex)
|
mDrawOnceCallback->redrawNextFrame();
|
||||||
return;
|
|
||||||
|
|
||||||
tex->createInternalResources();
|
|
||||||
|
|
||||||
mRenderTarget = NULL;
|
|
||||||
mViewport = NULL;
|
|
||||||
mRecover = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CharacterPreview::setupRenderTarget()
|
|
||||||
{
|
|
||||||
mRenderTarget = mTexture->getBuffer()->getRenderTarget();
|
|
||||||
mRenderTarget->removeAllViewports ();
|
|
||||||
mViewport = mRenderTarget->addViewport(mCamera);
|
|
||||||
mViewport->setOverlaysEnabled(false);
|
|
||||||
mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0));
|
|
||||||
mViewport->setShadowsEnabled(false);
|
|
||||||
mRenderTarget->setActive(true);
|
|
||||||
mRenderTarget->setAutoUpdated (false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
InventoryPreview::InventoryPreview(MWWorld::Ptr character)
|
InventoryPreview::InventoryPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character)
|
||||||
: CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 71, -700), Ogre::Vector3(0,71,0))
|
: CharacterPreview(viewer, resourceSystem, character, 512, 1024, osg::Vec3f(0, 700, 71), osg::Vec3f(0,0,71))
|
||||||
, mSizeX(0)
|
|
||||||
, mSizeY(0)
|
|
||||||
, mSelectionBuffer(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryPreview::~InventoryPreview()
|
void InventoryPreview::setViewport(int sizeX, int sizeY)
|
||||||
{
|
{
|
||||||
delete mSelectionBuffer;
|
sizeX = std::max(sizeX, 0);
|
||||||
}
|
sizeY = std::max(sizeY, 0);
|
||||||
|
|
||||||
void InventoryPreview::resize(int sizeX, int sizeY)
|
mCamera->setViewport(0, 0, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY));
|
||||||
{
|
|
||||||
mSizeX = sizeX;
|
|
||||||
mSizeY = sizeY;
|
|
||||||
|
|
||||||
mViewport->setDimensions (0, 0, std::min(1.f, float(mSizeX) / float(512)), std::min(1.f, float(mSizeY) / float(1024)));
|
redraw();
|
||||||
mTexture->load();
|
|
||||||
|
|
||||||
if (!mRenderTarget)
|
|
||||||
setupRenderTarget();
|
|
||||||
|
|
||||||
mRenderTarget->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryPreview::update()
|
void InventoryPreview::update()
|
||||||
|
@ -191,6 +188,7 @@ namespace MWRender
|
||||||
if (!mAnimation)
|
if (!mAnimation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mAnimation->showWeapons(true);
|
||||||
mAnimation->updateParts();
|
mAnimation->updateParts();
|
||||||
|
|
||||||
MWWorld::InventoryStore &inv = mCharacter.getClass().getInventoryStore(mCharacter);
|
MWWorld::InventoryStore &inv = mCharacter.getClass().getInventoryStore(mCharacter);
|
||||||
|
@ -250,70 +248,51 @@ namespace MWRender
|
||||||
|
|
||||||
mAnimation->runAnimation(0.0f);
|
mAnimation->runAnimation(0.0f);
|
||||||
|
|
||||||
mNode->setOrientation (Ogre::Quaternion::IDENTITY);
|
redraw();
|
||||||
|
|
||||||
mViewport->setDimensions (0, 0, std::min(1.f, float(mSizeX) / float(512)), std::min(1.f, float(mSizeY) / float(1024)));
|
|
||||||
mTexture->load();
|
|
||||||
|
|
||||||
if (!mRenderTarget)
|
|
||||||
setupRenderTarget();
|
|
||||||
|
|
||||||
mRenderTarget->update();
|
|
||||||
|
|
||||||
mSelectionBuffer->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InventoryPreview::setupRenderTarget()
|
|
||||||
{
|
|
||||||
CharacterPreview::setupRenderTarget();
|
|
||||||
mViewport->setDimensions (0, 0, std::min(1.f, float(mSizeX) / float(512)), std::min(1.f, float(mSizeY) / float(1024)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InventoryPreview::getSlotSelected (int posX, int posY)
|
int InventoryPreview::getSlotSelected (int posX, int posY)
|
||||||
{
|
{
|
||||||
return mSelectionBuffer->getSelected (posX, posY);
|
// TODO: implement
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InventoryPreview::updatePtr(const MWWorld::Ptr &ptr)
|
||||||
|
{
|
||||||
|
mCharacter = MWWorld::Ptr(ptr.getBase(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryPreview::onSetup()
|
void InventoryPreview::onSetup()
|
||||||
{
|
{
|
||||||
delete mSelectionBuffer;
|
osg::Vec3f scale (1.f, 1.f, 1.f);
|
||||||
mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0);
|
mCharacter.getClass().adjustScale(mCharacter, scale);
|
||||||
|
|
||||||
mAnimation->showWeapons(true);
|
mNode->setScale(scale);
|
||||||
|
|
||||||
mCurrentAnimGroup = "inventoryhandtohand";
|
mCamera->setViewMatrixAsLookAt(mPosition * scale.z(), mLookAt * scale.z(), osg::Vec3f(0,0,1));
|
||||||
mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
RaceSelectionPreview::RaceSelectionPreview()
|
RaceSelectionPreview::RaceSelectionPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem)
|
||||||
: CharacterPreview(MWBase::Environment::get().getWorld()->getPlayerPtr(),
|
: CharacterPreview(viewer, resourceSystem, MWBase::Environment::get().getWorld()->getPlayerPtr(),
|
||||||
512, 512, "CharacterHeadPreview", Ogre::Vector3(0, 8, -125), Ogre::Vector3(0,127,0))
|
512, 512, osg::Vec3f(0, 125, 8), osg::Vec3f(0,0,8))
|
||||||
, mBase (*mCharacter.get<ESM::NPC>()->mBase)
|
, mBase (*mCharacter.get<ESM::NPC>()->mBase)
|
||||||
, mRef(&mBase)
|
, mRef(&mBase)
|
||||||
, mPitch(Ogre::Degree(6))
|
, mPitchRadians(osg::DegreesToRadians(6.f))
|
||||||
{
|
{
|
||||||
mCharacter = MWWorld::Ptr(&mRef, NULL);
|
mCharacter = MWWorld::Ptr(&mRef, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceSelectionPreview::update(float angle)
|
RaceSelectionPreview::~RaceSelectionPreview()
|
||||||
{
|
{
|
||||||
mAnimation->runAnimation(0.0f);
|
|
||||||
|
|
||||||
mNode->setOrientation(Ogre::Quaternion(Ogre::Radian(angle), Ogre::Vector3::UNIT_Z)
|
|
||||||
* Ogre::Quaternion(mPitch, Ogre::Vector3::UNIT_X));
|
|
||||||
|
|
||||||
updateCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceSelectionPreview::render()
|
void RaceSelectionPreview::setAngle(float angleRadians)
|
||||||
{
|
{
|
||||||
mTexture->load();
|
mNode->setAttitude(osg::Quat(mPitchRadians, osg::Vec3(1,0,0))
|
||||||
|
* osg::Quat(angleRadians, osg::Vec3(0,0,1)));
|
||||||
if (!mRenderTarget)
|
redraw();
|
||||||
setupRenderTarget();
|
|
||||||
mRenderTarget->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceSelectionPreview::setPrototype(const ESM::NPC &proto)
|
void RaceSelectionPreview::setPrototype(const ESM::NPC &proto)
|
||||||
|
@ -321,27 +300,53 @@ namespace MWRender
|
||||||
mBase = proto;
|
mBase = proto;
|
||||||
mBase.mId = "player";
|
mBase.mId = "player";
|
||||||
rebuild();
|
rebuild();
|
||||||
mAnimation->runAnimation(0.0f);
|
|
||||||
updateCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UpdateCameraCallback : public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UpdateCameraCallback(osg::ref_ptr<const osg::Node> nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset)
|
||||||
|
: mNodeToFollow(nodeToFollow)
|
||||||
|
, mPosOffset(posOffset)
|
||||||
|
, mLookAtOffset(lookAtOffset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
osg::Camera* cam = static_cast<osg::Camera*>(node);
|
||||||
|
|
||||||
|
// Update keyframe controllers in the scene graph first...
|
||||||
|
traverse(node, nv);
|
||||||
|
|
||||||
|
// Now update camera utilizing the updated head position
|
||||||
|
osg::MatrixList mats = mNodeToFollow->getWorldMatrices();
|
||||||
|
if (!mats.size())
|
||||||
|
return;
|
||||||
|
osg::Matrix worldMat = mats[0];
|
||||||
|
osg::Vec3 headOffset = worldMat.getTrans();
|
||||||
|
|
||||||
|
cam->setViewMatrixAsLookAt(headOffset + mPosOffset, headOffset + mLookAtOffset, osg::Vec3(0,0,1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
osg::ref_ptr<const osg::Node> mNodeToFollow;
|
||||||
|
osg::Vec3 mPosOffset;
|
||||||
|
osg::Vec3 mLookAtOffset;
|
||||||
|
};
|
||||||
|
|
||||||
void RaceSelectionPreview::onSetup ()
|
void RaceSelectionPreview::onSetup ()
|
||||||
{
|
{
|
||||||
mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
|
mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
|
||||||
|
mAnimation->runAnimation(0.f);
|
||||||
|
|
||||||
updateCamera();
|
// attach camera to follow the head node
|
||||||
|
if (mUpdateCameraCallback)
|
||||||
|
mCamera->removeUpdateCallback(mUpdateCameraCallback);
|
||||||
|
|
||||||
|
const osg::Node* head = mAnimation->getNode("Bip01 Head");
|
||||||
|
mUpdateCameraCallback = new UpdateCameraCallback(head, mPosition, mLookAt);
|
||||||
|
mCamera->addUpdateCallback(mUpdateCameraCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RaceSelectionPreview::updateCamera()
|
|
||||||
{
|
|
||||||
Ogre::Vector3 scale = mNode->getScale();
|
|
||||||
Ogre::Node* headNode = mAnimation->getNode("Bip01 Head");
|
|
||||||
if (!headNode)
|
|
||||||
return;
|
|
||||||
Ogre::Vector3 headOffset = headNode->_getDerivedPosition();
|
|
||||||
headOffset = mNode->convertLocalToWorldPosition(headOffset);
|
|
||||||
|
|
||||||
mCamera->setPosition(headOffset + mPosition * scale);
|
|
||||||
mCamera->lookAt(headOffset + mPosition*Ogre::Vector3(0,1,0) * scale);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,48 @@
|
||||||
#ifndef MWRENDER_CHARACTERPREVIEW_H
|
#ifndef MWRENDER_CHARACTERPREVIEW_H
|
||||||
#define MWRENDER_CHARACTERPREVIEW_H
|
#define MWRENDER_CHARACTERPREVIEW_H
|
||||||
|
|
||||||
#include <OgreRenderTarget.h>
|
|
||||||
#include <OgreMaterialManager.h>
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
|
|
||||||
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
namespace OEngine
|
namespace osg
|
||||||
{
|
{
|
||||||
namespace Render
|
class Texture2D;
|
||||||
{
|
class Camera;
|
||||||
class SelectionBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace osgViewer
|
||||||
|
{
|
||||||
|
class Viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
|
|
||||||
class NpcAnimation;
|
class NpcAnimation;
|
||||||
|
class DrawOnceCallback;
|
||||||
|
|
||||||
class CharacterPreview : public Ogre::ManualResourceLoader
|
class CharacterPreview
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CharacterPreview(MWWorld::Ptr character, int sizeX, int sizeY, const std::string& name,
|
CharacterPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character, int sizeX, int sizeY,
|
||||||
Ogre::Vector3 position, Ogre::Vector3 lookAt);
|
const osg::Vec3f& position, const osg::Vec3f& lookAt);
|
||||||
virtual ~CharacterPreview();
|
virtual ~CharacterPreview();
|
||||||
|
|
||||||
virtual void setup ();
|
int getTextureWidth() const;
|
||||||
virtual void onSetup();
|
int getTextureHeight() const;
|
||||||
|
|
||||||
virtual void rebuild();
|
void redraw();
|
||||||
|
|
||||||
void onFrame();
|
void rebuild();
|
||||||
|
|
||||||
void loadResource(Ogre::Resource *resource);
|
osg::ref_ptr<osg::Texture2D> getTexture();
|
||||||
|
|
||||||
private:
|
|
||||||
bool mRecover; // Texture content was lost and needs to be re-rendered
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CharacterPreview(const CharacterPreview&);
|
CharacterPreview(const CharacterPreview&);
|
||||||
|
@ -47,28 +50,23 @@ namespace MWRender
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool renderHeadOnly() { return false; }
|
virtual bool renderHeadOnly() { return false; }
|
||||||
|
virtual void onSetup();
|
||||||
|
|
||||||
virtual void setupRenderTarget();
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||||
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
osg::ref_ptr<osg::Texture2D> mTexture;
|
||||||
|
osg::ref_ptr<osg::Camera> mCamera;
|
||||||
|
osg::ref_ptr<DrawOnceCallback> mDrawOnceCallback;
|
||||||
|
|
||||||
Ogre::TexturePtr mTexture;
|
osg::Vec3f mPosition;
|
||||||
Ogre::RenderTarget* mRenderTarget;
|
osg::Vec3f mLookAt;
|
||||||
Ogre::Viewport* mViewport;
|
|
||||||
|
|
||||||
Ogre::Camera* mCamera;
|
|
||||||
|
|
||||||
Ogre::SceneManager* mSceneMgr;
|
|
||||||
Ogre::SceneNode* mNode;
|
|
||||||
|
|
||||||
Ogre::Vector3 mPosition;
|
|
||||||
Ogre::Vector3 mLookAt;
|
|
||||||
|
|
||||||
MWWorld::Ptr mCharacter;
|
MWWorld::Ptr mCharacter;
|
||||||
|
|
||||||
MWRender::NpcAnimation* mAnimation;
|
MWRender::NpcAnimation* mAnimation;
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> mNode;
|
||||||
std::string mCurrentAnimGroup;
|
std::string mCurrentAnimGroup;
|
||||||
|
|
||||||
std::string mName;
|
|
||||||
|
|
||||||
int mSizeX;
|
int mSizeX;
|
||||||
int mSizeY;
|
int mSizeY;
|
||||||
};
|
};
|
||||||
|
@ -77,25 +75,21 @@ namespace MWRender
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InventoryPreview(MWWorld::Ptr character);
|
InventoryPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem, MWWorld::Ptr character);
|
||||||
virtual ~InventoryPreview();
|
|
||||||
virtual void onSetup();
|
void updatePtr(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
void update(); // Render preview again, e.g. after changed equipment
|
void update(); // Render preview again, e.g. after changed equipment
|
||||||
void resize(int sizeX, int sizeY);
|
void setViewport(int sizeX, int sizeY);
|
||||||
|
|
||||||
int getSlotSelected(int posX, int posY);
|
int getSlotSelected(int posX, int posY);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setupRenderTarget();
|
virtual void onSetup();
|
||||||
|
|
||||||
private:
|
|
||||||
int mSizeX;
|
|
||||||
int mSizeY;
|
|
||||||
|
|
||||||
OEngine::Render::SelectionBuffer* mSelectionBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UpdateCameraCallback;
|
||||||
|
|
||||||
class RaceSelectionPreview : public CharacterPreview
|
class RaceSelectionPreview : public CharacterPreview
|
||||||
{
|
{
|
||||||
ESM::NPC mBase;
|
ESM::NPC mBase;
|
||||||
|
@ -104,16 +98,13 @@ namespace MWRender
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual bool renderHeadOnly() { return true; }
|
virtual bool renderHeadOnly() { return true; }
|
||||||
|
virtual void onSetup();
|
||||||
void updateCamera();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RaceSelectionPreview();
|
RaceSelectionPreview(osgViewer::Viewer* viewer, Resource::ResourceSystem* resourceSystem);
|
||||||
|
virtual ~RaceSelectionPreview();
|
||||||
|
|
||||||
virtual void onSetup();
|
void setAngle(float angleRadians);
|
||||||
void render();
|
|
||||||
|
|
||||||
void update(float angle);
|
|
||||||
|
|
||||||
const ESM::NPC &getPrototype() const {
|
const ESM::NPC &getPrototype() const {
|
||||||
return mBase;
|
return mBase;
|
||||||
|
@ -123,7 +114,9 @@ namespace MWRender
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Ogre::Radian mPitch;
|
osg::ref_ptr<UpdateCameraCallback> mUpdateCameraCallback;
|
||||||
|
|
||||||
|
float mPitchRadians;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue