2014-01-05 18:22:29 +01:00
|
|
|
#ifndef GAME_RENDER_NPCANIMATION_H
|
|
|
|
#define GAME_RENDER_NPCANIMATION_H
|
2012-07-17 09:27:12 +02:00
|
|
|
|
2011-11-24 01:48:54 -05:00
|
|
|
#include "animation.hpp"
|
2011-12-11 22:40:00 -05:00
|
|
|
|
2013-11-15 02:08:36 +01:00
|
|
|
#include "../mwworld/inventorystore.hpp"
|
2011-12-11 22:40:00 -05:00
|
|
|
|
2016-10-08 03:49:50 +02:00
|
|
|
#include "actoranimation.hpp"
|
2014-03-12 11:30:44 +01:00
|
|
|
#include "weaponanimation.hpp"
|
|
|
|
|
2012-11-08 13:46:24 +04:00
|
|
|
namespace ESM
|
|
|
|
{
|
|
|
|
struct NPC;
|
2016-02-09 00:26:22 +01:00
|
|
|
struct BodyPart;
|
2012-11-08 13:46:24 +04:00
|
|
|
}
|
|
|
|
|
2013-01-05 21:12:08 -08:00
|
|
|
namespace MWRender
|
|
|
|
{
|
2011-11-24 01:48:54 -05:00
|
|
|
|
2015-05-31 02:26:31 +02:00
|
|
|
class NeckController;
|
2015-06-22 21:12:15 +02:00
|
|
|
class HeadAnimationTime;
|
2015-05-31 02:26:31 +02:00
|
|
|
|
2016-10-08 03:49:50 +02:00
|
|
|
class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener
|
2013-01-06 05:39:39 -08:00
|
|
|
{
|
2013-11-15 02:08:36 +01:00
|
|
|
public:
|
2014-10-11 21:05:12 +02:00
|
|
|
virtual void equipmentChanged();
|
2016-09-15 23:41:20 +09:00
|
|
|
virtual void permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew);
|
2013-11-15 02:08:36 +01:00
|
|
|
|
2013-01-06 05:39:39 -08:00
|
|
|
public:
|
2013-08-05 18:59:55 -07:00
|
|
|
typedef std::map<ESM::PartReferenceType,std::string> PartBoneMap;
|
2013-01-06 01:59:18 -08:00
|
|
|
|
2013-08-05 18:59:55 -07:00
|
|
|
enum ViewMode {
|
|
|
|
VM_Normal,
|
|
|
|
VM_FirstPerson,
|
|
|
|
VM_HeadOnly
|
|
|
|
};
|
2013-04-09 09:07:05 -07:00
|
|
|
|
2012-04-04 23:23:24 -04:00
|
|
|
private:
|
2013-08-05 18:59:55 -07:00
|
|
|
static const PartBoneMap sPartList;
|
2013-01-06 05:39:39 -08:00
|
|
|
|
2013-02-02 02:53:22 -08:00
|
|
|
// Bounded Parts
|
2015-04-15 22:11:38 +02:00
|
|
|
PartHolderPtr mObjectParts[ESM::PRT_Count];
|
2014-10-11 23:18:09 +02:00
|
|
|
std::string mSoundIds[ESM::PRT_Count];
|
2012-11-08 13:46:24 +04:00
|
|
|
|
2013-08-07 16:45:29 -07:00
|
|
|
const ESM::NPC *mNpc;
|
|
|
|
std::string mHeadModel;
|
|
|
|
std::string mHairModel;
|
|
|
|
ViewMode mViewMode;
|
2013-04-28 11:41:01 +01:00
|
|
|
bool mShowWeapons;
|
2013-12-27 22:00:16 +01:00
|
|
|
bool mShowCarriedLeft;
|
2012-11-08 13:46:24 +04:00
|
|
|
|
2014-01-04 20:43:57 +01:00
|
|
|
enum NpcType
|
|
|
|
{
|
|
|
|
Type_Normal,
|
|
|
|
Type_Werewolf,
|
|
|
|
Type_Vampire
|
|
|
|
};
|
|
|
|
NpcType mNpcType;
|
|
|
|
|
2013-08-05 18:59:55 -07:00
|
|
|
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty
|
|
|
|
int mPartPriorities[ESM::PRT_Count];
|
2013-01-06 01:59:18 -08:00
|
|
|
|
2015-05-31 02:26:31 +02:00
|
|
|
osg::Vec3f mFirstPersonOffset;
|
2015-12-07 16:29:30 +01:00
|
|
|
// Field of view to use when rendering first person meshes
|
|
|
|
float mFirstPersonFieldOfView;
|
2013-10-02 05:16:52 -04:00
|
|
|
|
2017-05-05 19:26:09 +02:00
|
|
|
std::shared_ptr<HeadAnimationTime> mHeadAnimationTime;
|
|
|
|
std::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
|
2013-12-07 14:11:06 +01:00
|
|
|
|
2014-10-12 11:40:14 +02:00
|
|
|
bool mSoundsDisabled;
|
2014-10-11 21:05:12 +02:00
|
|
|
|
2015-11-10 01:01:41 +01:00
|
|
|
bool mAccurateAiming;
|
|
|
|
float mAimingFactor;
|
|
|
|
|
2013-08-07 16:21:57 -07:00
|
|
|
void updateNpcBase();
|
|
|
|
|
2020-05-01 17:10:06 +02:00
|
|
|
NpcType getNpcType() const;
|
2019-03-20 11:52:47 +04:00
|
|
|
|
2015-05-20 03:54:04 +02:00
|
|
|
PartHolderPtr insertBoundedPart(const std::string &model, const std::string &bonename,
|
2018-10-09 10:21:12 +04:00
|
|
|
const std::string &bonefilter, bool enchantedGlow, osg::Vec4f* glowColor=nullptr);
|
2013-02-21 23:56:34 +04:00
|
|
|
|
2013-08-05 18:59:55 -07:00
|
|
|
void removeIndividualPart(ESM::PartReferenceType type);
|
|
|
|
void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority);
|
2012-04-23 15:27:03 +02:00
|
|
|
|
2013-11-20 00:07:26 +01:00
|
|
|
bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh,
|
2018-10-09 10:21:12 +04:00
|
|
|
bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr);
|
2012-07-12 20:12:18 -07:00
|
|
|
void removePartGroup(int group);
|
2013-11-20 00:07:26 +01:00
|
|
|
void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts,
|
2018-10-09 10:21:12 +04:00
|
|
|
bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr);
|
2012-09-13 19:03:31 +02:00
|
|
|
|
2015-10-19 22:17:04 +02:00
|
|
|
virtual void setRenderBin();
|
|
|
|
|
2015-05-31 02:26:31 +02:00
|
|
|
osg::ref_ptr<NeckController> mFirstPersonNeckController;
|
|
|
|
|
2017-04-17 21:53:35 +04:00
|
|
|
static bool isFirstPersonPart(const ESM::BodyPart* bodypart);
|
|
|
|
static bool isFemalePart(const ESM::BodyPart* bodypart);
|
2020-05-01 17:10:06 +02:00
|
|
|
static NpcType getNpcType(const MWWorld::Ptr& ptr);
|
2017-04-17 21:53:35 +04:00
|
|
|
|
2015-05-31 02:26:31 +02:00
|
|
|
protected:
|
|
|
|
virtual void addControllers();
|
2018-03-03 14:16:21 +04:00
|
|
|
virtual bool isArrowAttached() const;
|
2019-08-11 15:01:48 +04:00
|
|
|
virtual std::string getShieldMesh(MWWorld::ConstPtr shield) const;
|
2015-05-31 02:26:31 +02:00
|
|
|
|
2013-01-09 07:55:55 -08:00
|
|
|
public:
|
2013-11-15 02:08:36 +01:00
|
|
|
/**
|
|
|
|
* @param ptr
|
|
|
|
* @param disableListener Don't listen for equipment changes and magic effects. InventoryStore only supports
|
|
|
|
* one listener at a time, so you shouldn't do this if creating several NpcAnimations
|
|
|
|
* for the same Ptr, eg preview dolls for the player.
|
|
|
|
* Those need to be manually rendered anyway.
|
2014-10-12 11:40:14 +02:00
|
|
|
* @param disableSounds Same as \a disableListener but for playing items sounds
|
2013-11-15 02:08:36 +01:00
|
|
|
* @param viewMode
|
|
|
|
*/
|
2017-02-22 14:54:40 +01:00
|
|
|
NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
|
2015-12-07 16:29:30 +01:00
|
|
|
bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f);
|
2013-01-09 07:55:55 -08:00
|
|
|
virtual ~NpcAnimation();
|
|
|
|
|
2014-08-11 05:00:13 +02:00
|
|
|
virtual void enableHeadAnimation(bool enable);
|
|
|
|
|
2015-11-10 01:01:41 +01:00
|
|
|
/// 1: the first person meshes follow the camera's rotation completely
|
|
|
|
/// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands
|
|
|
|
virtual void setAccurateAiming(bool enabled);
|
|
|
|
|
2019-03-05 13:33:58 +04:00
|
|
|
virtual void setWeaponGroup(const std::string& group, bool relativeDuration);
|
2014-02-04 03:46:15 +01:00
|
|
|
|
2015-04-19 14:42:09 +02:00
|
|
|
virtual osg::Vec3f runAnimation(float timepassed);
|
2013-01-09 07:55:55 -08:00
|
|
|
|
2014-02-04 04:00:52 +01:00
|
|
|
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched
|
|
|
|
/// to indicate the facing orientation of the character.
|
|
|
|
virtual void setPitchFactor(float factor) { mPitchFactor = factor; }
|
|
|
|
|
2013-04-28 11:41:01 +01:00
|
|
|
virtual void showWeapons(bool showWeapon);
|
2020-04-04 19:20:52 +03:00
|
|
|
|
|
|
|
virtual bool getCarriedLeftShown() const { return mShowCarriedLeft; }
|
2014-12-12 16:49:22 +01:00
|
|
|
virtual void showCarriedLeft(bool show);
|
2013-04-28 11:41:01 +01:00
|
|
|
|
2014-02-04 04:11:46 +01:00
|
|
|
virtual void attachArrow();
|
2015-06-26 05:15:07 +02:00
|
|
|
virtual void releaseArrow(float attackStrength);
|
2014-02-04 04:11:46 +01:00
|
|
|
|
2015-05-31 01:07:43 +02:00
|
|
|
virtual osg::Group* getArrowBone();
|
|
|
|
virtual osg::Node* getWeaponNode();
|
|
|
|
virtual Resource::ResourceSystem* getResourceSystem();
|
|
|
|
|
2014-03-12 11:30:44 +01:00
|
|
|
// WeaponAnimation
|
|
|
|
virtual void showWeapon(bool show) { showWeapons(show); }
|
2014-02-04 04:11:46 +01:00
|
|
|
|
2013-04-09 15:10:14 -07:00
|
|
|
void setViewMode(ViewMode viewMode);
|
|
|
|
|
2013-11-14 14:41:10 +01:00
|
|
|
void updateParts();
|
2013-08-08 17:16:24 -07:00
|
|
|
|
|
|
|
/// Rebuilds the NPC, updating their root model, animation sources, and equipment.
|
|
|
|
void rebuild();
|
2013-12-08 23:05:21 +01:00
|
|
|
|
2015-05-20 03:35:52 +02:00
|
|
|
/// Get the inventory slot that the given node path leads into, or -1 if not found.
|
|
|
|
int getSlot(const osg::NodePath& path) const;
|
|
|
|
|
2014-12-12 02:39:59 +01:00
|
|
|
virtual void setVampire(bool vampire);
|
2015-05-14 17:34:55 +02:00
|
|
|
|
2015-05-31 02:26:31 +02:00
|
|
|
/// Set a translation offset (in object root space) to apply to meshes when in first person mode.
|
|
|
|
void setFirstPersonOffset(const osg::Vec3f& offset);
|
|
|
|
|
2015-05-14 17:34:55 +02:00
|
|
|
virtual void updatePtr(const MWWorld::Ptr& updated);
|
2016-02-09 00:26:22 +01:00
|
|
|
|
|
|
|
/// Get a list of body parts that may be used by an NPC of given race and gender.
|
2018-10-09 10:21:12 +04:00
|
|
|
/// @note This is a fixed size list, one list item for each ESM::PartReferenceType, may contain nullptr body parts.
|
2016-02-09 00:26:22 +01:00
|
|
|
static const std::vector<const ESM::BodyPart*>& getBodyParts(const std::string& raceId, bool female, bool firstperson, bool werewolf);
|
2011-11-24 01:48:54 -05:00
|
|
|
};
|
2012-07-12 20:12:18 -07:00
|
|
|
|
2011-11-24 01:48:54 -05:00
|
|
|
}
|
2013-01-05 21:12:08 -08:00
|
|
|
|
2012-04-23 15:27:03 +02:00
|
|
|
#endif
|