metaforce/DataSpec/DNAMP1/ANCS.hpp

518 lines
17 KiB
C++
Raw Normal View History

2015-08-08 04:49:42 +00:00
#ifndef _DNAMP1_ANCS_HPP_
#define _DNAMP1_ANCS_HPP_
2015-08-13 07:29:00 +00:00
#include <map>
2015-08-08 04:49:42 +00:00
#include "../DNACommon/DNACommon.hpp"
2015-08-11 23:32:02 +00:00
#include "../DNACommon/ANCS.hpp"
#include "CMDLMaterials.hpp"
2015-08-13 07:29:00 +00:00
#include "CINF.hpp"
#include "CSKR.hpp"
#include "ANIM.hpp"
2016-04-09 23:19:17 +00:00
#include "EVNT.hpp"
2016-03-04 23:04:53 +00:00
#include "athena/FileReader.hpp"
2015-08-08 04:49:42 +00:00
2017-12-29 08:08:12 +00:00
namespace DataSpec::DNAMP1
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
struct ANCS : BigDNA
2015-08-08 04:49:42 +00:00
{
2015-08-13 07:29:00 +00:00
using CINFType = CINF;
using CSKRType = CSKR;
using ANIMType = ANIM;
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint16> version;
2018-02-22 07:24:51 +00:00
struct CharacterSet : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint16> version;
Value<atUint32> characterCount;
2018-02-22 07:24:51 +00:00
struct CharacterInfo : BigDNA
2016-04-07 03:40:25 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Delete expl;
atUint32 idx;
std::string name;
UniqueID32 cmdl;
2016-04-07 03:40:25 +00:00
UniqueID32 cskr;
UniqueID32 cinf;
2015-08-08 04:49:42 +00:00
2018-02-22 07:24:51 +00:00
struct Animation : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint32> animIdx;
String<-1> strA;
String<-1> strB;
};
std::vector<Animation> animations;
2018-02-22 07:24:51 +00:00
struct PASDatabase : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint32> magic;
Value<atUint32> animStateCount;
Value<atUint32> defaultState;
2018-02-22 07:24:51 +00:00
struct AnimState : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Delete expl;
atUint32 id;
2018-02-22 07:24:51 +00:00
struct ParmInfo : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Delete expl;
2015-11-21 01:16:07 +00:00
enum class DataType
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
Int32 = 0,
UInt32 = 1,
Float = 2,
Bool = 3,
Enum = 4
2015-08-08 04:49:42 +00:00
};
union Parm
{
atInt32 int32;
atUint32 uint32;
float float32;
bool bool1;
Parm() : int32(0) {}
Parm(atInt32 val) : int32(val) {}
Parm(atUint32 val) : uint32(val) {}
Parm(float val) : float32(val) {}
Parm(bool val) : bool1(val) {}
};
atUint32 parmType;
2017-07-06 21:06:56 +00:00
atUint32 weightFunction;
float weight;
Parm range[2];
2015-08-08 04:49:42 +00:00
};
std::vector<ParmInfo> parmInfos;
struct AnimInfo
{
atUint32 id;
std::vector<ParmInfo::Parm> parmVals;
};
std::vector<AnimInfo> animInfos;
};
2018-02-25 08:23:27 +00:00
Vector<AnimState, AT_DNA_COUNT(animStateCount)> animStates;
2015-08-08 04:49:42 +00:00
} pasDatabase;
struct ParticleResData
{
std::vector<UniqueID32> part;
std::vector<UniqueID32> swhc;
std::vector<UniqueID32> unk;
std::vector<UniqueID32> elsc;
} partResData;
2015-08-08 23:24:17 +00:00
atUint32 unk1 = 0;
2015-08-08 04:49:42 +00:00
2018-02-22 07:24:51 +00:00
struct ActionAABB : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
String<-1> name;
Value<atVec3f> aabb[2];
};
std::vector<ActionAABB> animAABBs;
2018-02-22 07:24:51 +00:00
struct Effect : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
String<-1> name;
Value<atUint32> compCount;
2018-02-22 07:24:51 +00:00
struct EffectComponent : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
String<-1> name;
2015-08-23 06:42:29 +00:00
DNAFourCC type;
2015-08-08 04:49:42 +00:00
UniqueID32 id;
2016-04-08 03:24:53 +00:00
String<-1> locator;
2016-05-03 08:27:28 +00:00
Value<float> scale;
Value<atUint32> parentMode;
Value<atUint32> flags;
2015-08-08 04:49:42 +00:00
};
2018-02-25 08:23:27 +00:00
Vector<EffectComponent, AT_DNA_COUNT(compCount)> comps;
2015-08-08 04:49:42 +00:00
};
std::vector<Effect> effects;
2015-09-26 03:12:08 +00:00
UniqueID32 cmdlOverlay;
2016-04-07 03:40:25 +00:00
UniqueID32 cskrOverlay;
2015-08-08 04:49:42 +00:00
std::vector<atUint32> animIdxs;
};
2018-02-25 08:23:27 +00:00
Vector<CharacterInfo, AT_DNA_COUNT(characterCount)> characters;
2015-08-08 04:49:42 +00:00
} characterSet;
2018-02-22 07:24:51 +00:00
struct AnimationSet : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Delete expl;
2016-04-07 03:40:25 +00:00
struct MetaAnimPrimitive;
2018-02-22 07:24:51 +00:00
struct IMetaAnim : BigDNAVYaml
2015-08-08 04:49:42 +00:00
{
Delete expl;
2015-11-21 01:16:07 +00:00
enum class Type
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
Primitive = 0,
Blend = 1,
PhaseBlend = 2,
Random = 3,
Sequence = 4
2015-08-08 04:49:42 +00:00
} m_type;
const char* m_typeStr;
2016-04-07 03:40:25 +00:00
IMetaAnim(Type type, const char* typeStr)
: m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)=0;
2016-04-07 03:40:25 +00:00
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)=0;
2015-08-08 04:49:42 +00:00
};
2018-02-22 07:24:51 +00:00
struct MetaAnimFactory : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_EXPLICIT_DNA_YAML
2015-08-08 04:49:42 +00:00
std::unique_ptr<IMetaAnim> m_anim;
};
struct MetaAnimPrimitive : IMetaAnim
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2016-04-07 03:40:25 +00:00
MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {}
2015-08-08 04:49:42 +00:00
UniqueID32 animId;
Value<atUint32> animIdx;
String<-1> animName;
Value<float> unk1;
Value<atUint32> unk2;
2015-08-11 23:32:02 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
2015-08-11 23:32:02 +00:00
{
2015-10-27 00:32:12 +00:00
out[animIdx] = {animName, animId, UniqueID32(), false};
2015-08-11 23:32:02 +00:00
}
2016-04-07 03:40:25 +00:00
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
return func(*this);
}
2015-08-08 04:49:42 +00:00
};
struct MetaAnimBlend : IMetaAnim
{
2016-04-07 03:40:25 +00:00
MetaAnimBlend()
: IMetaAnim(Type::Blend, "Blend") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2015-08-08 04:49:42 +00:00
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
2015-08-11 23:32:02 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
2015-08-11 23:32:02 +00:00
{
animA.m_anim->gatherPrimitives(out);
animB.m_anim->gatherPrimitives(out);
}
2016-04-07 03:40:25 +00:00
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
2015-08-08 04:49:42 +00:00
};
struct MetaAnimPhaseBlend : IMetaAnim
{
2016-04-07 03:40:25 +00:00
MetaAnimPhaseBlend()
: IMetaAnim(Type::PhaseBlend, "PhaseBlend") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2015-08-08 04:49:42 +00:00
MetaAnimFactory animA;
MetaAnimFactory animB;
Value<float> unkFloat;
Value<atUint8> unk;
2015-08-11 23:32:02 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
2015-08-11 23:32:02 +00:00
{
animA.m_anim->gatherPrimitives(out);
animB.m_anim->gatherPrimitives(out);
}
2016-04-07 03:40:25 +00:00
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
if (!animA.m_anim->enumeratePrimitives(func))
return false;
if (!animB.m_anim->enumeratePrimitives(func))
return false;
return true;
}
2015-08-08 04:49:42 +00:00
};
struct MetaAnimRandom : IMetaAnim
{
2016-04-07 03:40:25 +00:00
MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2015-08-08 04:49:42 +00:00
Value<atUint32> animCount;
2018-02-22 07:24:51 +00:00
struct Child : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA
2015-08-08 04:49:42 +00:00
MetaAnimFactory anim;
Value<atUint32> probability;
};
2018-02-25 08:23:27 +00:00
Vector<Child, AT_DNA_COUNT(animCount)> children;
2015-08-11 23:32:02 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
2015-08-11 23:32:02 +00:00
{
for (const auto& child : children)
child.anim.m_anim->gatherPrimitives(out);
}
2016-04-07 03:40:25 +00:00
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
for (auto& child : children)
if (!child.anim.m_anim->enumeratePrimitives(func))
return false;
return true;
}
2015-08-08 04:49:42 +00:00
};
struct MetaAnimSequence : IMetaAnim
{
2016-04-07 03:40:25 +00:00
MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2015-08-08 04:49:42 +00:00
Value<atUint32> animCount;
2018-02-25 08:23:27 +00:00
Vector<MetaAnimFactory, AT_DNA_COUNT(animCount)> children;
2015-08-11 23:32:02 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
2015-08-11 23:32:02 +00:00
{
for (const auto& child : children)
child.m_anim->gatherPrimitives(out);
}
2016-04-07 03:40:25 +00:00
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
for (auto& child : children)
if (!child.m_anim->enumeratePrimitives(func))
return false;
return true;
}
2015-08-08 04:49:42 +00:00
};
2018-02-22 07:24:51 +00:00
struct Animation : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
String<-1> name;
MetaAnimFactory metaAnim;
};
std::vector<Animation> animations;
2018-02-22 07:24:51 +00:00
struct IMetaTrans : BigDNAVYaml
2015-08-08 04:49:42 +00:00
{
Delete expl;
2015-11-21 01:16:07 +00:00
enum class Type
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
MetaAnim = 0,
Trans = 1,
PhaseTrans = 2,
NoTrans = 3,
2015-08-08 04:49:42 +00:00
} m_type;
const char* m_typeStr;
2016-04-07 03:40:25 +00:00
IMetaTrans(Type type, const char* typeStr)
: m_type(type), m_typeStr(typeStr) {}
virtual void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) {}
virtual bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func) {return true;}
2015-08-08 04:49:42 +00:00
};
2018-02-22 07:24:51 +00:00
struct MetaTransFactory : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Delete expl;
std::unique_ptr<IMetaTrans> m_trans;
};
struct MetaTransMetaAnim : IMetaTrans
{
2016-04-07 03:40:25 +00:00
MetaTransMetaAnim()
: IMetaTrans(Type::MetaAnim, "MetaAnim") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2015-08-08 04:49:42 +00:00
MetaAnimFactory anim;
2016-04-07 03:40:25 +00:00
void gatherPrimitives(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out)
{
anim.m_anim->gatherPrimitives(out);
}
bool enumeratePrimitives(const std::function<bool(MetaAnimPrimitive& prim)>& func)
{
return anim.m_anim->enumeratePrimitives(func);
}
2015-08-08 04:49:42 +00:00
};
struct MetaTransTrans : IMetaTrans
{
2016-04-07 03:40:25 +00:00
MetaTransTrans()
: IMetaTrans(Type::Trans, "Trans") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2018-01-10 06:20:34 +00:00
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
2015-08-08 04:49:42 +00:00
};
struct MetaTransPhaseTrans : IMetaTrans
{
2016-04-07 03:40:25 +00:00
MetaTransPhaseTrans()
: IMetaTrans(Type::PhaseTrans, "PhaseTrans") {}
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
AT_DECL_DNAV
2018-01-10 06:20:34 +00:00
Value<float> transDurTime;
Value<atUint32> transDurTimeMode;
Value<bool> unk2;
Value<bool> runA;
Value<atUint32> flags;
2015-08-08 04:49:42 +00:00
};
2018-02-22 07:24:51 +00:00
struct Transition : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint32> unk;
Value<atUint32> animIdxA;
Value<atUint32> animIdxB;
MetaTransFactory metaTrans;
};
std::vector<Transition> transitions;
2015-08-08 23:24:17 +00:00
MetaTransFactory defaultTransition;
2015-08-08 04:49:42 +00:00
2018-02-22 07:24:51 +00:00
struct AdditiveAnimationInfo : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint32> animIdx;
Value<float> unk1;
Value<float> unk2;
};
std::vector<AdditiveAnimationInfo> additiveAnims;
float floatA = 0.0;
float floatB = 0.0;
2018-02-22 07:24:51 +00:00
struct HalfTransition : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
Value<atUint32> animIdx;
MetaTransFactory metaTrans;
};
std::vector<HalfTransition> halfTransitions;
2018-02-22 07:24:51 +00:00
struct AnimationResources : BigDNA
2015-08-08 04:49:42 +00:00
{
2018-02-22 07:24:51 +00:00
AT_DECL_DNA_YAML
2015-08-08 04:49:42 +00:00
UniqueID32 animId;
UniqueID32 evntId;
};
2015-08-08 04:58:50 +00:00
std::vector<AnimationResources> animResources;
2015-08-08 04:49:42 +00:00
} animationSet;
2015-08-08 23:24:17 +00:00
2015-08-11 23:32:02 +00:00
void getCharacterResInfo(std::vector<DNAANCS::CharacterResInfo<UniqueID32>>& out) const
{
out.clear();
out.reserve(characterSet.characters.size());
for (const CharacterSet::CharacterInfo& ci : characterSet.characters)
{
out.emplace_back();
DNAANCS::CharacterResInfo<UniqueID32>& chOut = out.back();
chOut.name = ci.name;
chOut.cmdl = ci.cmdl;
2016-04-07 03:40:25 +00:00
chOut.cskr = ci.cskr;
chOut.cinf = ci.cinf;
2015-09-27 02:24:03 +00:00
if (ci.cmdlOverlay)
2016-04-07 03:40:25 +00:00
chOut.overlays.emplace_back(FOURCC('OVER'), std::make_pair(ci.cmdlOverlay, ci.cskrOverlay));
2015-08-11 23:32:02 +00:00
}
}
void getAnimationResInfo(std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>>& out) const
2015-08-11 23:32:02 +00:00
{
out.clear();
for (const AnimationSet::Animation& ai : animationSet.animations)
2017-02-12 23:56:03 +00:00
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->gatherPrimitives(out);
2016-04-07 03:40:25 +00:00
for (const AnimationSet::Transition& ti : animationSet.transitions)
2017-02-12 23:56:03 +00:00
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->gatherPrimitives(out);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->gatherPrimitives(out);
2015-10-27 00:32:12 +00:00
for (auto& anim : out)
{
for (const AnimationSet::AnimationResources& res : animationSet.animResources)
{
if (res.animId == anim.second.animId)
{
anim.second.evntId = res.evntId;
break;
}
}
}
2015-08-11 23:32:02 +00:00
}
2016-04-07 03:40:25 +00:00
void enumeratePrimitives(const std::function<bool(AnimationSet::MetaAnimPrimitive& prim)>& func)
{
2016-04-07 03:40:25 +00:00
for (const AnimationSet::Animation& ai : animationSet.animations)
2017-02-12 23:56:03 +00:00
if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get())
anim->enumeratePrimitives(func);
2016-04-07 03:40:25 +00:00
for (const AnimationSet::Transition& ti : animationSet.transitions)
2017-02-12 23:56:03 +00:00
if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get())
trans->enumeratePrimitives(func);
if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get())
trans->enumeratePrimitives(func);
}
2017-11-15 04:12:13 +00:00
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
for (const CharacterSet::CharacterInfo& ci : characterSet.characters)
{
for (const auto& id : ci.partResData.part)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.swhc)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.unk)
g_curSpec->flattenDependencies(id, pathsOut);
for (const auto& id : ci.partResData.elsc)
g_curSpec->flattenDependencies(id, pathsOut);
}
}
2015-09-06 21:44:57 +00:00
static bool Extract(const SpecBase& dataSpec,
2015-08-11 23:32:02 +00:00
PAKEntryReadStream& rs,
2016-03-04 23:04:53 +00:00
const hecl::ProjectPath& outPath,
2015-08-11 23:32:02 +00:00
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
2017-12-29 08:08:12 +00:00
hecl::blender::Token& btok,
2016-04-10 04:49:02 +00:00
std::function<void(const hecl::SystemChar*)> fileChanged);
2015-10-23 00:45:26 +00:00
2016-03-04 23:04:53 +00:00
static bool Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor);
static bool CookCSKR(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookANIM(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
2017-12-29 08:08:12 +00:00
hecl::blender::DataStream& ds,
bool pc);
2015-08-08 04:49:42 +00:00
};
}
#endif // _DNAMP1_ANCS_HPP_