mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-07-04 12:51:34 +00:00
Restore projectiles
This commit is contained in:
parent
c85764b654
commit
de8e5f0db1
27 changed files with 231 additions and 226 deletions
|
@ -23,9 +23,7 @@ add_openmw_dir (mwrender
|
||||||
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
|
actors objects renderingmanager animation rotatecontroller sky npcanimation vismask
|
||||||
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
|
creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation
|
||||||
bulletdebugdraw globalmap characterpreview camera localmap
|
bulletdebugdraw globalmap characterpreview camera localmap
|
||||||
# occlusionquery water shadows
|
# occlusionquery water shadows ripplesimulation refraction terrainstorage
|
||||||
# ripplesimulation refraction
|
|
||||||
# terrainstorage weaponanimation
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
@ -68,8 +66,7 @@ add_openmw_dir (mwworld
|
||||||
cells localscripts customdata inventorystore ptr actionopen actionread
|
cells localscripts customdata inventorystore ptr actionopen actionread
|
||||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||||
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
|
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
|
||||||
contentloader esmloader actiontrap cellreflist cellref physicssystem weather
|
contentloader esmloader actiontrap cellreflist cellref physicssystem weather projectilemanager
|
||||||
# projectilemanager
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwphysics
|
add_openmw_dir (mwphysics
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace Ogre
|
namespace osg
|
||||||
{
|
{
|
||||||
class Vector3;
|
class Vec3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
|
@ -174,8 +174,8 @@ namespace MWBase
|
||||||
virtual bool toggleAI() = 0;
|
virtual bool toggleAI() = 0;
|
||||||
virtual bool isAIActive() = 0;
|
virtual bool isAIActive() = 0;
|
||||||
|
|
||||||
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
|
||||||
virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects) = 0;
|
virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects) = 0;
|
||||||
|
|
||||||
///return the list of actors which are following the given actor
|
///return the list of actors which are following the given actor
|
||||||
/**ie AiFollow is active and the target is the actor**/
|
/**ie AiFollow is active and the target is the actor**/
|
||||||
|
|
|
@ -378,7 +378,7 @@ namespace MWBase
|
||||||
virtual bool isWading(const MWWorld::Ptr &object) const = 0;
|
virtual bool isWading(const MWWorld::Ptr &object) const = 0;
|
||||||
///Is the head of the creature underwater?
|
///Is the head of the creature underwater?
|
||||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
virtual bool isSubmerged(const MWWorld::Ptr &object) const = 0;
|
||||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const = 0;
|
virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const = 0;
|
||||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
|
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
|
||||||
|
|
||||||
virtual void togglePOV() = 0;
|
virtual void togglePOV() = 0;
|
||||||
|
@ -485,7 +485,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId,
|
virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId,
|
||||||
float speed, bool stack, const ESM::EffectList& effects,
|
float speed, bool stack, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection) = 0;
|
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection) = 0;
|
||||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed) = 0;
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed) = 0;
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos) = 0;
|
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos) = 0;
|
||||||
|
|
||||||
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
|
virtual void explodeSpell (const osg::Vec3f& origin, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0;
|
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName) = 0;
|
||||||
|
|
||||||
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
|
||||||
|
|
|
@ -247,7 +247,7 @@ namespace MWClass
|
||||||
if (!victim.getClass().isActor())
|
if (!victim.getClass().isActor())
|
||||||
return; // Can't hit non-actors
|
return; // Can't hit non-actors
|
||||||
|
|
||||||
Ogre::Vector3 hitPosition (result.second.x(), result.second.y(), result.second.z());
|
osg::Vec3f hitPosition (result.second);
|
||||||
|
|
||||||
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
float hitchance = MWMechanics::getHitChance(ptr, victim, ref->mBase->mData.mCombat);
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ namespace MWClass
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||||
|
|
||||||
MWMechanics::diseaseContact(victim, ptr);
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ namespace MWClass
|
||||||
if(name == "left")
|
if(name == "left")
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
||||||
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return 2;
|
return 2;
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
|
@ -736,7 +736,7 @@ namespace MWClass
|
||||||
if(name == "right")
|
if(name == "right")
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
||||||
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return 3;
|
return 3;
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
|
|
|
@ -493,7 +493,7 @@ namespace MWClass
|
||||||
// TODO: Use second to work out the hit angle
|
// TODO: Use second to work out the hit angle
|
||||||
std::pair<MWWorld::Ptr, osg::Vec3f> result = world->getHitContact(ptr, dist);
|
std::pair<MWWorld::Ptr, osg::Vec3f> result = world->getHitContact(ptr, dist);
|
||||||
MWWorld::Ptr victim = result.first;
|
MWWorld::Ptr victim = result.first;
|
||||||
Ogre::Vector3 hitPosition (result.second.x(), result.second.y(), result.second.z());
|
osg::Vec3f hitPosition (result.second);
|
||||||
if(victim.isEmpty()) // Didn't hit anything
|
if(victim.isEmpty()) // Didn't hit anything
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ namespace MWClass
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if (healthdmg && damage > 0)
|
if (healthdmg && damage > 0)
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||||
|
|
||||||
MWMechanics::diseaseContact(victim, ptr);
|
MWMechanics::diseaseContact(victim, ptr);
|
||||||
|
|
||||||
|
@ -1138,7 +1138,7 @@ namespace MWClass
|
||||||
if(name == "left" || name == "right")
|
if(name == "left" || name == "right")
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
||||||
if(world->isSwimming(ptr))
|
if(world->isSwimming(ptr))
|
||||||
return (name == "left") ? "Swim Left" : "Swim Right";
|
return (name == "left") ? "Swim Left" : "Swim Right";
|
||||||
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
|
@ -1175,7 +1175,7 @@ namespace MWClass
|
||||||
if(name == "land")
|
if(name == "land")
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
|
||||||
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr))
|
||||||
return "DefaultLandWater";
|
return "DefaultLandWater";
|
||||||
if(world->isOnGround(ptr))
|
if(world->isOnGround(ptr))
|
||||||
|
|
|
@ -1623,6 +1623,9 @@ namespace MWGui
|
||||||
|
|
||||||
void WindowManager::clear()
|
void WindowManager::clear()
|
||||||
{
|
{
|
||||||
|
if (mLocalMapRender)
|
||||||
|
mLocalMapRender->clear();
|
||||||
|
|
||||||
mMap->clear();
|
mMap->clear();
|
||||||
mQuickKeysMenu->clear();
|
mQuickKeysMenu->clear();
|
||||||
mMessageBoxManager->clear();
|
mMessageBoxManager->clear();
|
||||||
|
|
|
@ -809,7 +809,7 @@ namespace MWMechanics
|
||||||
|
|
||||||
NpcStats &stats = ptr.getClass().getNpcStats(ptr);
|
NpcStats &stats = ptr.getClass().getNpcStats(ptr);
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
bool knockedOutUnderwater = (ctrl->isKnockedOut() && world->isUnderwater(ptr.getCell(), Ogre::Vector3(ptr.getRefData().getPosition().pos)));
|
bool knockedOutUnderwater = (ctrl->isKnockedOut() && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3())));
|
||||||
if((world->isSubmerged(ptr) || knockedOutUnderwater)
|
if((world->isSubmerged(ptr) || knockedOutUnderwater)
|
||||||
&& stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0)
|
&& stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0)
|
||||||
{
|
{
|
||||||
|
@ -1385,11 +1385,11 @@ namespace MWMechanics
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& out)
|
void Actors::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out)
|
||||||
{
|
{
|
||||||
for (PtrActorMap::iterator iter = mActors.begin(); iter != mActors.end(); ++iter)
|
for (PtrActorMap::iterator iter = mActors.begin(); iter != mActors.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (Ogre::Vector3(iter->first.getRefData().getPosition().pos).squaredDistance(position) <= radius*radius)
|
if ((iter->first.getRefData().getPosition().asVec3() - position).length2() <= radius*radius)
|
||||||
out.push_back(iter->first);
|
out.push_back(iter->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1457,7 +1457,7 @@ namespace MWMechanics
|
||||||
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
|
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
|
||||||
std::list<MWWorld::Ptr> list;
|
std::list<MWWorld::Ptr> list;
|
||||||
std::vector<MWWorld::Ptr> neighbors;
|
std::vector<MWWorld::Ptr> neighbors;
|
||||||
Ogre::Vector3 position = Ogre::Vector3(actor.getRefData().getPosition().pos);
|
osg::Vec3f position (actor.getRefData().getPosition().asVec3());
|
||||||
getObjectsInRange(position,
|
getObjectsInRange(position,
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
|
||||||
neighbors); //only care about those within the alarm disance
|
neighbors); //only care about those within the alarm disance
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace MWMechanics
|
||||||
void skipAnimation(const MWWorld::Ptr& ptr);
|
void skipAnimation(const MWWorld::Ptr& ptr);
|
||||||
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);
|
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);
|
||||||
|
|
||||||
void getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& out);
|
void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out);
|
||||||
|
|
||||||
///Returns the list of actors which are following the given actor
|
///Returns the list of actors which are following the given actor
|
||||||
/**ie AiFollow is active and the target is the actor **/
|
/**ie AiFollow is active and the target is the actor **/
|
||||||
|
|
|
@ -64,7 +64,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, AiState& stat
|
||||||
|
|
||||||
// Make all nearby actors also avoid the door
|
// Make all nearby actors also avoid the door
|
||||||
std::vector<MWWorld::Ptr> actors;
|
std::vector<MWWorld::Ptr> actors;
|
||||||
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(pos.pos[0],pos.pos[1],pos.pos[2]),100,actors);
|
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(),100,actors);
|
||||||
for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) {
|
for(std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it) {
|
||||||
if(*it != MWBase::Environment::get().getWorld()->getPlayerPtr()) { //Not the player
|
if(*it != MWBase::Environment::get().getWorld()->getPlayerPtr()) { //Not the player
|
||||||
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
|
MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence();
|
||||||
|
|
|
@ -28,7 +28,7 @@ float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg:
|
||||||
return std::atan2((normal * (v1 ^ v2)), (v1 * v2));
|
return std::atan2((normal * (v1 ^ v2)), (v1 * v2));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const Ogre::Vector3& hitPosition)
|
bool applyEnchantment (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition)
|
||||||
{
|
{
|
||||||
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
|
std::string enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : "";
|
||||||
if (!enchantmentName.empty())
|
if (!enchantmentName.empty())
|
||||||
|
@ -166,7 +166,7 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
void projectileHit(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, MWWorld::Ptr weapon, const MWWorld::Ptr &projectile,
|
void projectileHit(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, MWWorld::Ptr weapon, const MWWorld::Ptr &projectile,
|
||||||
const Ogre::Vector3& hitPosition)
|
const osg::Vec3f& hitPosition)
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
const MWWorld::Store<ESM::GameSetting> &gmst = world->getStore().get<ESM::GameSetting>();
|
||||||
|
@ -221,7 +221,7 @@ namespace MWMechanics
|
||||||
appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition);
|
appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition);
|
||||||
|
|
||||||
if (damage > 0)
|
if (damage > 0)
|
||||||
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, osg::Vec3f(hitPosition.x, hitPosition.y, hitPosition.z));
|
MWBase::Environment::get().getWorld()->spawnBloodEffect(victim, hitPosition);
|
||||||
|
|
||||||
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
|
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
|
||||||
if (victim != MWBase::Environment::get().getWorld()->getPlayerPtr()
|
if (victim != MWBase::Environment::get().getWorld()->getPlayerPtr()
|
||||||
|
|
|
@ -15,7 +15,7 @@ void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker
|
||||||
/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt
|
/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt
|
||||||
/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor
|
/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor
|
||||||
void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
|
||||||
const Ogre::Vector3& hitPosition);
|
const osg::Vec3f& hitPosition);
|
||||||
|
|
||||||
/// Get the chance (in percent) for \a attacker to successfully hit \a victim with a given weapon skill value
|
/// Get the chance (in percent) for \a attacker to successfully hit \a victim with a given weapon skill value
|
||||||
float getHitChance (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue);
|
float getHitChance (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue);
|
||||||
|
|
|
@ -1059,14 +1059,14 @@ namespace MWMechanics
|
||||||
// Find all the actors within the alarm radius
|
// Find all the actors within the alarm radius
|
||||||
std::vector<MWWorld::Ptr> neighbors;
|
std::vector<MWWorld::Ptr> neighbors;
|
||||||
|
|
||||||
Ogre::Vector3 from = Ogre::Vector3(player.getRefData().getPosition().pos);
|
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
||||||
|
|
||||||
mActors.getObjectsInRange(from, radius, neighbors);
|
mActors.getObjectsInRange(from, radius, neighbors);
|
||||||
|
|
||||||
// victim should be considered even beyond alarm radius
|
// victim should be considered even beyond alarm radius
|
||||||
if (!victim.isEmpty() && from.squaredDistance(Ogre::Vector3(victim.getRefData().getPosition().pos)) > radius*radius)
|
if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius*radius)
|
||||||
neighbors.push_back(victim);
|
neighbors.push_back(victim);
|
||||||
|
|
||||||
// Did anyone see it?
|
// Did anyone see it?
|
||||||
|
@ -1149,13 +1149,13 @@ namespace MWMechanics
|
||||||
|
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
Ogre::Vector3 from = Ogre::Vector3(player.getRefData().getPosition().pos);
|
osg::Vec3f from (player.getRefData().getPosition().asVec3());
|
||||||
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
float radius = esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getFloat();
|
||||||
|
|
||||||
mActors.getObjectsInRange(from, radius, neighbors);
|
mActors.getObjectsInRange(from, radius, neighbors);
|
||||||
|
|
||||||
// victim should be considered even beyond alarm radius
|
// victim should be considered even beyond alarm radius
|
||||||
if (!victim.isEmpty() && from.squaredDistance(Ogre::Vector3(victim.getRefData().getPosition().pos)) > radius*radius)
|
if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius*radius)
|
||||||
neighbors.push_back(victim);
|
neighbors.push_back(victim);
|
||||||
|
|
||||||
int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId();
|
int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId();
|
||||||
|
@ -1430,13 +1430,13 @@ namespace MWMechanics
|
||||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "attack");
|
MWBase::Environment::get().getDialogueManager()->say(ptr, "attack");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::getObjectsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects)
|
void MechanicsManager::getObjectsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects)
|
||||||
{
|
{
|
||||||
mActors.getObjectsInRange(position, radius, objects);
|
mActors.getObjectsInRange(position, radius, objects);
|
||||||
mObjects.getObjectsInRange(position, radius, objects);
|
mObjects.getObjectsInRange(position, radius, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MechanicsManager::getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects)
|
void MechanicsManager::getActorsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects)
|
||||||
{
|
{
|
||||||
mActors.getObjectsInRange(position, radius, objects);
|
mActors.getObjectsInRange(position, radius, objects);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,8 +145,8 @@ namespace MWMechanics
|
||||||
/// paused we may want to do it manually (after equipping permanent enchantment)
|
/// paused we may want to do it manually (after equipping permanent enchantment)
|
||||||
virtual void updateMagicEffects (const MWWorld::Ptr& ptr);
|
virtual void updateMagicEffects (const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects);
|
virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& objects);
|
||||||
virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects);
|
virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector<MWWorld::Ptr> &objects);
|
||||||
|
|
||||||
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
|
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
|
||||||
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
virtual std::list<int> getActorsFollowingIndices(const MWWorld::Ptr& actor);
|
||||||
|
|
|
@ -92,11 +92,11 @@ void Objects::skipAnimation(const MWWorld::Ptr& ptr)
|
||||||
iter->second->skipAnim();
|
iter->second->skipAnim();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& out)
|
void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out)
|
||||||
{
|
{
|
||||||
for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
|
for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (Ogre::Vector3(iter->first.getRefData().getPosition().pos).squaredDistance(position) <= radius*radius)
|
if ((position - iter->first.getRefData().getPosition().asVec3()).length2() <= radius*radius)
|
||||||
out.push_back(iter->first);
|
out.push_back(iter->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace MWMechanics
|
||||||
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
|
||||||
void skipAnimation(const MWWorld::Ptr& ptr);
|
void skipAnimation(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& out);
|
void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -779,7 +779,7 @@ namespace MWMechanics
|
||||||
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
|
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
|
||||||
false, enchantment->mEffects, mCaster, mSourceName,
|
false, enchantment->mEffects, mCaster, mSourceName,
|
||||||
// Not needed, enchantments can only be cast by actors
|
// Not needed, enchantments can only be cast by actors
|
||||||
Ogre::Vector3(1,0,0));
|
osg::Vec3f(1,0,0));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -861,13 +861,13 @@ namespace MWMechanics
|
||||||
getProjectileInfo(spell->mEffects, projectileModel, sound, speed);
|
getProjectileInfo(spell->mEffects, projectileModel, sound, speed);
|
||||||
if (!projectileModel.empty())
|
if (!projectileModel.empty())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 fallbackDirection (0,1,0);
|
osg::Vec3f fallbackDirection (0,1,0);
|
||||||
// Fall back to a "caster to target" direction if we have no other means of determining it
|
// Fall back to a "caster to target" direction if we have no other means of determining it
|
||||||
// (e.g. when cast by a non-actor)
|
// (e.g. when cast by a non-actor)
|
||||||
if (!mTarget.isEmpty())
|
if (!mTarget.isEmpty())
|
||||||
fallbackDirection =
|
fallbackDirection =
|
||||||
Ogre::Vector3(mTarget.getRefData().getPosition().pos)-
|
osg::Vec3f(mTarget.getRefData().getPosition().asVec3())-
|
||||||
Ogre::Vector3(mCaster.getRefData().getPosition().pos);
|
osg::Vec3f(mCaster.getRefData().getPosition().asVec3());
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
|
MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed,
|
||||||
false, spell->mEffects, mCaster, mSourceName, fallbackDirection);
|
false, spell->mEffects, mCaster, mSourceName, fallbackDirection);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace MWMechanics
|
||||||
bool mStack;
|
bool mStack;
|
||||||
std::string mId; // ID of spell, potion, item etc
|
std::string mId; // ID of spell, potion, item etc
|
||||||
std::string mSourceName; // Display name for spell, potion, etc
|
std::string mSourceName; // Display name for spell, potion, etc
|
||||||
Ogre::Vector3 mHitPosition; // Used for spawning area orb
|
osg::Vec3f mHitPosition; // Used for spawning area orb
|
||||||
bool mAlwaysSucceed; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false)
|
bool mAlwaysSucceed; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -748,7 +748,7 @@ namespace MWPhysics
|
||||||
const btCollisionObject* mMe;
|
const btCollisionObject* mMe;
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore, int mask)
|
PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore, int mask, int group)
|
||||||
{
|
{
|
||||||
btVector3 btFrom = toBullet(from);
|
btVector3 btFrom = toBullet(from);
|
||||||
btVector3 btTo = toBullet(to);
|
btVector3 btTo = toBullet(to);
|
||||||
|
@ -762,7 +762,7 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
|
|
||||||
ClosestNotMeRayResultCallback resultCallback(me, btFrom, btTo);
|
ClosestNotMeRayResultCallback resultCallback(me, btFrom, btTo);
|
||||||
resultCallback.m_collisionFilterGroup = 0xff;
|
resultCallback.m_collisionFilterGroup = group;
|
||||||
resultCallback.m_collisionFilterMask = mask;
|
resultCallback.m_collisionFilterMask = mask;
|
||||||
|
|
||||||
mCollisionWorld->rayTest(btFrom, btTo, resultCallback);
|
mCollisionWorld->rayTest(btFrom, btTo, resultCallback);
|
||||||
|
@ -860,6 +860,15 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::Ptr &actor)
|
||||||
|
{
|
||||||
|
Actor* physactor = getActor(actor);
|
||||||
|
if (physactor)
|
||||||
|
return physactor->getHalfExtents();
|
||||||
|
else
|
||||||
|
return osg::Vec3f();
|
||||||
|
}
|
||||||
|
|
||||||
class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -1128,7 +1137,7 @@ namespace MWPhysics
|
||||||
if (effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()
|
if (effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()
|
||||||
&& cell->getCell()->hasWater()
|
&& cell->getCell()->hasWater()
|
||||||
&& !world->isUnderwater(iter->first.getCell(),
|
&& !world->isUnderwater(iter->first.getCell(),
|
||||||
Ogre::Vector3(iter->first.getRefData().getPosition().pos)))
|
osg::Vec3f(iter->first.getRefData().getPosition().asVec3())))
|
||||||
waterCollision = true;
|
waterCollision = true;
|
||||||
|
|
||||||
ActorMap::iterator foundActor = mActors.find(iter->first);
|
ActorMap::iterator foundActor = mActors.find(iter->first);
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
/// @param me Optional, a Ptr to ignore in the list of results
|
/// @param me Optional, a Ptr to ignore in the list of results
|
||||||
RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore = MWWorld::Ptr(), int mask =
|
RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore = MWWorld::Ptr(), int mask =
|
||||||
CollisionType_World|CollisionType_HeightMap|CollisionType_Actor);
|
CollisionType_World|CollisionType_HeightMap|CollisionType_Actor, int group=0xff);
|
||||||
|
|
||||||
RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius);
|
RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius);
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool isOnGround (const MWWorld::Ptr& actor);
|
bool isOnGround (const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
|
osg::Vec3f getHalfExtents(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
|
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
|
||||||
/// be overwritten. Valid until the next call to applyQueuedMovement.
|
/// be overwritten. Valid until the next call to applyQueuedMovement.
|
||||||
void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity);
|
void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity);
|
||||||
|
|
|
@ -937,7 +937,7 @@ namespace MWScript
|
||||||
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr (targetId, false);
|
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr (targetId, false);
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(ptr, target);
|
MWMechanics::CastSpell cast(ptr, target);
|
||||||
cast.mHitPosition = Ogre::Vector3(target.getRefData().getPosition().pos);
|
cast.mHitPosition = target.getRefData().getPosition().asVec3();
|
||||||
cast.mAlwaysSucceed = true;
|
cast.mAlwaysSucceed = true;
|
||||||
cast.cast(spell);
|
cast.cast(spell);
|
||||||
}
|
}
|
||||||
|
@ -955,7 +955,7 @@ namespace MWScript
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(ptr, ptr);
|
MWMechanics::CastSpell cast(ptr, ptr);
|
||||||
cast.mHitPosition = Ogre::Vector3(ptr.getRefData().getPosition().pos);
|
cast.mHitPosition = ptr.getRefData().getPosition().asVec3();
|
||||||
cast.mAlwaysSucceed = true;
|
cast.mAlwaysSucceed = true;
|
||||||
cast.cast(spell);
|
cast.cast(spell);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ namespace MWWorld
|
||||||
|
|
||||||
void ActionTrap::executeImp(const Ptr &actor)
|
void ActionTrap::executeImp(const Ptr &actor)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 actorPosition(actor.getRefData().getPosition().pos);
|
osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3());
|
||||||
Ogre::Vector3 trapPosition(mTrapSource.getRefData().getPosition().pos);
|
osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3());
|
||||||
float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance();
|
float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance();
|
||||||
|
|
||||||
// GUI calcs if object in activation distance include object and player geometry
|
// GUI calcs if object in activation distance include object and player geometry
|
||||||
|
@ -20,7 +20,7 @@ namespace MWWorld
|
||||||
// to open door/container.
|
// to open door/container.
|
||||||
// Note, can't just detonate the trap at the trapped object's location and use the blast
|
// Note, can't just detonate the trap at the trapped object's location and use the blast
|
||||||
// radius, because for most trap spells this is 1 foot, much less than the activation distance.
|
// radius, because for most trap spells this is 1 foot, much less than the activation distance.
|
||||||
if (trapPosition.distance(actorPosition) < (activationDistance * fudgeFactor))
|
if ((trapPosition - actorPosition).length() < (activationDistance * fudgeFactor))
|
||||||
{
|
{
|
||||||
// assume actor touched trap
|
// assume actor touched trap
|
||||||
MWMechanics::CastSpell cast(mTrapSource, actor);
|
MWMechanics::CastSpell cast(mTrapSource, actor);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "projectilemanager.hpp"
|
#include "projectilemanager.hpp"
|
||||||
|
|
||||||
#include <OgreSceneManager.h>
|
#include <osg/PositionAttitudeTransform>
|
||||||
#include <OgreSceneNode.h>
|
|
||||||
|
|
||||||
#include <libs/openengine/bullet/physic.hpp>
|
|
||||||
|
|
||||||
#include <components/esm/projectilestate.hpp>
|
#include <components/esm/projectilestate.hpp>
|
||||||
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
#include <components/sceneutil/controller.hpp>
|
||||||
|
|
||||||
#include "../mwworld/manualref.hpp"
|
#include "../mwworld/manualref.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
@ -22,72 +22,70 @@
|
||||||
|
|
||||||
#include "../mwrender/effectmanager.hpp"
|
#include "../mwrender/effectmanager.hpp"
|
||||||
#include "../mwrender/animation.hpp"
|
#include "../mwrender/animation.hpp"
|
||||||
#include "../mwrender/renderconst.hpp"
|
#include "../mwrender/vismask.hpp"
|
||||||
|
|
||||||
#include "../mwsound/sound.hpp"
|
#include "../mwsound/sound.hpp"
|
||||||
|
|
||||||
|
#include "../mwphysics/physicssystem.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
|
||||||
ProjectileManager::ProjectileManager(Ogre::SceneManager* sceneMgr, OEngine::Physic::PhysicEngine &engine)
|
ProjectileManager::ProjectileManager(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWPhysics::PhysicsSystem* physics)
|
||||||
: mPhysEngine(engine)
|
: mParent(parent)
|
||||||
, mSceneMgr(sceneMgr)
|
, mResourceSystem(resourceSystem)
|
||||||
|
, mPhysics(physics)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileManager::createModel(State &state, const std::string &model)
|
void ProjectileManager::createModel(State &state, const std::string &model)
|
||||||
{
|
{
|
||||||
state.mObject = NifOgre::Loader::createObjects(state.mNode, model);
|
state.mNode = new osg::PositionAttitudeTransform;
|
||||||
for(size_t i = 0;i < state.mObject->mControllers.size();i++)
|
state.mNode->setNodeMask(MWRender::Mask_Effect);
|
||||||
{
|
mParent->addChild(state.mNode);
|
||||||
if(state.mObject->mControllers[i].getSource().isNull())
|
|
||||||
state.mObject->mControllers[i].setSource(Ogre::SharedPtr<MWRender::EffectAnimationTime> (new MWRender::EffectAnimationTime()));
|
mResourceSystem->getSceneManager()->createInstance(model, state.mNode);
|
||||||
|
|
||||||
|
state.mEffectAnimationTime.reset(new MWRender::EffectAnimationTime);
|
||||||
|
|
||||||
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor (state.mEffectAnimationTime);
|
||||||
|
state.mNode->accept(assignVisitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Effects,
|
void ProjectileManager::update(State& state, float duration)
|
||||||
MWRender::RQG_Main, MWRender::RQG_Alpha, 0.f, false, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProjectileManager::update(NifOgre::ObjectScenePtr object, float duration)
|
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < object->mControllers.size() ;i++)
|
state.mEffectAnimationTime->addTime(duration);
|
||||||
{
|
|
||||||
MWRender::EffectAnimationTime* value = dynamic_cast<MWRender::EffectAnimationTime*>(object->mControllers[i].getSource().get());
|
|
||||||
if (value)
|
|
||||||
value->addTime(duration);
|
|
||||||
|
|
||||||
object->mControllers[i].update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileManager::launchMagicBolt(const std::string &model, const std::string &sound,
|
void ProjectileManager::launchMagicBolt(const std::string &model, const std::string &sound,
|
||||||
const std::string &spellId, float speed, bool stack,
|
const std::string &spellId, float speed, bool stack,
|
||||||
const ESM::EffectList &effects, const Ptr &caster, const std::string &sourceName,
|
const ESM::EffectList &effects, const Ptr &caster, const std::string &sourceName,
|
||||||
const Ogre::Vector3& fallbackDirection)
|
const osg::Vec3f& fallbackDirection)
|
||||||
{
|
{
|
||||||
float height = 0;
|
float height = 0;
|
||||||
if (OEngine::Physic::PhysicActor* actor = mPhysEngine.getCharacter(caster.getRefData().getHandle()))
|
|
||||||
height = actor->getHalfExtents().z * 2 * 0.75f; // Spawn at 0.75 * ActorHeight
|
|
||||||
|
|
||||||
Ogre::Vector3 pos(caster.getRefData().getPosition().pos);
|
height += mPhysics->getHalfExtents(caster).z() * 2.f * 0.75f; // Spawn at 0.75 * ActorHeight
|
||||||
pos.z += height;
|
|
||||||
|
osg::Vec3f pos(caster.getRefData().getPosition().asVec3());
|
||||||
|
pos.z() += height;
|
||||||
|
|
||||||
if (MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos)) // Underwater casting not possible
|
if (MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos)) // Underwater casting not possible
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Ogre::Quaternion orient;
|
osg::Quat orient;
|
||||||
if (caster.getClass().isActor())
|
if (caster.getClass().isActor())
|
||||||
orient = Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
orient = osg::Quat(caster.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
|
||||||
Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
|
* osg::Quat(caster.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));
|
||||||
else
|
else
|
||||||
orient = Ogre::Vector3::UNIT_Y.getRotationTo(fallbackDirection);
|
orient.makeRotate(osg::Vec3f(0,1,0), osg::Vec3f(fallbackDirection));
|
||||||
|
|
||||||
MagicBoltState state;
|
MagicBoltState state;
|
||||||
state.mSourceName = sourceName;
|
state.mSourceName = sourceName;
|
||||||
state.mId = model;
|
state.mId = model;
|
||||||
state.mSpellId = spellId;
|
state.mSpellId = spellId;
|
||||||
state.mCasterHandle = caster.getRefData().getHandle();
|
state.mCasterHandle = caster;
|
||||||
if (caster.getClass().isActor())
|
if (caster.getClass().isActor())
|
||||||
state.mActorId = caster.getClass().getCreatureStats(caster).getActorId();
|
state.mActorId = caster.getClass().getCreatureStats(caster).getActorId();
|
||||||
else
|
else
|
||||||
|
@ -107,8 +105,9 @@ namespace MWWorld
|
||||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), model);
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), model);
|
||||||
MWWorld::Ptr ptr = ref.getPtr();
|
MWWorld::Ptr ptr = ref.getPtr();
|
||||||
|
|
||||||
state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient);
|
|
||||||
createModel(state, ptr.getClass().getModel(ptr));
|
createModel(state, ptr.getClass().getModel(ptr));
|
||||||
|
state.mNode->setPosition(pos);
|
||||||
|
state.mNode->setAttitude(orient);
|
||||||
|
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
state.mSound = sndMgr->playManualSound3D(pos, sound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
|
state.mSound = sndMgr->playManualSound3D(pos, sound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
|
||||||
|
@ -116,20 +115,21 @@ namespace MWWorld
|
||||||
mMagicBolts.push_back(state);
|
mMagicBolts.push_back(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectileManager::launchProjectile(Ptr actor, Ptr projectile, const Ogre::Vector3 &pos,
|
void ProjectileManager::launchProjectile(Ptr actor, Ptr projectile, const osg::Vec3f &pos, const osg::Quat &orient, Ptr bow, float speed)
|
||||||
const Ogre::Quaternion &orient, Ptr bow, float speed)
|
|
||||||
{
|
{
|
||||||
ProjectileState state;
|
ProjectileState state;
|
||||||
state.mActorId = actor.getClass().getCreatureStats(actor).getActorId();
|
state.mActorId = actor.getClass().getCreatureStats(actor).getActorId();
|
||||||
state.mBowId = bow.getCellRef().getRefId();
|
state.mBowId = bow.getCellRef().getRefId();
|
||||||
state.mVelocity = orient.yAxis() * speed;
|
state.mVelocity = orient * osg::Vec3f(0,1,0) * speed;
|
||||||
state.mId = projectile.getCellRef().getRefId();
|
state.mId = projectile.getCellRef().getRefId();
|
||||||
|
state.mCasterHandle = actor;
|
||||||
|
|
||||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId());
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId());
|
||||||
MWWorld::Ptr ptr = ref.getPtr();
|
MWWorld::Ptr ptr = ref.getPtr();
|
||||||
|
|
||||||
state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient);
|
|
||||||
createModel(state, ptr.getClass().getModel(ptr));
|
createModel(state, ptr.getClass().getModel(ptr));
|
||||||
|
state.mNode->setPosition(pos);
|
||||||
|
state.mNode->setAttitude(orient);
|
||||||
|
|
||||||
mProjectiles.push_back(state);
|
mProjectiles.push_back(state);
|
||||||
}
|
}
|
||||||
|
@ -144,60 +144,46 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
for (std::vector<MagicBoltState>::iterator it = mMagicBolts.begin(); it != mMagicBolts.end();)
|
for (std::vector<MagicBoltState>::iterator it = mMagicBolts.begin(); it != mMagicBolts.end();)
|
||||||
{
|
{
|
||||||
Ogre::Quaternion orient = it->mNode->getOrientation();
|
osg::Quat orient = it->mNode->getAttitude();
|
||||||
static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
static float fTargetSpellMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("fTargetSpellMaxSpeed")->getFloat();
|
.find("fTargetSpellMaxSpeed")->getFloat();
|
||||||
float speed = fTargetSpellMaxSpeed * it->mSpeed;
|
float speed = fTargetSpellMaxSpeed * it->mSpeed;
|
||||||
|
|
||||||
Ogre::Vector3 direction = orient.yAxis();
|
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
||||||
direction.normalise();
|
direction.normalize();
|
||||||
Ogre::Vector3 pos(it->mNode->getPosition());
|
osg::Vec3f pos(it->mNode->getPosition());
|
||||||
Ogre::Vector3 newPos = pos + direction * duration * speed;
|
osg::Vec3f newPos = pos + direction * duration * speed;
|
||||||
|
|
||||||
if (it->mSound.get())
|
if (it->mSound.get())
|
||||||
it->mSound->setPosition(newPos);
|
it->mSound->setPosition(newPos);
|
||||||
|
|
||||||
it->mNode->setPosition(newPos);
|
it->mNode->setPosition(newPos);
|
||||||
|
|
||||||
update(it->mObject, duration);
|
update(*it, duration);
|
||||||
|
|
||||||
|
MWWorld::Ptr caster = it->getCaster();
|
||||||
|
|
||||||
// Check for impact
|
// Check for impact
|
||||||
// TODO: use a proper btRigidBody / btGhostObject?
|
// TODO: use a proper btRigidBody / btGhostObject?
|
||||||
btVector3 from(pos.x, pos.y, pos.z);
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, 0xff, MWPhysics::CollisionType_Projectile);
|
||||||
btVector3 to(newPos.x, newPos.y, newPos.z);
|
|
||||||
|
|
||||||
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile);
|
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
if (result.mHit)
|
||||||
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
|
||||||
{
|
{
|
||||||
MWWorld::Ptr obstacle = MWBase::Environment::get().getWorld()->searchPtrViaHandle(cIt->second);
|
hit = true;
|
||||||
|
if (result.mHitObject.isEmpty())
|
||||||
MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaHandle(it->mCasterHandle);
|
|
||||||
if (caster.isEmpty())
|
|
||||||
caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->mActorId);
|
|
||||||
|
|
||||||
if (!obstacle.isEmpty() && obstacle == caster)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (caster.isEmpty())
|
|
||||||
caster = obstacle;
|
|
||||||
|
|
||||||
if (obstacle.isEmpty())
|
|
||||||
{
|
{
|
||||||
// Terrain
|
// terrain
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MWMechanics::CastSpell cast(caster, obstacle);
|
MWMechanics::CastSpell cast(caster, result.mHitObject);
|
||||||
cast.mHitPosition = pos;
|
cast.mHitPosition = pos;
|
||||||
cast.mId = it->mSpellId;
|
cast.mId = it->mSpellId;
|
||||||
cast.mSourceName = it->mSourceName;
|
cast.mSourceName = it->mSourceName;
|
||||||
cast.mStack = it->mStack;
|
cast.mStack = it->mStack;
|
||||||
cast.inflict(obstacle, caster, it->mEffects, ESM::RT_Target, false, true);
|
cast.inflict(result.mHitObject, caster, it->mEffects, ESM::RT_Target, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hit = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explodes when hitting water
|
// Explodes when hitting water
|
||||||
|
@ -206,12 +192,11 @@ namespace MWWorld
|
||||||
|
|
||||||
if (hit)
|
if (hit)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->mActorId);
|
|
||||||
MWBase::Environment::get().getWorld()->explodeSpell(pos, it->mEffects, caster, ESM::RT_Target, it->mSpellId, it->mSourceName);
|
MWBase::Environment::get().getWorld()->explodeSpell(pos, it->mEffects, caster, ESM::RT_Target, it->mSpellId, it->mSourceName);
|
||||||
|
|
||||||
MWBase::Environment::get().getSoundManager()->stopSound(it->mSound);
|
MWBase::Environment::get().getSoundManager()->stopSound(it->mSound);
|
||||||
|
|
||||||
mSceneMgr->destroySceneNode(it->mNode);
|
mParent->removeChild(it->mNode);
|
||||||
|
|
||||||
it = mMagicBolts.erase(it);
|
it = mMagicBolts.erase(it);
|
||||||
continue;
|
continue;
|
||||||
|
@ -227,34 +212,26 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
// gravity constant - must be way lower than the gravity affecting actors, since we're not
|
// gravity constant - must be way lower than the gravity affecting actors, since we're not
|
||||||
// simulating aerodynamics at all
|
// simulating aerodynamics at all
|
||||||
it->mVelocity -= Ogre::Vector3(0, 0, 627.2f * 0.1f) * duration;
|
it->mVelocity -= osg::Vec3f(0, 0, 627.2f * 0.1f) * duration;
|
||||||
|
|
||||||
Ogre::Vector3 pos(it->mNode->getPosition());
|
osg::Vec3f pos(it->mNode->getPosition());
|
||||||
Ogre::Vector3 newPos = pos + it->mVelocity * duration;
|
osg::Vec3f newPos = pos + it->mVelocity * duration;
|
||||||
|
|
||||||
Ogre::Quaternion orient = Ogre::Vector3::UNIT_Y.getRotationTo(it->mVelocity);
|
osg::Quat orient;
|
||||||
it->mNode->setOrientation(orient);
|
orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity);
|
||||||
|
it->mNode->setAttitude(orient);
|
||||||
it->mNode->setPosition(newPos);
|
it->mNode->setPosition(newPos);
|
||||||
|
|
||||||
update(it->mObject, duration);
|
update(*it, duration);
|
||||||
|
|
||||||
|
MWWorld::Ptr caster = it->getCaster();
|
||||||
|
|
||||||
// Check for impact
|
// Check for impact
|
||||||
// TODO: use a proper btRigidBody / btGhostObject?
|
// TODO: use a proper btRigidBody / btGhostObject?
|
||||||
btVector3 from(pos.x, pos.y, pos.z);
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, 0xff, MWPhysics::CollisionType_Projectile);
|
||||||
btVector3 to(newPos.x, newPos.y, newPos.z);
|
|
||||||
std::vector<std::pair<float, std::string> > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile);
|
|
||||||
bool hit=false;
|
|
||||||
|
|
||||||
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt)
|
if (result.mHit)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr obstacle = MWBase::Environment::get().getWorld()->searchPtrViaHandle(cIt->second);
|
|
||||||
|
|
||||||
MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->mActorId);
|
|
||||||
|
|
||||||
// Arrow intersects with player immediately after shooting :/
|
|
||||||
if (obstacle == caster)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), it->mId);
|
MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), it->mId);
|
||||||
|
|
||||||
// Try to get a Ptr to the bow that was used. It might no longer exist.
|
// Try to get a Ptr to the bow that was used. It might no longer exist.
|
||||||
|
@ -268,15 +245,11 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
if (caster.isEmpty())
|
if (caster.isEmpty())
|
||||||
caster = obstacle;
|
caster = result.mHitObject;
|
||||||
|
|
||||||
MWMechanics::projectileHit(caster, obstacle, bow, projectileRef.getPtr(), pos + (newPos - pos) * cIt->first);
|
MWMechanics::projectileHit(caster, result.mHitObject, bow, projectileRef.getPtr(), result.mHitPos);
|
||||||
|
|
||||||
hit = true;
|
mParent->removeChild(it->mNode);
|
||||||
}
|
|
||||||
if (hit)
|
|
||||||
{
|
|
||||||
mSceneMgr->destroySceneNode(it->mNode);
|
|
||||||
|
|
||||||
it = mProjectiles.erase(it);
|
it = mProjectiles.erase(it);
|
||||||
continue;
|
continue;
|
||||||
|
@ -290,13 +263,13 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
for (std::vector<ProjectileState>::iterator it = mProjectiles.begin(); it != mProjectiles.end(); ++it)
|
for (std::vector<ProjectileState>::iterator it = mProjectiles.begin(); it != mProjectiles.end(); ++it)
|
||||||
{
|
{
|
||||||
mSceneMgr->destroySceneNode(it->mNode);
|
mParent->removeChild(it->mNode);
|
||||||
}
|
}
|
||||||
mProjectiles.clear();
|
mProjectiles.clear();
|
||||||
for (std::vector<MagicBoltState>::iterator it = mMagicBolts.begin(); it != mMagicBolts.end(); ++it)
|
for (std::vector<MagicBoltState>::iterator it = mMagicBolts.begin(); it != mMagicBolts.end(); ++it)
|
||||||
{
|
{
|
||||||
|
mParent->removeChild(it->mNode);
|
||||||
MWBase::Environment::get().getSoundManager()->stopSound(it->mSound);
|
MWBase::Environment::get().getSoundManager()->stopSound(it->mSound);
|
||||||
mSceneMgr->destroySceneNode(it->mNode);
|
|
||||||
}
|
}
|
||||||
mMagicBolts.clear();
|
mMagicBolts.clear();
|
||||||
}
|
}
|
||||||
|
@ -309,8 +282,8 @@ namespace MWWorld
|
||||||
|
|
||||||
ESM::ProjectileState state;
|
ESM::ProjectileState state;
|
||||||
state.mId = it->mId;
|
state.mId = it->mId;
|
||||||
state.mPosition = it->mNode->getPosition();
|
state.mPosition = ESM::Vector3(osg::Vec3f(it->mNode->getPosition()));
|
||||||
state.mOrientation = it->mNode->getOrientation();
|
state.mOrientation = ESM::Quaternion(osg::Quat(it->mNode->getAttitude()));
|
||||||
state.mActorId = it->mActorId;
|
state.mActorId = it->mActorId;
|
||||||
|
|
||||||
state.mBowId = it->mBowId;
|
state.mBowId = it->mBowId;
|
||||||
|
@ -327,8 +300,8 @@ namespace MWWorld
|
||||||
|
|
||||||
ESM::MagicBoltState state;
|
ESM::MagicBoltState state;
|
||||||
state.mId = it->mId;
|
state.mId = it->mId;
|
||||||
state.mPosition = it->mNode->getPosition();
|
state.mPosition = ESM::Vector3(osg::Vec3f(it->mNode->getPosition()));
|
||||||
state.mOrientation = it->mNode->getOrientation();
|
state.mOrientation = ESM::Quaternion(osg::Quat(it->mNode->getAttitude()));
|
||||||
state.mActorId = it->mActorId;
|
state.mActorId = it->mActorId;
|
||||||
|
|
||||||
state.mSpellId = it->mSpellId;
|
state.mSpellId = it->mSpellId;
|
||||||
|
@ -369,8 +342,9 @@ namespace MWWorld
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation);
|
|
||||||
createModel(state, model);
|
createModel(state, model);
|
||||||
|
state.mNode->setPosition(osg::Vec3f(esm.mPosition));
|
||||||
|
state.mNode->setAttitude(osg::Quat(esm.mOrientation));
|
||||||
|
|
||||||
mProjectiles.push_back(state);
|
mProjectiles.push_back(state);
|
||||||
return true;
|
return true;
|
||||||
|
@ -401,8 +375,9 @@ namespace MWWorld
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation);
|
|
||||||
createModel(state, model);
|
createModel(state, model);
|
||||||
|
state.mNode->setPosition(osg::Vec3f(esm.mPosition));
|
||||||
|
state.mNode->setAttitude(osg::Quat(esm.mOrientation));
|
||||||
|
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f,
|
state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f,
|
||||||
|
@ -421,4 +396,12 @@ namespace MWWorld
|
||||||
return mMagicBolts.size() + mProjectiles.size();
|
return mMagicBolts.size() + mProjectiles.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::Ptr ProjectileManager::State::getCaster()
|
||||||
|
{
|
||||||
|
if (!mCasterHandle.isEmpty())
|
||||||
|
return mCasterHandle;
|
||||||
|
|
||||||
|
return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
#include <components/esm/effectlist.hpp>
|
#include <components/esm/effectlist.hpp>
|
||||||
|
|
||||||
|
@ -21,9 +21,20 @@ namespace Loading
|
||||||
class Listener;
|
class Listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Ogre
|
namespace osg
|
||||||
{
|
{
|
||||||
class SceneManager;
|
class Group;
|
||||||
|
class Quat;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
class ResourceSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
|
class EffectAnimationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
|
@ -32,16 +43,16 @@ namespace MWWorld
|
||||||
class ProjectileManager
|
class ProjectileManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectileManager (Ogre::SceneManager* sceneMgr,
|
ProjectileManager (osg::Group* parent, Resource::ResourceSystem* resourceSystem,
|
||||||
OEngine::Physic::PhysicEngine& engine);
|
MWPhysics::PhysicsSystem* physics);
|
||||||
|
|
||||||
/// If caster is an actor, the actor's facing orientation is used. Otherwise fallbackDirection is used.
|
/// If caster is an actor, the actor's facing orientation is used. Otherwise fallbackDirection is used.
|
||||||
void launchMagicBolt (const std::string& model, const std::string &sound, const std::string &spellId,
|
void launchMagicBolt (const std::string& model, const std::string &sound, const std::string &spellId,
|
||||||
float speed, bool stack, const ESM::EffectList& effects,
|
float speed, bool stack, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection);
|
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection);
|
||||||
|
|
||||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||||
const Ogre::Vector3& pos, const Ogre::Quaternion& orient, MWWorld::Ptr bow, float speed);
|
const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed);
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
@ -53,22 +64,22 @@ namespace MWWorld
|
||||||
int countSavedGameRecords() const;
|
int countSavedGameRecords() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OEngine::Physic::PhysicEngine& mPhysEngine;
|
osg::ref_ptr<osg::Group> mParent;
|
||||||
Ogre::SceneManager* mSceneMgr;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
|
MWPhysics::PhysicsSystem* mPhysics;
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
NifOgre::ObjectScenePtr mObject;
|
osg::ref_ptr<osg::PositionAttitudeTransform> mNode;
|
||||||
Ogre::SceneNode* mNode;
|
boost::shared_ptr<MWRender::EffectAnimationTime> mEffectAnimationTime;
|
||||||
|
|
||||||
int mActorId;
|
int mActorId;
|
||||||
|
|
||||||
// actorId doesn't work for non-actors, so we also keep track of the Ogre-handle.
|
|
||||||
// For non-actors, the caster ptr is mainly needed to prevent the projectile
|
|
||||||
// from colliding with its caster.
|
|
||||||
// TODO: this will break when the game is saved and reloaded, since there is currently
|
// TODO: this will break when the game is saved and reloaded, since there is currently
|
||||||
// no way to write identifiers for non-actors to a savegame.
|
// no way to write identifiers for non-actors to a savegame.
|
||||||
std::string mCasterHandle;
|
MWWorld::Ptr mCasterHandle;
|
||||||
|
|
||||||
|
MWWorld::Ptr getCaster();
|
||||||
|
|
||||||
// MW-id of this projectile
|
// MW-id of this projectile
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
@ -96,7 +107,7 @@ namespace MWWorld
|
||||||
// RefID of the bow or crossbow the actor was using when this projectile was fired (may be empty)
|
// RefID of the bow or crossbow the actor was using when this projectile was fired (may be empty)
|
||||||
std::string mBowId;
|
std::string mBowId;
|
||||||
|
|
||||||
Ogre::Vector3 mVelocity;
|
osg::Vec3f mVelocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<MagicBoltState> mMagicBolts;
|
std::vector<MagicBoltState> mMagicBolts;
|
||||||
|
@ -106,7 +117,7 @@ namespace MWWorld
|
||||||
void moveMagicBolts(float dt);
|
void moveMagicBolts(float dt);
|
||||||
|
|
||||||
void createModel (State& state, const std::string& model);
|
void createModel (State& state, const std::string& model);
|
||||||
void update (NifOgre::ObjectScenePtr object, float duration);
|
void update (State& state, float duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#include "containerstore.hpp"
|
#include "containerstore.hpp"
|
||||||
#include "inventorystore.hpp"
|
#include "inventorystore.hpp"
|
||||||
#include "actionteleport.hpp"
|
#include "actionteleport.hpp"
|
||||||
//#include "projectilemanager.hpp"
|
#include "projectilemanager.hpp"
|
||||||
#include "weather.hpp"
|
#include "weather.hpp"
|
||||||
|
|
||||||
#include "contentloader.hpp"
|
#include "contentloader.hpp"
|
||||||
|
@ -159,9 +159,7 @@ namespace MWWorld
|
||||||
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0)
|
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0)
|
||||||
{
|
{
|
||||||
mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode);
|
mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode);
|
||||||
#if 0
|
mProjectileManager.reset(new ProjectileManager(rootNode, resourceSystem, mPhysics));
|
||||||
mProjectileManager.reset(new ProjectileManager(renderer.getScene(), *mPhysEngine));
|
|
||||||
#endif
|
|
||||||
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem);
|
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem);
|
||||||
|
|
||||||
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
|
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
|
||||||
|
@ -276,9 +274,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
mWeatherManager->clear();
|
mWeatherManager->clear();
|
||||||
mRendering->clear();
|
mRendering->clear();
|
||||||
#if 0
|
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
#endif
|
|
||||||
mLocalScripts.clear();
|
mLocalScripts.clear();
|
||||||
|
|
||||||
mWorldScene->changeToVoid();
|
mWorldScene->changeToVoid();
|
||||||
|
@ -313,9 +309,7 @@ namespace MWWorld
|
||||||
mCells.countSavedGameRecords()
|
mCells.countSavedGameRecords()
|
||||||
+mStore.countSavedGameRecords()
|
+mStore.countSavedGameRecords()
|
||||||
+mGlobalVariables.countSavedGameRecords()
|
+mGlobalVariables.countSavedGameRecords()
|
||||||
#if 0
|
|
||||||
+mProjectileManager->countSavedGameRecords()
|
+mProjectileManager->countSavedGameRecords()
|
||||||
#endif
|
|
||||||
+1 // player record
|
+1 // player record
|
||||||
+1 // weather record
|
+1 // weather record
|
||||||
+1 // actorId counter
|
+1 // actorId counter
|
||||||
|
@ -346,9 +340,8 @@ namespace MWWorld
|
||||||
mGlobalVariables.write (writer, progress);
|
mGlobalVariables.write (writer, progress);
|
||||||
mPlayer->write (writer, progress);
|
mPlayer->write (writer, progress);
|
||||||
mWeatherManager->write (writer, progress);
|
mWeatherManager->write (writer, progress);
|
||||||
#if 0
|
|
||||||
mProjectileManager->write (writer, progress);
|
mProjectileManager->write (writer, progress);
|
||||||
#endif
|
|
||||||
writer.startRecord(ESM::REC_ENAB);
|
writer.startRecord(ESM::REC_ENAB);
|
||||||
writer.writeHNT("TELE", mTeleportEnabled);
|
writer.writeHNT("TELE", mTeleportEnabled);
|
||||||
writer.writeHNT("LEVT", mLevitationEnabled);
|
writer.writeHNT("LEVT", mLevitationEnabled);
|
||||||
|
@ -377,9 +370,7 @@ namespace MWWorld
|
||||||
!mPlayer->readRecord (reader, type) &&
|
!mPlayer->readRecord (reader, type) &&
|
||||||
!mWeatherManager->readRecord (reader, type) &&
|
!mWeatherManager->readRecord (reader, type) &&
|
||||||
!mCells.readRecord (reader, type, contentFileMap)
|
!mCells.readRecord (reader, type, contentFileMap)
|
||||||
#if 0
|
|
||||||
&& !mProjectileManager->readRecord (reader, type)
|
&& !mProjectileManager->readRecord (reader, type)
|
||||||
#endif
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("unknown record in saved game");
|
throw std::runtime_error ("unknown record in saved game");
|
||||||
|
@ -472,10 +463,8 @@ namespace MWWorld
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
// Must be cleared before mRendering is destroyed
|
// Must be cleared before mRendering is destroyed
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
#endif
|
|
||||||
delete mWeatherManager;
|
delete mWeatherManager;
|
||||||
delete mWorldScene;
|
delete mWorldScene;
|
||||||
delete mRendering;
|
delete mRendering;
|
||||||
|
@ -970,9 +959,7 @@ namespace MWWorld
|
||||||
if (mCurrentWorldSpace != cellName)
|
if (mCurrentWorldSpace != cellName)
|
||||||
{
|
{
|
||||||
// changed worldspace
|
// changed worldspace
|
||||||
#if 0
|
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
#endif
|
|
||||||
mRendering->notifyWorldSpaceChanged();
|
mRendering->notifyWorldSpaceChanged();
|
||||||
|
|
||||||
mCurrentWorldSpace = cellName;
|
mCurrentWorldSpace = cellName;
|
||||||
|
@ -990,9 +977,7 @@ namespace MWWorld
|
||||||
if (mCurrentWorldSpace != "sys::default") // FIXME
|
if (mCurrentWorldSpace != "sys::default") // FIXME
|
||||||
{
|
{
|
||||||
// changed worldspace
|
// changed worldspace
|
||||||
#if 0
|
|
||||||
mProjectileManager->clear();
|
mProjectileManager->clear();
|
||||||
#endif
|
|
||||||
mRendering->notifyWorldSpaceChanged();
|
mRendering->notifyWorldSpaceChanged();
|
||||||
}
|
}
|
||||||
removeContainerScripts(getPlayerPtr());
|
removeContainerScripts(getPlayerPtr());
|
||||||
|
@ -1388,7 +1373,7 @@ namespace MWWorld
|
||||||
mPhysics->stepSimulation(duration);
|
mPhysics->stepSimulation(duration);
|
||||||
processDoors(duration);
|
processDoors(duration);
|
||||||
|
|
||||||
//mProjectileManager->update(duration);
|
mProjectileManager->update(duration);
|
||||||
|
|
||||||
const MWPhysics::PtrVelocityList &results = mPhysics->applyQueuedMovement(duration);
|
const MWPhysics::PtrVelocityList &results = mPhysics->applyQueuedMovement(duration);
|
||||||
MWPhysics::PtrVelocityList::const_iterator player(results.end());
|
MWPhysics::PtrVelocityList::const_iterator player(results.end());
|
||||||
|
@ -1637,9 +1622,7 @@ namespace MWWorld
|
||||||
const ESM::Position& refpos = getPlayerPtr().getRefData().getPosition();
|
const ESM::Position& refpos = getPlayerPtr().getRefData().getPosition();
|
||||||
osg::Vec3f playerPos = refpos.asVec3();
|
osg::Vec3f playerPos = refpos.asVec3();
|
||||||
|
|
||||||
const MWPhysics::Actor* actor = mPhysics->getActor(getPlayerPtr());
|
playerPos.z() += 1.85f * mPhysics->getHalfExtents(getPlayerPtr()).z();
|
||||||
if (actor)
|
|
||||||
playerPos.z() += 1.85f * actor->getHalfExtents().z();
|
|
||||||
|
|
||||||
osg::Quat playerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0,-1,0)) *
|
osg::Quat playerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0,-1,0)) *
|
||||||
osg::Quat(refpos.rot[0], osg::Vec3f(-1,0,0)) *
|
osg::Quat(refpos.rot[0], osg::Vec3f(-1,0,0)) *
|
||||||
|
@ -2015,24 +1998,19 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
bool World::isUnderwater(const MWWorld::Ptr &object, const float heightRatio) const
|
||||||
{
|
{
|
||||||
const float *fpos = object.getRefData().getPosition().pos;
|
osg::Vec3f pos (object.getRefData().getPosition().asVec3());
|
||||||
Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]);
|
|
||||||
|
|
||||||
const MWPhysics::Actor* actor = mPhysics->getActor(object);
|
pos.z() += heightRatio*2*mPhysics->getHalfExtents(object).z();
|
||||||
if (actor)
|
|
||||||
{
|
|
||||||
pos.z += heightRatio*2*actor->getHalfExtents().z();
|
|
||||||
}
|
|
||||||
|
|
||||||
return isUnderwater(object.getCell(), pos);
|
return isUnderwater(object.getCell(), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const
|
bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const
|
||||||
{
|
{
|
||||||
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return pos.z < cell->getWaterLevel();
|
return pos.z() < cell->getWaterLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
||||||
|
@ -2125,7 +2103,7 @@ namespace MWWorld
|
||||||
|
|
||||||
Ptr player = mPlayer->getPlayer();
|
Ptr player = mPlayer->getPlayer();
|
||||||
RefData &refdata = player.getRefData();
|
RefData &refdata = player.getRefData();
|
||||||
Ogre::Vector3 playerPos(refdata.getPosition().pos);
|
osg::Vec3f playerPos(refdata.getPosition().asVec3());
|
||||||
|
|
||||||
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
||||||
if (!actor)
|
if (!actor)
|
||||||
|
@ -2519,7 +2497,7 @@ namespace MWWorld
|
||||||
|
|
||||||
// Witnesses of the player's transformation will make them a globally known werewolf
|
// Witnesses of the player's transformation will make them a globally known werewolf
|
||||||
std::vector<MWWorld::Ptr> closeActors;
|
std::vector<MWWorld::Ptr> closeActors;
|
||||||
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(actor.getRefData().getPosition().pos),
|
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(actor.getRefData().getPosition().asVec3(),
|
||||||
getStore().get<ESM::GameSetting>().search("fAlarmRadius")->getFloat(),
|
getStore().get<ESM::GameSetting>().search("fAlarmRadius")->getFloat(),
|
||||||
closeActors);
|
closeActors);
|
||||||
|
|
||||||
|
@ -2695,7 +2673,7 @@ namespace MWWorld
|
||||||
|
|
||||||
MWMechanics::CastSpell cast(actor, target);
|
MWMechanics::CastSpell cast(actor, target);
|
||||||
if (!target.isEmpty())
|
if (!target.isEmpty())
|
||||||
cast.mHitPosition = Ogre::Vector3(target.getRefData().getPosition().pos);
|
cast.mHitPosition = target.getRefData().getPosition().asVec3();
|
||||||
|
|
||||||
if (!selectedSpell.empty())
|
if (!selectedSpell.empty())
|
||||||
{
|
{
|
||||||
|
@ -2718,18 +2696,14 @@ namespace MWWorld
|
||||||
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
void World::launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed)
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed);
|
mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::launchMagicBolt (const std::string& model, const std::string &sound, const std::string &spellId,
|
void World::launchMagicBolt (const std::string& model, const std::string &sound, const std::string &spellId,
|
||||||
float speed, bool stack, const ESM::EffectList& effects,
|
float speed, bool stack, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection)
|
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
mProjectileManager->launchMagicBolt(model, sound, spellId, speed, stack, effects, caster, sourceName, fallbackDirection);
|
mProjectileManager->launchMagicBolt(model, sound, spellId, speed, stack, effects, caster, sourceName, fallbackDirection);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& World::getContentFiles() const
|
const std::vector<std::string>& World::getContentFiles() const
|
||||||
|
@ -3181,7 +3155,7 @@ namespace MWWorld
|
||||||
mRendering->spawnEffect(model, textureOverride, worldPos);
|
mRendering->spawnEffect(model, textureOverride, worldPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::explodeSpell(const Ogre::Vector3 &origin, const ESM::EffectList &effects, const Ptr &caster, ESM::RangeType rangeType,
|
void World::explodeSpell(const osg::Vec3f &origin, const ESM::EffectList &effects, const Ptr &caster, ESM::RangeType rangeType,
|
||||||
const std::string& id, const std::string& sourceName)
|
const std::string& id, const std::string& sourceName)
|
||||||
{
|
{
|
||||||
std::map<MWWorld::Ptr, std::vector<ESM::ENAMstruct> > toApply;
|
std::map<MWWorld::Ptr, std::vector<ESM::ENAMstruct> > toApply;
|
||||||
|
@ -3200,7 +3174,7 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
areaStatic = getStore().get<ESM::Static>().find ("VFX_DefaultArea");
|
areaStatic = getStore().get<ESM::Static>().find ("VFX_DefaultArea");
|
||||||
|
|
||||||
mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", osg::Vec3f(origin.x, origin.y, origin.z), static_cast<float>(effectIt->mArea));
|
mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", origin, static_cast<float>(effectIt->mArea));
|
||||||
|
|
||||||
// Play explosion sound (make sure to use NoTrack, since we will delete the projectile now)
|
// Play explosion sound (make sure to use NoTrack, since we will delete the projectile now)
|
||||||
static const std::string schools[] = {
|
static const std::string schools[] = {
|
||||||
|
@ -3209,9 +3183,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
||||||
if(!effect->mAreaSound.empty())
|
if(!effect->mAreaSound.empty())
|
||||||
sndMgr->playManualSound3D(osg::Vec3f(origin.x, origin.y, origin.z), effect->mAreaSound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoTrack);
|
sndMgr->playManualSound3D(origin, effect->mAreaSound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoTrack);
|
||||||
else
|
else
|
||||||
sndMgr->playManualSound3D(osg::Vec3f(origin.x, origin.y, origin.z), schools[effect->mData.mSchool]+" area", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoTrack);
|
sndMgr->playManualSound3D(origin, schools[effect->mData.mSchool]+" area", 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_NoTrack);
|
||||||
}
|
}
|
||||||
// Get the actors in range of the effect
|
// Get the actors in range of the effect
|
||||||
std::vector<MWWorld::Ptr> objects;
|
std::vector<MWWorld::Ptr> objects;
|
||||||
|
|
|
@ -455,7 +455,7 @@ namespace MWWorld
|
||||||
///Is the head of the creature underwater?
|
///Is the head of the creature underwater?
|
||||||
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
|
virtual bool isSubmerged(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
virtual bool isSwimming(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isUnderwater(const MWWorld::CellStore* cell, const Ogre::Vector3 &pos) const;
|
virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const;
|
||||||
virtual bool isWading(const MWWorld::Ptr &object) const;
|
virtual bool isWading(const MWWorld::Ptr &object) const;
|
||||||
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
virtual bool isOnGround(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
@ -572,7 +572,7 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId,
|
virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId,
|
||||||
float speed, bool stack, const ESM::EffectList& effects,
|
float speed, bool stack, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, const std::string& sourceName, const Ogre::Vector3& fallbackDirection);
|
const MWWorld::Ptr& caster, const std::string& sourceName, const osg::Vec3f& fallbackDirection);
|
||||||
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
virtual void launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed);
|
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed);
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ namespace MWWorld
|
||||||
|
|
||||||
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos);
|
virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos);
|
||||||
|
|
||||||
virtual void explodeSpell (const Ogre::Vector3& origin, const ESM::EffectList& effects,
|
virtual void explodeSpell (const osg::Vec3f& origin, const ESM::EffectList& effects,
|
||||||
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName);
|
const MWWorld::Ptr& caster, ESM::RangeType rangeType, const std::string& id, const std::string& sourceName);
|
||||||
|
|
||||||
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor);
|
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor);
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <osg/Quat>
|
||||||
#include <OgreQuaternion.h>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include "effectlist.hpp"
|
#include "effectlist.hpp"
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
#include <OgreQuaternion.h>
|
#include <OgreQuaternion.h>
|
||||||
|
|
||||||
|
#include <osg/Vec3f>
|
||||||
|
#include <osg/Quat>
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -21,11 +24,23 @@ struct Quaternion
|
||||||
mValues[2] = q.y;
|
mValues[2] = q.y;
|
||||||
mValues[3] = q.z;
|
mValues[3] = q.z;
|
||||||
}
|
}
|
||||||
|
Quaternion(const osg::Quat& q)
|
||||||
|
{
|
||||||
|
mValues[0] = q.w();
|
||||||
|
mValues[1] = q.x();
|
||||||
|
mValues[2] = q.y();
|
||||||
|
mValues[3] = q.z();
|
||||||
|
}
|
||||||
|
|
||||||
operator Ogre::Quaternion () const
|
operator Ogre::Quaternion () const
|
||||||
{
|
{
|
||||||
return Ogre::Quaternion(mValues[0], mValues[1], mValues[2], mValues[3]);
|
return Ogre::Quaternion(mValues[0], mValues[1], mValues[2], mValues[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator osg::Quat () const
|
||||||
|
{
|
||||||
|
return osg::Quat(mValues[1], mValues[2], mValues[3], mValues[0]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector3
|
struct Vector3
|
||||||
|
@ -39,11 +54,22 @@ struct Vector3
|
||||||
mValues[1] = v.y;
|
mValues[1] = v.y;
|
||||||
mValues[2] = v.z;
|
mValues[2] = v.z;
|
||||||
}
|
}
|
||||||
|
Vector3(const osg::Vec3f& v)
|
||||||
|
{
|
||||||
|
mValues[0] = v.x();
|
||||||
|
mValues[1] = v.y();
|
||||||
|
mValues[2] = v.z();
|
||||||
|
}
|
||||||
|
|
||||||
operator Ogre::Vector3 () const
|
operator Ogre::Vector3 () const
|
||||||
{
|
{
|
||||||
return Ogre::Vector3(&mValues[0]);
|
return Ogre::Vector3(&mValues[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator osg::Vec3f () const
|
||||||
|
{
|
||||||
|
return osg::Vec3f(mValues[0], mValues[1], mValues[2]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue