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"
|
|
|
|
|
2020-06-28 22:50:06 +02:00
|
|
|
#include <array>
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-06-28 22:50:06 +02:00
|
|
|
namespace MWSound
|
|
|
|
{
|
|
|
|
class Sound;
|
|
|
|
}
|
|
|
|
|
2013-01-05 21:12:08 -08:00
|
|
|
namespace MWRender
|
|
|
|
{
|
2011-11-24 01:48:54 -05:00
|
|
|
|
2021-10-05 12:21:12 +00:00
|
|
|
class RotateController;
|
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:
|
2020-10-16 22:18:54 +04:00
|
|
|
void equipmentChanged() override;
|
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];
|
2020-06-28 22:50:06 +02:00
|
|
|
std::array<MWSound::Sound*, ESM::PRT_Count> mSounds;
|
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
|
|
|
|
2022-08-21 18:53:38 +02:00
|
|
|
PartHolderPtr insertBoundedPart(const std::string& model, std::string_view bonename,
|
|
|
|
std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight);
|
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,
|
2021-11-02 18:01:22 +01:00
|
|
|
bool enchantedGlow = false, osg::Vec4f* glowColor = nullptr, bool isLight = false);
|
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
|
|
|
|
2020-05-12 13:37:00 +00:00
|
|
|
void setRenderBin();
|
2015-10-19 22:17:04 +02:00
|
|
|
|
2021-10-05 12:21:12 +00:00
|
|
|
osg::ref_ptr<RotateController> mFirstPersonNeckController;
|
2015-05-31 02:26:31 +02:00
|
|
|
|
2017-04-17 21:53:35 +04:00
|
|
|
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:
|
2020-10-16 22:18:54 +04:00
|
|
|
void addControllers() override;
|
|
|
|
bool isArrowAttached() const override;
|
2021-11-01 19:33:29 +01:00
|
|
|
std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const override;
|
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,
|
2015-12-07 16:29:30 +01:00
|
|
|
Resource::ResourceSystem* resourceSystem, bool disableSounds = false, ViewMode viewMode = VM_Normal,
|
|
|
|
float firstPersonFieldOfView = 55.f);
|
2013-01-09 07:55:55 -08:00
|
|
|
virtual ~NpcAnimation();
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void enableHeadAnimation(bool enable) override;
|
2014-08-11 05:00:13 +02:00
|
|
|
|
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
|
2020-10-16 22:18:54 +04:00
|
|
|
void setAccurateAiming(bool enabled) override;
|
2015-11-10 01:01:41 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void setWeaponGroup(const std::string& group, bool relativeDuration) override;
|
2014-02-04 03:46:15 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
osg::Vec3f runAnimation(float timepassed) override;
|
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.
|
2020-10-16 22:18:54 +04:00
|
|
|
void setPitchFactor(float factor) override { mPitchFactor = factor; }
|
2014-02-04 04:00:52 +01:00
|
|
|
|
2022-08-18 05:04:51 +03:00
|
|
|
bool getWeaponsShown() const override { return mShowWeapons; }
|
2020-10-16 22:18:54 +04:00
|
|
|
void showWeapons(bool showWeapon) override;
|
2020-04-04 19:20:52 +03:00
|
|
|
|
2022-08-04 05:32:10 +03:00
|
|
|
bool updateCarriedLeftVisible(const int weaptype) const override;
|
2020-10-16 22:18:54 +04:00
|
|
|
bool getCarriedLeftShown() const override { return mShowCarriedLeft; }
|
|
|
|
void showCarriedLeft(bool show) override;
|
2013-04-28 11:41:01 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void attachArrow() override;
|
|
|
|
void detachArrow() override;
|
|
|
|
void releaseArrow(float attackStrength) override;
|
2014-02-04 04:11:46 +01:00
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
osg::Group* getArrowBone() override;
|
|
|
|
osg::Node* getWeaponNode() override;
|
|
|
|
Resource::ResourceSystem* getResourceSystem() override;
|
2015-05-31 01:07:43 +02:00
|
|
|
|
2014-03-12 11:30:44 +01:00
|
|
|
// WeaponAnimation
|
2020-10-16 22:18:54 +04:00
|
|
|
void showWeapon(bool show) override { 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;
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void setVampire(bool vampire) override;
|
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);
|
|
|
|
|
2020-10-16 22:18:54 +04:00
|
|
|
void updatePtr(const MWWorld::Ptr& updated) override;
|
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(
|
Initial commit: In ESM structures, replace the string members that are RefIds to other records, to a new strong type
The strong type is actually just a string underneath, but this will help in the future to have a distinction so it's easier to search and replace when we use an integer ID
Slowly going through all the changes to make, still hundreds of errors
a lot of functions/structures use std::string or stringview to designate an ID. So it takes time
Continues slowly replacing ids. There are technically more and more compilation errors
I have good hope that there is a point where the amount of errors will dramatically go down as all the main functions use the ESM::RefId type
Continue moving forward, changes to the stores
slowly moving along
Starting to see the fruit of those changes.
still many many error, but more and more Irun into a situation where a function is sandwiched between two functions that use the RefId type.
More replacements. Things are starting to get easier
I can see more and more often the issue is that the function is awaiting a RefId, but is given a string
there is less need to go down functions and to fix a long list of them.
Still moving forward, and for the first time error count is going down!
Good pace, not sure about topics though, mId and mName are actually the same thing and are used interchangeably
Cells are back to using string for the name, haven't fixed everything yet. Many other changes
Under the bar of 400 compilation errors.
more good progress <100 compile errors!
More progress
Game settings store can use string for find, it was a bit absurd how every use of it required to create refId from string
some more progress on other fronts
Mostly game settings clean
one error opened a lot of other errors. Down to 18, but more will prbably appear
only link errors left??
Fixed link errors
OpenMW compiles, and launches, with some issues, but still!
2022-09-25 13:17:09 +02:00
|
|
|
const ESM::RefId& 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
|