mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-05 16:45:34 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
034ebf8ffd
31 changed files with 198 additions and 41 deletions
|
@ -182,8 +182,8 @@ namespace MWBase
|
||||||
virtual void activateQuickKey (int index) = 0;
|
virtual void activateQuickKey (int index) = 0;
|
||||||
|
|
||||||
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0;
|
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0;
|
||||||
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent) = 0;
|
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item) = 0;
|
||||||
virtual void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent) = 0;
|
virtual void setSelectedWeapon(const MWWorld::Ptr& item) = 0;
|
||||||
virtual void unsetSelectedSpell() = 0;
|
virtual void unsetSelectedSpell() = 0;
|
||||||
virtual void unsetSelectedWeapon() = 0;
|
virtual void unsetSelectedWeapon() = 0;
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,9 @@ namespace MWBase
|
||||||
virtual MWWorld::Ptr getFacedObject() = 0;
|
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||||
|
|
||||||
|
virtual void adjustPosition (const MWWorld::Ptr& ptr) = 0;
|
||||||
|
///< Adjust position after load to be on ground. Must be called after model load.
|
||||||
|
|
||||||
virtual void deleteObject (const MWWorld::Ptr& ptr) = 0;
|
virtual void deleteObject (const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
||||||
|
|
|
@ -260,6 +260,8 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
if (!info.enchant.empty())
|
||||||
|
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge;
|
||||||
|
|
||||||
info.text = text;
|
info.text = text;
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,8 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
if (!info.enchant.empty())
|
||||||
|
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge;
|
||||||
|
|
||||||
info.text = text;
|
info.text = text;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
#include "../mwworld/actiontalk.hpp"
|
#include "../mwworld/actiontalk.hpp"
|
||||||
|
@ -86,6 +87,11 @@ namespace MWClass
|
||||||
return ref->mBase->mId;
|
return ref->mBase->mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Creature::adjustPosition(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->adjustPosition(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
MWRender::Actors& actors = renderingInterface.getActors();
|
MWRender::Actors& actors = renderingInterface.getActors();
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace MWClass
|
||||||
|
|
||||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||||
|
|
||||||
|
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||||
/// can return an empty string.
|
/// can return an empty string.
|
||||||
|
|
|
@ -160,6 +160,11 @@ namespace MWClass
|
||||||
return ref->mBase->mId;
|
return ref->mBase->mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Npc::adjustPosition(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->adjustPosition(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr));
|
renderingInterface.getActors().insertNPC(ptr, getInventoryStore(ptr));
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace MWClass
|
||||||
|
|
||||||
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
|
||||||
|
|
||||||
|
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
virtual std::string getName (const MWWorld::Ptr& ptr) const;
|
||||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||||
/// can return an empty string.
|
/// can return an empty string.
|
||||||
|
|
|
@ -349,6 +349,9 @@ namespace MWClass
|
||||||
|
|
||||||
info.enchant = ref->mBase->mEnchant;
|
info.enchant = ref->mBase->mEnchant;
|
||||||
|
|
||||||
|
if (!info.enchant.empty())
|
||||||
|
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge;
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner");
|
||||||
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
|
||||||
|
|
|
@ -294,7 +294,7 @@ namespace MWGui
|
||||||
if (weaponSlot == invStore.end())
|
if (weaponSlot == invStore.end())
|
||||||
mWindowManager.unsetSelectedWeapon();
|
mWindowManager.unsetSelectedWeapon();
|
||||||
else
|
else
|
||||||
mWindowManager.setSelectedWeapon(*weaponSlot, 100); /// \todo track weapon durability
|
mWindowManager.setSelectedWeapon(*weaponSlot); /// \todo track weapon durability
|
||||||
|
|
||||||
mPreviewDirty = true;
|
mPreviewDirty = true;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
|
||||||
|
|
||||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player);
|
||||||
for (MWWorld::ContainerStoreIterator iter (store.begin());
|
int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor;
|
||||||
|
for (MWWorld::ContainerStoreIterator iter (store.begin(categories));
|
||||||
iter!=store.end(); ++iter)
|
iter!=store.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
|
if (MWWorld::Class::get(*iter).hasItemHealth(*iter))
|
||||||
|
|
|
@ -346,7 +346,7 @@ namespace MWGui
|
||||||
|
|
||||||
store.setSelectedEnchantItem(it);
|
store.setSelectedEnchantItem(it);
|
||||||
spells.setSelectedSpell("");
|
spells.setSelectedSpell("");
|
||||||
mWindowManager.setSelectedEnchantItem(item, 100); /// \todo track charge %
|
mWindowManager.setSelectedEnchantItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,7 @@ namespace MWGui
|
||||||
|
|
||||||
store.setSelectedEnchantItem(it);
|
store.setSelectedEnchantItem(it);
|
||||||
spells.setSelectedSpell("");
|
spells.setSelectedSpell("");
|
||||||
mWindowManager.setSelectedEnchantItem(item, 100); /// \todo track charge %
|
mWindowManager.setSelectedEnchantItem(item);
|
||||||
|
|
||||||
updateSpells();
|
updateSpells();
|
||||||
}
|
}
|
||||||
|
|
|
@ -456,8 +456,8 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info)
|
||||||
if (enchant->mData.mType == ESM::Enchantment::WhenStrikes
|
if (enchant->mData.mType == ESM::Enchantment::WhenStrikes
|
||||||
|| enchant->mData.mType == ESM::Enchantment::WhenUsed)
|
|| enchant->mData.mType == ESM::Enchantment::WhenUsed)
|
||||||
{
|
{
|
||||||
/// \todo store the current enchantment charge somewhere
|
int maxCharge = enchant->mData.mCharge;
|
||||||
int charge = enchant->mData.mCharge;
|
int charge = (info.remainingEnchantCharge == -1) ? maxCharge : info.remainingEnchantCharge;
|
||||||
|
|
||||||
const int chargeWidth = 204;
|
const int chargeWidth = 204;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace MWGui
|
||||||
: isPotion(false)
|
: isPotion(false)
|
||||||
, imageSize(32)
|
, imageSize(32)
|
||||||
, wordWrap(true)
|
, wordWrap(true)
|
||||||
|
, remainingEnchantCharge(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string caption;
|
std::string caption;
|
||||||
|
@ -26,6 +27,7 @@ namespace MWGui
|
||||||
|
|
||||||
// enchantment (for cloth, armor, weapons)
|
// enchantment (for cloth, armor, weapons)
|
||||||
std::string enchant;
|
std::string enchant;
|
||||||
|
int remainingEnchantCharge;
|
||||||
|
|
||||||
// effects (for potions, ingredients)
|
// effects (for potions, ingredients)
|
||||||
Widgets::SpellEffectList effects;
|
Widgets::SpellEffectList effects;
|
||||||
|
|
|
@ -933,14 +933,19 @@ void WindowManager::setSelectedSpell(const std::string& spellId, int successChan
|
||||||
mSpellWindow->setTitle(spell->mName);
|
mSpellWindow->setTitle(spell->mName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
|
void WindowManager::setSelectedEnchantItem(const MWWorld::Ptr& item)
|
||||||
{
|
{
|
||||||
|
const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>()
|
||||||
|
.find(MWWorld::Class::get(item).getEnchantment(item));
|
||||||
|
|
||||||
|
int chargePercent = item.getCellRef().mEnchantmentCharge / static_cast<float>(ench->mData.mCharge) * 100;
|
||||||
mHud->setSelectedEnchantItem(item, chargePercent);
|
mHud->setSelectedEnchantItem(item, chargePercent);
|
||||||
mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
mSpellWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
|
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
|
||||||
{
|
{
|
||||||
|
int durabilityPercent = item.getCellRef().mCharge / static_cast<float>(MWWorld::Class::get(item).getItemMaxHealth(item)) * 100;
|
||||||
mHud->setSelectedWeapon(item, durabilityPercent);
|
mHud->setSelectedWeapon(item, durabilityPercent);
|
||||||
mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
mInventoryWindow->setTitle(MWWorld::Class::get(item).getName(item));
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,8 +179,8 @@ namespace MWGui
|
||||||
virtual void activateQuickKey (int index);
|
virtual void activateQuickKey (int index);
|
||||||
|
|
||||||
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent);
|
virtual void setSelectedSpell(const std::string& spellId, int successChancePercent);
|
||||||
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent);
|
virtual void setSelectedEnchantItem(const MWWorld::Ptr& item);
|
||||||
virtual void setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent);
|
virtual void setSelectedWeapon(const MWWorld::Ptr& item);
|
||||||
virtual void unsetSelectedSpell();
|
virtual void unsetSelectedSpell();
|
||||||
virtual void unsetSelectedWeapon();
|
virtual void unsetSelectedWeapon();
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
|
||||||
mObjects.buildStaticGeometry (*store);
|
mObjects.buildStaticGeometry (*store);
|
||||||
mDebugging->cellAdded(store);
|
mDebugging->cellAdded(store);
|
||||||
if (store->mCell->isExterior())
|
if (store->mCell->isExterior())
|
||||||
mTerrainManager->cellAdded(store);
|
mTerrainManager->cellAdded(store);
|
||||||
waterAdded(store);
|
waterAdded(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,25 +529,28 @@ void RenderingManager::applyFog (bool underwater)
|
||||||
|
|
||||||
void RenderingManager::setAmbientMode()
|
void RenderingManager::setAmbientMode()
|
||||||
{
|
{
|
||||||
switch (mAmbientMode)
|
switch (mAmbientMode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
setAmbientColour(mAmbientColor);
|
||||||
setAmbientColour(mAmbientColor);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
setAmbientColour(0.7f*mAmbientColor + 0.3f*ColourValue(1,1,1));
|
||||||
setAmbientColour(0.7f*mAmbientColor + 0.3f*ColourValue(1,1,1));
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
setAmbientColour(ColourValue(1,1,1));
|
||||||
setAmbientColour(ColourValue(1,1,1));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RenderingManager::getTerrainHeightAt(Ogre::Vector3 worldPos)
|
||||||
|
{
|
||||||
|
return mTerrainManager->getTerrainHeightAt(worldPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingManager::configureAmbient(MWWorld::Ptr::CellStore &mCell)
|
void RenderingManager::configureAmbient(MWWorld::Ptr::CellStore &mCell)
|
||||||
{
|
{
|
||||||
mAmbientColor.setAsABGR (mCell.mCell->mAmbi.mAmbient);
|
mAmbientColor.setAsABGR (mCell.mCell->mAmbi.mAmbient);
|
||||||
|
|
|
@ -158,6 +158,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
||||||
|
|
||||||
void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches);
|
void getTriangleBatchCount(unsigned int &triangles, unsigned int &batches);
|
||||||
|
|
||||||
|
float getTerrainHeightAt (Ogre::Vector3 worldPos);
|
||||||
|
|
||||||
void setGlare(bool glare);
|
void setGlare(bool glare);
|
||||||
void skyEnable ();
|
void skyEnable ();
|
||||||
void skyDisable ();
|
void skyDisable ();
|
||||||
|
|
|
@ -71,6 +71,17 @@ namespace MWRender
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
float TerrainManager::getTerrainHeightAt(Vector3 worldPos)
|
||||||
|
{
|
||||||
|
Ogre::Terrain* terrain = NULL;
|
||||||
|
float height = mTerrainGroup.getHeightAtWorldPosition(worldPos, &terrain);
|
||||||
|
if (terrain == NULL)
|
||||||
|
return std::numeric_limits<int>().min();
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
TerrainManager::~TerrainManager()
|
TerrainManager::~TerrainManager()
|
||||||
{
|
{
|
||||||
OGRE_DELETE mTerrainGlobals;
|
OGRE_DELETE mTerrainGlobals;
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace MWRender{
|
||||||
|
|
||||||
void cellAdded(MWWorld::CellStore* store);
|
void cellAdded(MWWorld::CellStore* store);
|
||||||
void cellRemoved(MWWorld::CellStore* store);
|
void cellRemoved(MWWorld::CellStore* store);
|
||||||
|
|
||||||
|
float getTerrainHeightAt (Ogre::Vector3 worldPos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ogre::TerrainGlobalOptions* mTerrainGlobals;
|
Ogre::TerrainGlobalOptions* mTerrainGlobals;
|
||||||
Ogre::TerrainGroup mTerrainGroup;
|
Ogre::TerrainGroup mTerrainGroup;
|
||||||
|
|
|
@ -303,6 +303,8 @@ namespace MWScript
|
||||||
zRot = zRot/60.;
|
zRot = zRot/60.;
|
||||||
}
|
}
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
||||||
|
|
||||||
|
MWWorld::Class::get(ptr).adjustPosition(ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -341,6 +343,7 @@ namespace MWScript
|
||||||
zRot = zRot/60.;
|
zRot = zRot/60.;
|
||||||
}
|
}
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
|
||||||
|
MWWorld::Class::get(ptr).adjustPosition(ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -208,14 +208,21 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::startRandomTitle()
|
void SoundManager::startRandomTitle()
|
||||||
{
|
{
|
||||||
Ogre::StringVectorPtr filelist;
|
Ogre::StringVector filelist;
|
||||||
filelist = mResourceMgr.findResourceNames(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"Music/"+mCurrentPlaylist+"/*");
|
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
||||||
if(!filelist->size())
|
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
||||||
|
{
|
||||||
|
Ogre::StringVectorPtr resourcesInThisGroup = mResourceMgr.findResourceNames(*it,
|
||||||
|
"Music/"+mCurrentPlaylist+"/*");
|
||||||
|
filelist.insert(filelist.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!filelist.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int i = rand()%filelist->size();
|
int i = rand()%filelist.size();
|
||||||
streamMusicFull((*filelist)[i]);
|
streamMusicFull(filelist[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundManager::isMusicPlaying()
|
bool SoundManager::isMusicPlaying()
|
||||||
|
|
|
@ -259,6 +259,10 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("class can't be enchanted");
|
throw std::runtime_error ("class can't be enchanted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Class::adjustPosition(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MWWorld::Ptr
|
MWWorld::Ptr
|
||||||
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
|
Class::copyToCellImpl(const Ptr &ptr, CellStore &cell) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,6 +81,9 @@ namespace MWWorld
|
||||||
///< \return name (the one that is to be presented to the user; not the internal one);
|
///< \return name (the one that is to be presented to the user; not the internal one);
|
||||||
/// can return an empty string.
|
/// can return an empty string.
|
||||||
|
|
||||||
|
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Adjust position to stand on ground. Must be called post model load
|
||||||
|
|
||||||
virtual MWMechanics::CreatureStats& getCreatureStats (const Ptr& ptr) const;
|
virtual MWMechanics::CreatureStats& getCreatureStats (const Ptr& ptr) const;
|
||||||
///< Return creature stats or throw an exception, if class does not have creature stats
|
///< Return creature stats or throw an exception, if class does not have creature stats
|
||||||
/// (default implementation: throw an exceoption)
|
/// (default implementation: throw an exceoption)
|
||||||
|
|
|
@ -88,6 +88,50 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr, OEngine::Physic::PhysicEngine *engine)
|
||||||
|
{
|
||||||
|
const ESM::Position &refpos = ptr.getRefData().getPosition();
|
||||||
|
Ogre::Vector3 position(refpos.pos);
|
||||||
|
|
||||||
|
bool hit=false;
|
||||||
|
bool isInterior = !ptr.getCell()->isExterior();
|
||||||
|
|
||||||
|
OEngine::Physic::PhysicActor *physicActor = engine->getCharacter(ptr.getRefData().getHandle());
|
||||||
|
if (!physicActor)
|
||||||
|
return position;
|
||||||
|
|
||||||
|
bool wasCollisionMode = physicActor->getCollisionMode();
|
||||||
|
|
||||||
|
physicActor->enableCollisions(false);
|
||||||
|
|
||||||
|
Ogre::Vector3 halfExtents = physicActor->getHalfExtents();// + Vector3(1,1,1);
|
||||||
|
|
||||||
|
Ogre::Vector3 newPosition = position;
|
||||||
|
|
||||||
|
traceResults trace; //no initialization needed
|
||||||
|
|
||||||
|
int maxHeight = 400.f;
|
||||||
|
int steps = 100;
|
||||||
|
for (int i=0; i<steps; ++i)
|
||||||
|
{
|
||||||
|
newtrace(&trace, newPosition, newPosition-Ogre::Vector3(0,0,maxHeight / steps), halfExtents, isInterior, engine);
|
||||||
|
if(trace.fraction < 1.0f)
|
||||||
|
hit = true;
|
||||||
|
newPosition = trace.endpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
newPosition = trace.endpos;
|
||||||
|
|
||||||
|
physicActor->setOnGround(hit);
|
||||||
|
physicActor->enableCollisions(wasCollisionMode);
|
||||||
|
|
||||||
|
if (hit)
|
||||||
|
return newPosition;
|
||||||
|
else
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time,
|
static Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time,
|
||||||
bool gravity, OEngine::Physic::PhysicEngine *engine)
|
bool gravity, OEngine::Physic::PhysicEngine *engine)
|
||||||
{
|
{
|
||||||
|
@ -318,7 +362,7 @@ namespace MWWorld
|
||||||
btVector3 btTo = btVector3(to.x, to.y, to.z);
|
btVector3 btTo = btVector3(to.x, to.y, to.z);
|
||||||
|
|
||||||
std::pair<std::string, float> test = mEngine->rayTest(btFrom, btTo);
|
std::pair<std::string, float> test = mEngine->rayTest(btFrom, btTo);
|
||||||
if (test.first == "") {
|
if (test.second == -1) {
|
||||||
return std::make_pair(false, Ogre::Vector3());
|
return std::make_pair(false, Ogre::Vector3());
|
||||||
}
|
}
|
||||||
return std::make_pair(true, ray.getPoint(len * test.second));
|
return std::make_pair(true, ray.getPoint(len * test.second));
|
||||||
|
@ -351,6 +395,10 @@ namespace MWWorld
|
||||||
return MovementSolver::move(ptr, movement, time, gravity, mEngine);
|
return MovementSolver::move(ptr, movement, time, gravity, mEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 PhysicsSystem::traceDown(const MWWorld::Ptr &ptr)
|
||||||
|
{
|
||||||
|
return MovementSolver::traceDown(ptr, mEngine);
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addHeightField (float* heights,
|
void PhysicsSystem::addHeightField (float* heights,
|
||||||
int x, int y, float yoffset,
|
int x, int y, float yoffset,
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace MWWorld
|
||||||
bool toggleCollisionMode();
|
bool toggleCollisionMode();
|
||||||
|
|
||||||
Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity);
|
Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity);
|
||||||
|
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
|
std::pair<float, std::string> getFacedHandle (MWWorld::World& world, float queryDistance);
|
||||||
std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
|
std::vector < std::pair <float, std::string> > getFacedHandles (float queryDistance);
|
||||||
|
|
|
@ -51,6 +51,7 @@ namespace
|
||||||
class_.insertObject(ptr, physics);
|
class_.insertObject(ptr, physics);
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
|
||||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().mScale);
|
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().mScale);
|
||||||
|
class_.adjustPosition(ptr);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +100,6 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
mRendering.removeCell(*iter);
|
mRendering.removeCell(*iter);
|
||||||
//mPhysics->removeObject("Unnamed_43");
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
|
MWBase::Environment::get().getWorld()->getLocalScripts().clearCell (*iter);
|
||||||
MWBase::Environment::get().getMechanicsManager()->drop (*iter);
|
MWBase::Environment::get().getMechanicsManager()->drop (*iter);
|
||||||
|
@ -115,11 +115,6 @@ namespace MWWorld
|
||||||
|
|
||||||
if(result.second)
|
if(result.second)
|
||||||
{
|
{
|
||||||
/// \todo rescale depending on the state of a new GMST
|
|
||||||
insertCell (*cell, true);
|
|
||||||
|
|
||||||
mRendering.cellAdded (cell);
|
|
||||||
|
|
||||||
float verts = ESM::Land::LAND_SIZE;
|
float verts = ESM::Land::LAND_SIZE;
|
||||||
float worldsize = ESM::Land::REAL_SIZE;
|
float worldsize = ESM::Land::REAL_SIZE;
|
||||||
|
|
||||||
|
@ -142,6 +137,11 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \todo rescale depending on the state of a new GMST
|
||||||
|
insertCell (*cell, true);
|
||||||
|
|
||||||
|
mRendering.cellAdded (cell);
|
||||||
|
|
||||||
mRendering.configureAmbient(*cell);
|
mRendering.configureAmbient(*cell);
|
||||||
mRendering.requestMap(cell);
|
mRendering.requestMap(cell);
|
||||||
mRendering.configureAmbient(*cell);
|
mRendering.configureAmbient(*cell);
|
||||||
|
@ -165,6 +165,8 @@ namespace MWWorld
|
||||||
float y = Ogre::Radian(pos.rot[1]).valueDegrees();
|
float y = Ogre::Radian(pos.rot[1]).valueDegrees();
|
||||||
float z = Ogre::Radian(pos.rot[2]).valueDegrees();
|
float z = Ogre::Radian(pos.rot[2]).valueDegrees();
|
||||||
world->rotateObject(player, x, y, z);
|
world->rotateObject(player, x, y, z);
|
||||||
|
|
||||||
|
MWWorld::Class::get(player).adjustPosition(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWBase::MechanicsManager *mechMgr =
|
MWBase::MechanicsManager *mechMgr =
|
||||||
|
@ -355,6 +357,8 @@ namespace MWWorld
|
||||||
float y = Ogre::Radian(position.rot[1]).valueDegrees();
|
float y = Ogre::Radian(position.rot[1]).valueDegrees();
|
||||||
float z = Ogre::Radian(position.rot[2]).valueDegrees();
|
float z = Ogre::Radian(position.rot[2]).valueDegrees();
|
||||||
world->rotateObject(world->getPlayer().getPlayer(), x, y, z);
|
world->rotateObject(world->getPlayer().getPlayer(), x, y, z);
|
||||||
|
|
||||||
|
MWWorld::Class::get(world->getPlayer().getPlayer()).adjustPosition(world->getPlayer().getPlayer());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -706,9 +706,11 @@ namespace MWWorld
|
||||||
void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z)
|
void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z)
|
||||||
{
|
{
|
||||||
ESM::Position &pos = ptr.getRefData().getPosition();
|
ESM::Position &pos = ptr.getRefData().getPosition();
|
||||||
|
|
||||||
pos.pos[0] = x;
|
pos.pos[0] = x;
|
||||||
pos.pos[1] = y;
|
pos.pos[1] = y;
|
||||||
pos.pos[2] = z;
|
pos.pos[2] = z;
|
||||||
|
|
||||||
Ogre::Vector3 vec(x, y, z);
|
Ogre::Vector3 vec(x, y, z);
|
||||||
|
|
||||||
CellStore *currCell = ptr.getCell();
|
CellStore *currCell = ptr.getCell();
|
||||||
|
@ -717,7 +719,7 @@ namespace MWWorld
|
||||||
|
|
||||||
if (*currCell != newCell)
|
if (*currCell != newCell)
|
||||||
{
|
{
|
||||||
removeContainerScripts(ptr);
|
removeContainerScripts(ptr);
|
||||||
|
|
||||||
if (isPlayer)
|
if (isPlayer)
|
||||||
{
|
{
|
||||||
|
@ -749,7 +751,7 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MWWorld::Ptr copy =
|
MWWorld::Ptr copy =
|
||||||
MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
|
MWWorld::Class::get(ptr).copyToCell(ptr, newCell, pos);
|
||||||
|
|
||||||
mRendering->updateObjectCell(ptr, copy);
|
mRendering->updateObjectCell(ptr, copy);
|
||||||
|
|
||||||
|
@ -779,12 +781,14 @@ namespace MWWorld
|
||||||
bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
|
bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z)
|
||||||
{
|
{
|
||||||
CellStore *cell = ptr.getCell();
|
CellStore *cell = ptr.getCell();
|
||||||
|
|
||||||
if (cell->isExterior()) {
|
if (cell->isExterior()) {
|
||||||
int cellX, cellY;
|
int cellX, cellY;
|
||||||
positionToIndex(x, y, cellX, cellY);
|
positionToIndex(x, y, cellX, cellY);
|
||||||
|
|
||||||
cell = getExterior(cellX, cellY);
|
cell = getExterior(cellX, cellY);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveObject(ptr, *cell, x, y, z);
|
moveObject(ptr, *cell, x, y, z);
|
||||||
|
|
||||||
return cell != ptr.getCell();
|
return cell != ptr.getCell();
|
||||||
|
@ -822,6 +826,33 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::adjustPosition(const Ptr &ptr)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 pos (ptr.getRefData().getPosition().pos[0], ptr.getRefData().getPosition().pos[1], ptr.getRefData().getPosition().pos[2]);
|
||||||
|
|
||||||
|
if(!ptr.getRefData().getBaseNode())
|
||||||
|
{
|
||||||
|
// will be adjusted when Ptr's cell becomes active
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float terrainHeight = mRendering->getTerrainHeightAt(pos);
|
||||||
|
|
||||||
|
if (pos.z < terrainHeight)
|
||||||
|
pos.z = terrainHeight+400; // place slightly above. will snap down to ground with code below
|
||||||
|
|
||||||
|
ptr.getRefData().getPosition().pos[2] = pos.z;
|
||||||
|
|
||||||
|
if (!isFlying(ptr))
|
||||||
|
{
|
||||||
|
Ogre::Vector3 traced = mPhysics->traceDown(ptr);
|
||||||
|
if (traced.z < pos.z)
|
||||||
|
pos.z = traced.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveObject(ptr, pos.x, pos.y, pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
||||||
{
|
{
|
||||||
rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(),
|
rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(),
|
||||||
|
|
|
@ -188,6 +188,9 @@ namespace MWWorld
|
||||||
virtual Ptr searchPtrViaHandle (const std::string& handle);
|
virtual Ptr searchPtrViaHandle (const std::string& handle);
|
||||||
///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found
|
///< Return a pointer to a liveCellRef with the given Ogre handle or Ptr() if not found
|
||||||
|
|
||||||
|
virtual void adjustPosition (const Ptr& ptr);
|
||||||
|
///< Adjust position after load to be on ground. Must be called after model load.
|
||||||
|
|
||||||
virtual void enable (const Ptr& ptr);
|
virtual void enable (const Ptr& ptr);
|
||||||
|
|
||||||
virtual void disable (const Ptr& ptr);
|
virtual void disable (const Ptr& ptr);
|
||||||
|
|
|
@ -323,7 +323,8 @@ namespace Physic
|
||||||
|
|
||||||
mHeightFieldMap [name] = hf;
|
mHeightFieldMap [name] = hf;
|
||||||
|
|
||||||
dynamicsWorld->addRigidBody(body,CollisionType_World,CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal);
|
dynamicsWorld->addRigidBody(body,CollisionType_World|CollisionType_Raycasting,
|
||||||
|
CollisionType_World|CollisionType_ActorInternal|CollisionType_ActorExternal|CollisionType_Raycasting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicEngine::removeHeightField(int x, int y)
|
void PhysicEngine::removeHeightField(int x, int y)
|
||||||
|
|
Loading…
Reference in a new issue