diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 3cf43749de..c46a831837 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -23,9 +23,7 @@ add_openmw_dir (mwrender actors objects renderingmanager animation rotatecontroller sky npcanimation vismask creatureanimation effectmanager util renderinginterface pathgrid rendermode weaponanimation bulletdebugdraw globalmap characterpreview camera localmap -# occlusionquery water shadows -# ripplesimulation refraction -# terrainstorage weaponanimation +# occlusionquery water shadows ripplesimulation refraction terrainstorage ) add_openmw_dir (mwinput @@ -68,8 +66,7 @@ add_openmw_dir (mwworld cells localscripts customdata inventorystore ptr actionopen actionread actionequip timestamp actionalchemy cellstore actionapply actioneat esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor - contentloader esmloader actiontrap cellreflist cellref physicssystem weather -# projectilemanager + contentloader esmloader actiontrap cellreflist cellref physicssystem weather projectilemanager ) add_openmw_dir (mwphysics diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index f7fc515f57..1d3619d3da 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -6,9 +6,9 @@ #include #include -namespace Ogre +namespace osg { - class Vector3; + class Vec3f; } namespace ESM @@ -174,8 +174,8 @@ namespace MWBase virtual bool toggleAI() = 0; virtual bool isAIActive() = 0; - virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector& objects) = 0; - virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector &objects) = 0; + virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects) = 0; + virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) = 0; ///return the list of actors which are following the given actor /**ie AiFollow is active and the target is the actor**/ diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 4d01f95295..f258eb300a 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -378,7 +378,7 @@ namespace MWBase virtual bool isWading(const MWWorld::Ptr &object) const = 0; ///Is the head of the creature underwater? 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 void togglePOV() = 0; @@ -485,7 +485,7 @@ namespace MWBase virtual void launchMagicBolt (const std::string& model, const std::string& sound, const std::string& spellId, 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, 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 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; virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0; diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 64850d1279..ea67884d35 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -247,7 +247,7 @@ namespace MWClass if (!victim.getClass().isActor()) 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); @@ -319,7 +319,7 @@ namespace MWClass 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); @@ -726,7 +726,7 @@ namespace MWClass if(name == "left") { 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)) return 2; if(world->isOnGround(ptr)) @@ -736,7 +736,7 @@ namespace MWClass if(name == "right") { 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)) return 3; if(world->isOnGround(ptr)) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 791c2f57e2..4307fe9be0 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -493,7 +493,7 @@ namespace MWClass // TODO: Use second to work out the hit angle std::pair result = world->getHitContact(ptr, dist); 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 return; @@ -583,7 +583,7 @@ namespace MWClass 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); @@ -1138,7 +1138,7 @@ namespace MWClass if(name == "left" || name == "right") { 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)) return (name == "left") ? "Swim Left" : "Swim Right"; if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) @@ -1175,7 +1175,7 @@ namespace MWClass if(name == "land") { 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)) return "DefaultLandWater"; if(world->isOnGround(ptr)) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 88b0bd3211..1182de1515 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1623,6 +1623,9 @@ namespace MWGui void WindowManager::clear() { + if (mLocalMapRender) + mLocalMapRender->clear(); + mMap->clear(); mQuickKeysMenu->clear(); mMessageBoxManager->clear(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 84e97487a2..81dbca58ab 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -809,7 +809,7 @@ namespace MWMechanics NpcStats &stats = ptr.getClass().getNpcStats(ptr); 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) && stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0) { @@ -1385,11 +1385,11 @@ namespace MWMechanics return false; } - void Actors::getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector& out) + void Actors::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) { 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); } } @@ -1457,7 +1457,7 @@ namespace MWMechanics std::list Actors::getActorsFighting(const MWWorld::Ptr& actor) { std::list list; std::vector neighbors; - Ogre::Vector3 position = Ogre::Vector3(actor.getRefData().getPosition().pos); + osg::Vec3f position (actor.getRefData().getPosition().asVec3()); getObjectsInRange(position, MWBase::Environment::get().getWorld()->getStore().get().find("fAlarmRadius")->getFloat(), neighbors); //only care about those within the alarm disance diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 70f1b47d91..f9e58ab4fe 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -114,7 +114,7 @@ namespace MWMechanics void skipAnimation(const MWWorld::Ptr& ptr); bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName); - void getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector& out); + void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out); ///Returns the list of actors which are following the given actor /**ie AiFollow is active and the target is the actor **/ diff --git a/apps/openmw/mwmechanics/aiavoiddoor.cpp b/apps/openmw/mwmechanics/aiavoiddoor.cpp index 9ec5bc19a0..83f9dffb47 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.cpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.cpp @@ -64,7 +64,7 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, AiState& stat // Make all nearby actors also avoid the door std::vector 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::iterator it = actors.begin(); it != actors.end(); ++it) { if(*it != MWBase::Environment::get().getWorld()->getPlayerPtr()) { //Not the player MWMechanics::AiSequence& seq = it->getClass().getCreatureStats(*it).getAiSequence(); diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index ee48d124f0..b013dbb1b7 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -28,7 +28,7 @@ float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg: 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) : ""; 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, - const Ogre::Vector3& hitPosition) + const osg::Vec3f& hitPosition) { MWBase::World *world = MWBase::Environment::get().getWorld(); const MWWorld::Store &gmst = world->getStore().get(); @@ -221,7 +221,7 @@ namespace MWMechanics appliedEnchantment = applyEnchantment(attacker, victim, projectile, hitPosition); 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 if (victim != MWBase::Environment::get().getWorld()->getPlayerPtr() diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index a2fd8b0067..0a31a1a7e3 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -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 \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, - 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 float getHitChance (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 0ae9395c5d..8fbb31fb7b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1059,14 +1059,14 @@ namespace MWMechanics // Find all the actors within the alarm radius std::vector 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(); float radius = esmStore.get().find("fAlarmRadius")->getFloat(); mActors.getObjectsInRange(from, radius, neighbors); // 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); // Did anyone see it? @@ -1149,13 +1149,13 @@ namespace MWMechanics 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().find("fAlarmRadius")->getFloat(); mActors.getObjectsInRange(from, radius, neighbors); // 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); int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId(); @@ -1430,13 +1430,13 @@ namespace MWMechanics MWBase::Environment::get().getDialogueManager()->say(ptr, "attack"); } - void MechanicsManager::getObjectsInRange(const Ogre::Vector3 &position, float radius, std::vector &objects) + void MechanicsManager::getObjectsInRange(const osg::Vec3f &position, float radius, std::vector &objects) { mActors.getObjectsInRange(position, radius, objects); mObjects.getObjectsInRange(position, radius, objects); } - void MechanicsManager::getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector &objects) + void MechanicsManager::getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) { mActors.getObjectsInRange(position, radius, objects); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index d08334ae8c..f695ec57a8 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -145,8 +145,8 @@ namespace MWMechanics /// paused we may want to do it manually (after equipping permanent enchantment) virtual void updateMagicEffects (const MWWorld::Ptr& ptr); - virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector& objects); - virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector &objects); + virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects); + virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects); virtual std::list getActorsFollowing(const MWWorld::Ptr& actor); virtual std::list getActorsFollowingIndices(const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index ba35af777d..d6f5da88d2 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -92,11 +92,11 @@ void Objects::skipAnimation(const MWWorld::Ptr& ptr) iter->second->skipAnim(); } -void Objects::getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector& out) +void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) { 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); } } diff --git a/apps/openmw/mwmechanics/objects.hpp b/apps/openmw/mwmechanics/objects.hpp index 373a2a1056..6e22c0582b 100644 --- a/apps/openmw/mwmechanics/objects.hpp +++ b/apps/openmw/mwmechanics/objects.hpp @@ -41,7 +41,7 @@ namespace MWMechanics void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); void skipAnimation(const MWWorld::Ptr& ptr); - void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector& out); + void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& out); }; } diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 8965d3b0d5..cdca6eeaad 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -779,7 +779,7 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, false, enchantment->mEffects, mCaster, mSourceName, // Not needed, enchantments can only be cast by actors - Ogre::Vector3(1,0,0)); + osg::Vec3f(1,0,0)); return true; } @@ -861,13 +861,13 @@ namespace MWMechanics getProjectileInfo(spell->mEffects, projectileModel, sound, speed); 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 // (e.g. when cast by a non-actor) if (!mTarget.isEmpty()) fallbackDirection = - Ogre::Vector3(mTarget.getRefData().getPosition().pos)- - Ogre::Vector3(mCaster.getRefData().getPosition().pos); + osg::Vec3f(mTarget.getRefData().getPosition().asVec3())- + osg::Vec3f(mCaster.getRefData().getPosition().asVec3()); MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, false, spell->mEffects, mCaster, mSourceName, fallbackDirection); diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index f50584edf2..4241c9e3e3 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -71,7 +71,7 @@ namespace MWMechanics bool mStack; std::string mId; // ID of spell, potion, item 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) public: diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index c0e7a80b9d..f97c5fd138 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -748,7 +748,7 @@ namespace MWPhysics 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 btTo = toBullet(to); @@ -762,7 +762,7 @@ namespace MWPhysics } ClosestNotMeRayResultCallback resultCallback(me, btFrom, btTo); - resultCallback.m_collisionFilterGroup = 0xff; + resultCallback.m_collisionFilterGroup = group; resultCallback.m_collisionFilterMask = mask; 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 { public: @@ -1128,7 +1137,7 @@ namespace MWPhysics if (effects.get(ESM::MagicEffect::WaterWalking).getMagnitude() && cell->getCell()->hasWater() && !world->isUnderwater(iter->first.getCell(), - Ogre::Vector3(iter->first.getRefData().getPosition().pos))) + osg::Vec3f(iter->first.getRefData().getPosition().asVec3()))) waterCollision = true; ActorMap::iterator foundActor = mActors.find(iter->first); diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index d4f7e25b10..7e3c279515 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -99,7 +99,7 @@ namespace MWPhysics /// @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 = - 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); @@ -108,6 +108,8 @@ namespace MWPhysics 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 /// be overwritten. Valid until the next call to applyQueuedMovement. void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index efdb49cf7f..8580eb8f88 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -937,7 +937,7 @@ namespace MWScript MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getPtr (targetId, false); MWMechanics::CastSpell cast(ptr, target); - cast.mHitPosition = Ogre::Vector3(target.getRefData().getPosition().pos); + cast.mHitPosition = target.getRefData().getPosition().asVec3(); cast.mAlwaysSucceed = true; cast.cast(spell); } @@ -955,7 +955,7 @@ namespace MWScript runtime.pop(); MWMechanics::CastSpell cast(ptr, ptr); - cast.mHitPosition = Ogre::Vector3(ptr.getRefData().getPosition().pos); + cast.mHitPosition = ptr.getRefData().getPosition().asVec3(); cast.mAlwaysSucceed = true; cast.cast(spell); } diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index d153b7e618..68d7c69e9f 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -9,8 +9,8 @@ namespace MWWorld void ActionTrap::executeImp(const Ptr &actor) { - Ogre::Vector3 actorPosition(actor.getRefData().getPosition().pos); - Ogre::Vector3 trapPosition(mTrapSource.getRefData().getPosition().pos); + osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); + osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); float activationDistance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); // GUI calcs if object in activation distance include object and player geometry @@ -20,7 +20,7 @@ namespace MWWorld // to open door/container. // 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. - if (trapPosition.distance(actorPosition) < (activationDistance * fudgeFactor)) + if ((trapPosition - actorPosition).length() < (activationDistance * fudgeFactor)) { // assume actor touched trap MWMechanics::CastSpell cast(mTrapSource, actor); diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index acbe819f1e..84d86fba74 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -1,11 +1,11 @@ #include "projectilemanager.hpp" -#include -#include - -#include +#include #include +#include +#include +#include #include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" @@ -22,72 +22,70 @@ #include "../mwrender/effectmanager.hpp" #include "../mwrender/animation.hpp" -#include "../mwrender/renderconst.hpp" +#include "../mwrender/vismask.hpp" #include "../mwsound/sound.hpp" +#include "../mwphysics/physicssystem.hpp" + + namespace MWWorld { - ProjectileManager::ProjectileManager(Ogre::SceneManager* sceneMgr, OEngine::Physic::PhysicEngine &engine) - : mPhysEngine(engine) - , mSceneMgr(sceneMgr) + ProjectileManager::ProjectileManager(osg::Group* parent, Resource::ResourceSystem* resourceSystem, MWPhysics::PhysicsSystem* physics) + : mParent(parent) + , mResourceSystem(resourceSystem) + , mPhysics(physics) { } void ProjectileManager::createModel(State &state, const std::string &model) { - state.mObject = NifOgre::Loader::createObjects(state.mNode, model); - for(size_t i = 0;i < state.mObject->mControllers.size();i++) - { - if(state.mObject->mControllers[i].getSource().isNull()) - state.mObject->mControllers[i].setSource(Ogre::SharedPtr (new MWRender::EffectAnimationTime())); - } + state.mNode = new osg::PositionAttitudeTransform; + state.mNode->setNodeMask(MWRender::Mask_Effect); + mParent->addChild(state.mNode); - MWRender::Animation::setRenderProperties(state.mObject, MWRender::RV_Effects, - MWRender::RQG_Main, MWRender::RQG_Alpha, 0.f, false, NULL); + mResourceSystem->getSceneManager()->createInstance(model, state.mNode); + + state.mEffectAnimationTime.reset(new MWRender::EffectAnimationTime); + + SceneUtil::AssignControllerSourcesVisitor assignVisitor (state.mEffectAnimationTime); + state.mNode->accept(assignVisitor); } - void ProjectileManager::update(NifOgre::ObjectScenePtr object, float duration) + void ProjectileManager::update(State& state, float duration) { - for(size_t i = 0; i < object->mControllers.size() ;i++) - { - MWRender::EffectAnimationTime* value = dynamic_cast(object->mControllers[i].getSource().get()); - if (value) - value->addTime(duration); - - object->mControllers[i].update(); - } + state.mEffectAnimationTime->addTime(duration); } void ProjectileManager::launchMagicBolt(const std::string &model, const std::string &sound, const std::string &spellId, float speed, bool stack, const ESM::EffectList &effects, const Ptr &caster, const std::string &sourceName, - const Ogre::Vector3& fallbackDirection) + const osg::Vec3f& fallbackDirection) { 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); - pos.z += height; + height += mPhysics->getHalfExtents(caster).z() * 2.f * 0.75f; // Spawn at 0.75 * ActorHeight + + osg::Vec3f pos(caster.getRefData().getPosition().asVec3()); + pos.z() += height; if (MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos)) // Underwater casting not possible return; - Ogre::Quaternion orient; + osg::Quat orient; if (caster.getClass().isActor()) - orient = Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) * - Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X); + orient = osg::Quat(caster.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0)) + * osg::Quat(caster.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1)); else - orient = Ogre::Vector3::UNIT_Y.getRotationTo(fallbackDirection); + orient.makeRotate(osg::Vec3f(0,1,0), osg::Vec3f(fallbackDirection)); MagicBoltState state; state.mSourceName = sourceName; state.mId = model; state.mSpellId = spellId; - state.mCasterHandle = caster.getRefData().getHandle(); + state.mCasterHandle = caster; if (caster.getClass().isActor()) state.mActorId = caster.getClass().getCreatureStats(caster).getActorId(); else @@ -107,8 +105,9 @@ namespace MWWorld MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), model); MWWorld::Ptr ptr = ref.getPtr(); - state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient); createModel(state, ptr.getClass().getModel(ptr)); + state.mNode->setPosition(pos); + state.mNode->setAttitude(orient); 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); @@ -116,20 +115,21 @@ namespace MWWorld mMagicBolts.push_back(state); } - void ProjectileManager::launchProjectile(Ptr actor, Ptr projectile, const Ogre::Vector3 &pos, - const Ogre::Quaternion &orient, Ptr bow, float speed) + void ProjectileManager::launchProjectile(Ptr actor, Ptr projectile, const osg::Vec3f &pos, const osg::Quat &orient, Ptr bow, float speed) { ProjectileState state; state.mActorId = actor.getClass().getCreatureStats(actor).getActorId(); 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.mCasterHandle = actor; MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId()); MWWorld::Ptr ptr = ref.getPtr(); - state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient); createModel(state, ptr.getClass().getModel(ptr)); + state.mNode->setPosition(pos); + state.mNode->setAttitude(orient); mProjectiles.push_back(state); } @@ -144,60 +144,46 @@ namespace MWWorld { for (std::vector::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() .find("fTargetSpellMaxSpeed")->getFloat(); float speed = fTargetSpellMaxSpeed * it->mSpeed; - Ogre::Vector3 direction = orient.yAxis(); - direction.normalise(); - Ogre::Vector3 pos(it->mNode->getPosition()); - Ogre::Vector3 newPos = pos + direction * duration * speed; + osg::Vec3f direction = orient * osg::Vec3f(0,1,0); + direction.normalize(); + osg::Vec3f pos(it->mNode->getPosition()); + osg::Vec3f newPos = pos + direction * duration * speed; if (it->mSound.get()) it->mSound->setPosition(newPos); it->mNode->setPosition(newPos); - update(it->mObject, duration); + update(*it, duration); + + MWWorld::Ptr caster = it->getCaster(); // Check for impact // TODO: use a proper btRigidBody / btGhostObject? - btVector3 from(pos.x, pos.y, pos.z); - btVector3 to(newPos.x, newPos.y, newPos.z); + MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, 0xff, MWPhysics::CollisionType_Projectile); - std::vector > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile); - bool hit=false; - - for (std::vector >::iterator cIt = collisions.begin(); cIt != collisions.end() && !hit; ++cIt) + bool hit = false; + if (result.mHit) { - MWWorld::Ptr obstacle = MWBase::Environment::get().getWorld()->searchPtrViaHandle(cIt->second); - - 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()) + hit = true; + if (result.mHitObject.isEmpty()) { - // Terrain + // terrain } else { - MWMechanics::CastSpell cast(caster, obstacle); + MWMechanics::CastSpell cast(caster, result.mHitObject); cast.mHitPosition = pos; cast.mId = it->mSpellId; cast.mSourceName = it->mSourceName; 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 @@ -206,12 +192,11 @@ namespace MWWorld 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().getSoundManager()->stopSound(it->mSound); - mSceneMgr->destroySceneNode(it->mNode); + mParent->removeChild(it->mNode); it = mMagicBolts.erase(it); continue; @@ -227,34 +212,26 @@ namespace MWWorld { // gravity constant - must be way lower than the gravity affecting actors, since we're not // 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()); - Ogre::Vector3 newPos = pos + it->mVelocity * duration; + osg::Vec3f pos(it->mNode->getPosition()); + osg::Vec3f newPos = pos + it->mVelocity * duration; - Ogre::Quaternion orient = Ogre::Vector3::UNIT_Y.getRotationTo(it->mVelocity); - it->mNode->setOrientation(orient); + osg::Quat orient; + orient.makeRotate(osg::Vec3f(0,1,0), it->mVelocity); + it->mNode->setAttitude(orient); it->mNode->setPosition(newPos); - update(it->mObject, duration); + update(*it, duration); + + MWWorld::Ptr caster = it->getCaster(); // Check for impact // TODO: use a proper btRigidBody / btGhostObject? - btVector3 from(pos.x, pos.y, pos.z); - btVector3 to(newPos.x, newPos.y, newPos.z); - std::vector > collisions = mPhysEngine.rayTest2(from, to, OEngine::Physic::CollisionType_Projectile); - bool hit=false; + MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(pos, newPos, caster, 0xff, MWPhysics::CollisionType_Projectile); - for (std::vector >::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); // 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()) - 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; - } - if (hit) - { - mSceneMgr->destroySceneNode(it->mNode); + mParent->removeChild(it->mNode); it = mProjectiles.erase(it); continue; @@ -290,13 +263,13 @@ namespace MWWorld { for (std::vector::iterator it = mProjectiles.begin(); it != mProjectiles.end(); ++it) { - mSceneMgr->destroySceneNode(it->mNode); + mParent->removeChild(it->mNode); } mProjectiles.clear(); for (std::vector::iterator it = mMagicBolts.begin(); it != mMagicBolts.end(); ++it) { + mParent->removeChild(it->mNode); MWBase::Environment::get().getSoundManager()->stopSound(it->mSound); - mSceneMgr->destroySceneNode(it->mNode); } mMagicBolts.clear(); } @@ -309,8 +282,8 @@ namespace MWWorld ESM::ProjectileState state; state.mId = it->mId; - state.mPosition = it->mNode->getPosition(); - state.mOrientation = it->mNode->getOrientation(); + state.mPosition = ESM::Vector3(osg::Vec3f(it->mNode->getPosition())); + state.mOrientation = ESM::Quaternion(osg::Quat(it->mNode->getAttitude())); state.mActorId = it->mActorId; state.mBowId = it->mBowId; @@ -327,8 +300,8 @@ namespace MWWorld ESM::MagicBoltState state; state.mId = it->mId; - state.mPosition = it->mNode->getPosition(); - state.mOrientation = it->mNode->getOrientation(); + state.mPosition = ESM::Vector3(osg::Vec3f(it->mNode->getPosition())); + state.mOrientation = ESM::Quaternion(osg::Quat(it->mNode->getAttitude())); state.mActorId = it->mActorId; state.mSpellId = it->mSpellId; @@ -369,8 +342,9 @@ namespace MWWorld return true; } - state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation); createModel(state, model); + state.mNode->setPosition(osg::Vec3f(esm.mPosition)); + state.mNode->setAttitude(osg::Quat(esm.mOrientation)); mProjectiles.push_back(state); return true; @@ -401,8 +375,9 @@ namespace MWWorld return true; } - state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation); createModel(state, model); + state.mNode->setPosition(osg::Vec3f(esm.mPosition)); + state.mNode->setAttitude(osg::Quat(esm.mOrientation)); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f, @@ -421,4 +396,12 @@ namespace MWWorld return mMagicBolts.size() + mProjectiles.size(); } + MWWorld::Ptr ProjectileManager::State::getCaster() + { + if (!mCasterHandle.isEmpty()) + return mCasterHandle; + + return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId); + } + } diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index f46f544d28..f42bc040f8 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -3,7 +3,7 @@ #include -#include +#include #include @@ -21,9 +21,20 @@ namespace Loading class Listener; } -namespace Ogre +namespace osg { - class SceneManager; + class Group; + class Quat; +} + +namespace Resource +{ + class ResourceSystem; +} + +namespace MWRender +{ + class EffectAnimationTime; } namespace MWWorld @@ -32,16 +43,16 @@ namespace MWWorld class ProjectileManager { public: - ProjectileManager (Ogre::SceneManager* sceneMgr, - OEngine::Physic::PhysicEngine& engine); + ProjectileManager (osg::Group* parent, Resource::ResourceSystem* resourceSystem, + MWPhysics::PhysicsSystem* physics); /// 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, 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, - 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); @@ -53,22 +64,22 @@ namespace MWWorld int countSavedGameRecords() const; private: - OEngine::Physic::PhysicEngine& mPhysEngine; - Ogre::SceneManager* mSceneMgr; + osg::ref_ptr mParent; + Resource::ResourceSystem* mResourceSystem; + MWPhysics::PhysicsSystem* mPhysics; struct State { - NifOgre::ObjectScenePtr mObject; - Ogre::SceneNode* mNode; + osg::ref_ptr mNode; + boost::shared_ptr mEffectAnimationTime; 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 // 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 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) std::string mBowId; - Ogre::Vector3 mVelocity; + osg::Vec3f mVelocity; }; std::vector mMagicBolts; @@ -106,7 +117,7 @@ namespace MWWorld void moveMagicBolts(float dt); void createModel (State& state, const std::string& model); - void update (NifOgre::ObjectScenePtr object, float duration); + void update (State& state, float duration); }; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2f47c19e60..126267fd46 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -54,7 +54,7 @@ #include "containerstore.hpp" #include "inventorystore.hpp" #include "actionteleport.hpp" -//#include "projectilemanager.hpp" +#include "projectilemanager.hpp" #include "weather.hpp" #include "contentloader.hpp" @@ -159,9 +159,7 @@ namespace MWWorld mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0) { mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode); -#if 0 - mProjectileManager.reset(new ProjectileManager(renderer.getScene(), *mPhysEngine)); -#endif + mProjectileManager.reset(new ProjectileManager(rootNode, resourceSystem, mPhysics)); mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem); mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); @@ -276,9 +274,7 @@ namespace MWWorld { mWeatherManager->clear(); mRendering->clear(); -#if 0 mProjectileManager->clear(); -#endif mLocalScripts.clear(); mWorldScene->changeToVoid(); @@ -313,9 +309,7 @@ namespace MWWorld mCells.countSavedGameRecords() +mStore.countSavedGameRecords() +mGlobalVariables.countSavedGameRecords() - #if 0 +mProjectileManager->countSavedGameRecords() - #endif +1 // player record +1 // weather record +1 // actorId counter @@ -346,9 +340,8 @@ namespace MWWorld mGlobalVariables.write (writer, progress); mPlayer->write (writer, progress); mWeatherManager->write (writer, progress); -#if 0 mProjectileManager->write (writer, progress); -#endif + writer.startRecord(ESM::REC_ENAB); writer.writeHNT("TELE", mTeleportEnabled); writer.writeHNT("LEVT", mLevitationEnabled); @@ -377,9 +370,7 @@ namespace MWWorld !mPlayer->readRecord (reader, type) && !mWeatherManager->readRecord (reader, type) && !mCells.readRecord (reader, type, contentFileMap) - #if 0 && !mProjectileManager->readRecord (reader, type) - #endif ) { throw std::runtime_error ("unknown record in saved game"); @@ -472,10 +463,8 @@ namespace MWWorld World::~World() { -#if 0 // Must be cleared before mRendering is destroyed mProjectileManager->clear(); -#endif delete mWeatherManager; delete mWorldScene; delete mRendering; @@ -970,9 +959,7 @@ namespace MWWorld if (mCurrentWorldSpace != cellName) { // changed worldspace -#if 0 mProjectileManager->clear(); -#endif mRendering->notifyWorldSpaceChanged(); mCurrentWorldSpace = cellName; @@ -990,9 +977,7 @@ namespace MWWorld if (mCurrentWorldSpace != "sys::default") // FIXME { // changed worldspace -#if 0 mProjectileManager->clear(); -#endif mRendering->notifyWorldSpaceChanged(); } removeContainerScripts(getPlayerPtr()); @@ -1388,7 +1373,7 @@ namespace MWWorld mPhysics->stepSimulation(duration); processDoors(duration); - //mProjectileManager->update(duration); + mProjectileManager->update(duration); const MWPhysics::PtrVelocityList &results = mPhysics->applyQueuedMovement(duration); MWPhysics::PtrVelocityList::const_iterator player(results.end()); @@ -1637,9 +1622,7 @@ namespace MWWorld const ESM::Position& refpos = getPlayerPtr().getRefData().getPosition(); osg::Vec3f playerPos = refpos.asVec3(); - const MWPhysics::Actor* actor = mPhysics->getActor(getPlayerPtr()); - if (actor) - playerPos.z() += 1.85f * actor->getHalfExtents().z(); + playerPos.z() += 1.85f * mPhysics->getHalfExtents(getPlayerPtr()).z(); osg::Quat playerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0,-1,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 { - const float *fpos = object.getRefData().getPosition().pos; - Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + osg::Vec3f pos (object.getRefData().getPosition().asVec3()); - const MWPhysics::Actor* actor = mPhysics->getActor(object); - if (actor) - { - pos.z += heightRatio*2*actor->getHalfExtents().z(); - } + pos.z() += heightRatio*2*mPhysics->getHalfExtents(object).z(); 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)) { return false; } - return pos.z < cell->getWaterLevel(); + return pos.z() < cell->getWaterLevel(); } bool World::isOnGround(const MWWorld::Ptr &ptr) const @@ -2125,7 +2103,7 @@ namespace MWWorld Ptr player = mPlayer->getPlayer(); RefData &refdata = player.getRefData(); - Ogre::Vector3 playerPos(refdata.getPosition().pos); + osg::Vec3f playerPos(refdata.getPosition().asVec3()); const MWPhysics::Actor* actor = mPhysics->getActor(player); if (!actor) @@ -2519,7 +2497,7 @@ namespace MWWorld // Witnesses of the player's transformation will make them a globally known werewolf std::vector closeActors; - MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(actor.getRefData().getPosition().pos), + MWBase::Environment::get().getMechanicsManager()->getActorsInRange(actor.getRefData().getPosition().asVec3(), getStore().get().search("fAlarmRadius")->getFloat(), closeActors); @@ -2695,7 +2673,7 @@ namespace MWWorld MWMechanics::CastSpell cast(actor, target); if (!target.isEmpty()) - cast.mHitPosition = Ogre::Vector3(target.getRefData().getPosition().pos); + cast.mHitPosition = target.getRefData().getPosition().asVec3(); if (!selectedSpell.empty()) { @@ -2718,18 +2696,14 @@ namespace MWWorld void World::launchProjectile (MWWorld::Ptr actor, MWWorld::Ptr projectile, const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr bow, float speed) { -#if 0 mProjectileManager->launchProjectile(actor, projectile, worldPos, orient, bow, speed); -#endif } void World::launchMagicBolt (const std::string& model, const std::string &sound, const std::string &spellId, 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); -#endif } const std::vector& World::getContentFiles() const @@ -3181,7 +3155,7 @@ namespace MWWorld 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) { std::map > toApply; @@ -3200,7 +3174,7 @@ namespace MWWorld else areaStatic = getStore().get().find ("VFX_DefaultArea"); - mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", osg::Vec3f(origin.x, origin.y, origin.z), static_cast(effectIt->mArea)); + mRendering->spawnEffect("meshes\\" + areaStatic->mModel, "", origin, static_cast(effectIt->mArea)); // Play explosion sound (make sure to use NoTrack, since we will delete the projectile now) static const std::string schools[] = { @@ -3209,9 +3183,9 @@ namespace MWWorld { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); 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 - 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 std::vector objects; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b1718f0304..4c4df2c995 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -455,7 +455,7 @@ namespace MWWorld ///Is the head of the creature underwater? virtual bool isSubmerged(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 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, 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, 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 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); virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor); diff --git a/components/esm/projectilestate.hpp b/components/esm/projectilestate.hpp index 51cd5d8c40..38429e4595 100644 --- a/components/esm/projectilestate.hpp +++ b/components/esm/projectilestate.hpp @@ -3,8 +3,8 @@ #include -#include -#include +#include +#include #include "effectlist.hpp" diff --git a/components/esm/util.hpp b/components/esm/util.hpp index bb7f3cf7cd..07a7655c74 100644 --- a/components/esm/util.hpp +++ b/components/esm/util.hpp @@ -4,6 +4,9 @@ #include #include +#include +#include + namespace ESM { @@ -21,11 +24,23 @@ struct Quaternion mValues[2] = q.y; 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 { 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 @@ -39,11 +54,22 @@ struct Vector3 mValues[1] = v.y; 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 { return Ogre::Vector3(&mValues[0]); } + + operator osg::Vec3f () const + { + return osg::Vec3f(mValues[0], mValues[1], mValues[2]); + } }; }