Port CharacterPreview

c++11
scrawl 10 years ago
parent 820f4a2688
commit 72c1f37527

@ -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->update();
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 ();
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() CharacterPreview::~CharacterPreview ()
{ {
mViewer->getSceneData()->asGroup()->removeChild(mCamera);
} }
void CharacterPreview::onFrame() int CharacterPreview::getTextureWidth() const
{ {
if (mRecover) return mSizeX;
{
setupRenderTarget();
mRenderTarget->update();
mRecover = false;
}
} }
void CharacterPreview::setup () int CharacterPreview::getTextureHeight() const
{ {
mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); return mSizeY;
}
// 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 (); void CharacterPreview::onSetup()
{
} }
CharacterPreview::~CharacterPreview () osg::ref_ptr<osg::Texture2D> CharacterPreview::getTexture()
{ {
if (mSceneMgr) return mTexture;
{
mSceneMgr->destroyAllCameras();
delete mAnimation;
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
Ogre::TextureManager::getSingleton().remove(mName);
}
} }
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;
mCharacter.getClass().adjustScale(mCharacter, scale);
mNode->setScale(Ogre::Vector3(scale));
mCamera->setPosition(mPosition * mNode->getScale()); mAnimation = new NpcAnimation(mCharacter, mNode, mResourceSystem, 0, true, true,
mCamera->lookAt(mLookAt * mNode->getScale()); (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
onSetup(); onSetup();
}
void CharacterPreview::loadResource(Ogre::Resource *resource)
{
Ogre::Texture* tex = dynamic_cast<Ogre::Texture*>(resource);
if (!tex)
return;
tex->createInternalResources();
mRenderTarget = NULL; redraw();
mViewport = NULL;
mRecover = true;
} }
void CharacterPreview::setupRenderTarget() void CharacterPreview::redraw()
{ {
mRenderTarget = mTexture->getBuffer()->getRenderTarget(); mCamera->setNodeMask(~0);
mRenderTarget->removeAllViewports (); mDrawOnceCallback->redrawNextFrame();
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)
{
mSizeX = sizeX;
mSizeY = sizeY;
mViewport->setDimensions (0, 0, std::min(1.f, float(mSizeX) / float(512)), std::min(1.f, float(mSizeY) / float(1024))); mCamera->setViewport(0, 0, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY));
mTexture->load();
if (!mRenderTarget) redraw();
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() int InventoryPreview::getSlotSelected (int posX, int posY)
{ {
CharacterPreview::setupRenderTarget(); // TODO: implement
mViewport->setDimensions (0, 0, std::min(1.f, float(mSizeX) / float(512)), std::min(1.f, float(mSizeY) / float(1024))); return 0;
} }
int InventoryPreview::getSlotSelected (int posX, int posY) void InventoryPreview::updatePtr(const MWWorld::Ptr &ptr)
{ {
return mSelectionBuffer->getSelected (posX, posY); 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();
} }
void RaceSelectionPreview::onSetup () class UpdateCameraCallback : public osg::NodeCallback
{ {
mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); public:
UpdateCameraCallback(osg::ref_ptr<const osg::Node> nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset)
: mNodeToFollow(nodeToFollow)
, mPosOffset(posOffset)
, mLookAtOffset(lookAtOffset)
{
}
updateCamera(); virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
} {
osg::Camera* cam = static_cast<osg::Camera*>(node);
void RaceSelectionPreview::updateCamera() // 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 ()
{ {
Ogre::Vector3 scale = mNode->getScale(); mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
Ogre::Node* headNode = mAnimation->getNode("Bip01 Head"); mAnimation->runAnimation(0.f);
if (!headNode)
return;
Ogre::Vector3 headOffset = headNode->_getDerivedPosition();
headOffset = mNode->convertLocalToWorldPosition(headOffset);
mCamera->setPosition(headOffset + mPosition * scale); // attach camera to follow the head node
mCamera->lookAt(headOffset + mPosition*Ogre::Vector3(0,1,0) * scale); if (mUpdateCameraCallback)
mCamera->removeUpdateCallback(mUpdateCameraCallback);
const osg::Node* head = mAnimation->getNode("Bip01 Head");
mUpdateCameraCallback = new UpdateCameraCallback(head, mPosition, mLookAt);
mCamera->addUpdateCallback(mUpdateCameraCallback);
} }
} }

@ -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 onFrame(); void redraw();
void loadResource(Ogre::Resource *resource); void rebuild();
private: osg::ref_ptr<osg::Texture2D> getTexture();
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;
Ogre::TexturePtr mTexture; osg::ref_ptr<osg::Texture2D> mTexture;
Ogre::RenderTarget* mRenderTarget; osg::ref_ptr<osg::Camera> mCamera;
Ogre::Viewport* mViewport; osg::ref_ptr<DrawOnceCallback> mDrawOnceCallback;
Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
Ogre::SceneNode* mNode;
Ogre::Vector3 mPosition; osg::Vec3f mPosition;
Ogre::Vector3 mLookAt; osg::Vec3f 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…
Cancel
Save