metaforce/Runtime/Graphics/CModel.hpp

269 lines
9.4 KiB
C++
Raw Normal View History

2016-04-13 06:07:23 +00:00
#ifndef __URDE_CMODEL_HPP__
#define __URDE_CMODEL_HPP__
2016-02-13 00:57:09 +00:00
#include "RetroTypes.hpp"
2016-03-04 23:04:53 +00:00
#include "zeus/CColor.hpp"
2016-03-29 23:14:14 +00:00
#include "CFactoryMgr.hpp"
#include "CToken.hpp"
#include "zeus/CAABox.hpp"
2016-03-31 02:44:43 +00:00
#include "DNACommon/CMDL.hpp"
#include "DNAMP1/CMDLMaterials.hpp"
2016-07-21 05:21:45 +00:00
#include "Shaders/CModelShaders.hpp"
2016-02-13 00:57:09 +00:00
2016-03-30 19:16:01 +00:00
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
2016-03-04 23:04:53 +00:00
namespace urde
2016-02-13 00:57:09 +00:00
{
2016-03-29 23:14:14 +00:00
class IObjectStore;
class CTexture;
2016-04-04 02:32:57 +00:00
class CLight;
2016-08-21 20:39:18 +00:00
class CSkinRules;
class CPoseAsTransforms;
class CModel;
2016-02-13 00:57:09 +00:00
struct CModelFlags
{
2017-05-06 05:21:42 +00:00
u8 x0_blendMode = 0; /* >6: additive, >4: blend, else opaque */
2017-03-20 05:09:53 +00:00
u8 x1_matSetIdx = 0;
2017-03-10 20:52:53 +00:00
EExtendedShader m_extendedShader = EExtendedShader::Flat;
2017-03-20 05:09:53 +00:00
u16 x2_flags = 0; /* Flags */
zeus::CColor x4_color; /* Set into kcolor slot specified by material */
2016-07-31 04:46:03 +00:00
zeus::CColor addColor = zeus::CColor::skClear;
2017-03-06 06:33:51 +00:00
zeus::CAABox mbShadowBox;
2016-03-17 02:18:01 +00:00
2016-04-03 05:25:34 +00:00
CModelFlags() = default;
CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col)
2017-05-30 03:45:31 +00:00
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col)
{
if (blendMode > 6)
m_extendedShader = EExtendedShader::ForcedAdditive;
else if (blendMode > 4)
m_extendedShader = EExtendedShader::ForcedAlpha;
else
m_extendedShader = EExtendedShader::Lighting;
}
2016-04-03 05:25:34 +00:00
2016-03-31 06:18:56 +00:00
/* Flags
2017-05-06 05:21:42 +00:00
0x1: depth equal
0x2: depth update
2016-03-31 02:44:43 +00:00
0x4: render without texture lock
2016-03-31 06:18:56 +00:00
0x8: depth greater
0x10: depth non-inclusive
2016-03-17 02:18:01 +00:00
*/
2016-02-13 00:57:09 +00:00
};
2016-03-31 02:44:43 +00:00
/* urde addition: doesn't require hacky stashing of
* pointers within loaded CMDL buffer */
struct CBooSurface
2016-03-30 19:16:01 +00:00
{
2016-04-04 02:32:57 +00:00
DataSpec::DNACMDL::SurfaceHeader_2 m_data;
size_t selfIdx;
2016-03-31 02:44:43 +00:00
class CBooModel* m_parent = nullptr;
CBooSurface* m_next = nullptr;
2016-07-26 22:05:59 +00:00
zeus::CAABox GetBounds() const
{
if (!m_data.aabbSz)
return zeus::CAABox(m_data.centroid, m_data.centroid);
else
return zeus::CAABox(m_data.aabb[0], m_data.aabb[1]);
}
2016-03-30 19:16:01 +00:00
};
2016-03-29 23:14:14 +00:00
class CBooModel
{
2016-03-31 06:18:56 +00:00
friend class CModel;
2016-07-25 22:52:02 +00:00
friend class CBooRenderer;
2016-08-03 21:53:03 +00:00
friend class CMetroidModelInstance;
2016-08-21 20:39:18 +00:00
friend class CSkinnedModel;
2016-03-29 23:14:14 +00:00
public:
2016-03-31 06:18:56 +00:00
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
using UVAnimation = DataSpec::DNAMP1::MaterialSet::Material::UVAnimation;
2016-03-31 02:44:43 +00:00
struct SShader
2016-03-29 23:14:14 +00:00
{
2016-03-31 02:44:43 +00:00
std::vector<TCachedToken<CTexture>> x0_textures;
2016-09-12 04:53:28 +00:00
std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>> m_shaders;
2016-03-31 06:18:56 +00:00
MaterialSet m_matSet;
int m_matSetIdx;
SShader(int idx) : m_matSetIdx(idx) {}
2016-03-31 02:44:43 +00:00
void UnlockTextures();
2016-03-29 23:14:14 +00:00
};
2016-03-31 02:44:43 +00:00
2017-05-06 05:21:42 +00:00
enum class ESurfaceSelection
{
UnsortedOnly,
SortedOnly,
All
};
2016-03-29 23:14:14 +00:00
private:
2016-09-09 04:19:19 +00:00
CBooModel* m_next = nullptr;
CBooModel* m_prev = nullptr;
size_t m_uniUpdateCount = 0;
TLockedToken<CModel> m_model;
2016-03-31 02:44:43 +00:00
std::vector<CBooSurface>* x0_surfaces;
2016-03-31 06:18:56 +00:00
const MaterialSet* x4_matSet;
int m_matSetIdx = -1;
2016-09-12 04:53:28 +00:00
const std::vector<std::shared_ptr<hecl::Runtime::ShaderPipelines>>* m_pipelines;
std::vector<TCachedToken<CTexture>> x1c_textures;
2016-03-29 23:14:14 +00:00
zeus::CAABox x20_aabb;
2016-03-31 02:44:43 +00:00
CBooSurface* x38_firstUnsortedSurface = nullptr;
CBooSurface* x3c_firstSortedSurface = nullptr;
bool x40_24_texturesLoaded : 1;
2016-07-27 23:06:57 +00:00
bool x40_25_modelVisible : 1;
u8 x41_mask;
u32 x44_areaInstanceIdx = -1;
2016-03-30 19:16:01 +00:00
2016-03-31 06:18:56 +00:00
struct UVAnimationBuffer
{
2016-04-04 02:32:57 +00:00
static void ProcessAnimation(u8*& bufOut, const UVAnimation& anim);
static void PadOutBuffer(u8*& bufStart, u8*& bufOut);
2016-07-31 02:06:47 +00:00
static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags);
2016-04-04 02:32:57 +00:00
};
CModelShaders::LightingUniform m_lightingData;
2016-03-31 06:18:56 +00:00
2016-03-30 19:16:01 +00:00
/* urde addition: boo! */
2016-04-04 02:32:57 +00:00
size_t m_uniformDataSize = 0;
2016-09-09 04:19:19 +00:00
struct ModelInstance
{
boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferD* m_uniformBuffer;
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings;
boo::IVertexFormat* m_dynamicVtxFmt = nullptr;
boo::IGraphicsBufferD* m_dynamicVbo = nullptr;
boo::IGraphicsBuffer* GetBooVBO(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx);
boo::IVertexFormat* GetBooVtxFmt(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx);
2016-09-09 04:19:19 +00:00
};
std::vector<ModelInstance> m_instances;
2016-03-30 19:16:01 +00:00
boo::IVertexFormat* m_staticVtxFmt = nullptr;
boo::IGraphicsBufferS* m_staticVbo = nullptr;
boo::IGraphicsBufferS* m_staticIbo = nullptr;
boo::ITexture* m_txtrOverrides[8] = {};
2016-09-09 04:19:19 +00:00
ModelInstance* PushNewModelInstance();
2016-03-30 19:16:01 +00:00
void DrawAlphaSurfaces(const CModelFlags& flags) const;
void DrawNormalSurfaces(const CModelFlags& flags) const;
void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
static zeus::CVector3f g_PlayerPosition;
static float g_ModSeconds;
static float g_TransformedTime;
static float g_TransformedTime2;
static CBooModel* g_LastModelCached;
2016-03-29 23:14:14 +00:00
public:
2016-09-09 04:19:19 +00:00
~CBooModel();
CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
2016-03-31 02:44:43 +00:00
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
const zeus::CAABox& aabb, u8 renderMask,
int numInsts, boo::ITexture* txtrOverrides[8]);
2016-03-29 23:14:14 +00:00
static void MakeTexturesFromMats(const MaterialSet& matSet,
std::vector<TCachedToken<CTexture>>& toksOut,
IObjectStore& store);
void MakeTexturesFromMats(std::vector<TCachedToken<CTexture>>& toksOut,
IObjectStore& store);
2016-03-29 23:14:14 +00:00
2016-04-14 21:42:47 +00:00
bool IsOpaque() const {return x3c_firstSortedSurface == nullptr;}
2016-04-04 02:32:57 +00:00
void ActivateLights(const std::vector<CLight>& lights);
2017-05-06 05:21:42 +00:00
void DisableAllLights();
2016-03-31 02:44:43 +00:00
void RemapMaterialData(SShader& shader);
bool TryLockTextures() const;
2016-03-30 19:16:01 +00:00
void UnlockTextures() const;
void Touch(int shaderIdx) const;
2017-03-05 07:57:12 +00:00
void VerifyCurrentShader(int shaderIdx);
boo::IGraphicsBufferD* UpdateUniformData(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const;
2016-08-21 20:39:18 +00:00
void DrawAlpha(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const;
void DrawNormal(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const;
void Draw(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const;
2017-05-06 05:21:42 +00:00
void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const;
2016-03-30 19:16:01 +00:00
2016-03-31 06:18:56 +00:00
const MaterialSet::Material& GetMaterialByIndex(int idx) const
2016-03-31 02:44:43 +00:00
{
return x4_matSet->materials.at(idx);
}
2016-03-30 19:16:01 +00:00
2016-09-09 04:19:19 +00:00
void ClearUniformCounter() { m_uniUpdateCount = 0; }
static void ClearModelUniformCounters();
2016-03-30 19:16:01 +00:00
static bool g_DrawingOccluders;
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos);
2017-03-05 07:57:12 +00:00
2017-03-26 05:53:04 +00:00
static zeus::CVector3f g_ReflectViewPos;
static void KillCachedViewDepState();
static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
2017-04-15 05:32:25 +00:00
zeus::CMatrix4f* mtxsOut, float& alphaOut);
2016-03-29 23:14:14 +00:00
};
2016-02-13 00:57:09 +00:00
class CModel
{
friend class CBooModel;
//std::unique_ptr<u8[]> x0_data;
//u32 x4_dataLen;
TToken<CModel> m_selfToken; /* DO NOT LOCK! */
zeus::CAABox m_aabb;
u32 m_flags;
2016-03-31 02:44:43 +00:00
std::vector<CBooSurface> x8_surfaces;
std::vector<CBooModel::SShader> x18_matSets;
2016-03-29 23:14:14 +00:00
std::unique_ptr<CBooModel> x28_modelInst;
CModel* x30_next = nullptr;
CModel* x34_prev = nullptr;
int x38_lastFrame;
2016-03-30 19:16:01 +00:00
/* urde addition: boo! */
boo::GraphicsDataToken m_gfxToken;
boo::IVertexFormat* m_staticVtxFmt = nullptr;
boo::IGraphicsBufferS* m_staticVbo = nullptr;
hecl::HMDLMeta m_hmdlMeta;
std::unique_ptr<uint8_t[]> m_dynamicVertexData;
2016-03-30 19:16:01 +00:00
boo::IGraphicsBufferS* m_ibo;
2016-03-29 23:14:14 +00:00
public:
2016-03-31 06:18:56 +00:00
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store, CObjectReference* selfRef);
2016-03-31 02:44:43 +00:00
void DrawSortedParts(const CModelFlags& flags) const;
void DrawUnsortedParts(const CModelFlags& flags) const;
2016-02-13 00:57:09 +00:00
void Draw(const CModelFlags& flags) const;
2016-03-31 02:44:43 +00:00
bool IsLoaded(int shaderIdx) const;
2017-05-06 05:21:42 +00:00
void Touch(int shaderIdx) { x28_modelInst->Touch(shaderIdx); }
2016-04-04 05:02:09 +00:00
2016-04-14 21:42:47 +00:00
const zeus::CAABox& GetAABB() const {return m_aabb;}
2016-04-04 05:02:09 +00:00
CBooModel& GetInstance() {return *x28_modelInst;}
2016-04-14 21:42:47 +00:00
const CBooModel& GetInstance() const {return *x28_modelInst;}
std::unique_ptr<CBooModel> MakeNewInstance(int shaderIdx, int subInsts, boo::ITexture* txtrOverrides[8] = nullptr);
void UpdateLastFrame() const { const_cast<CModel&>(*this).x38_lastFrame = CGraphics::GetFrameCounter(); }
size_t GetPoolVertexOffset(size_t idx) const;
zeus::CVector3f GetPoolVertex(size_t idx) const;
size_t GetPoolNormalOffset(size_t idx) const;
zeus::CVector3f GetPoolNormal(size_t idx) const;
void ApplyVerticesCPU(boo::IGraphicsBufferD* vertBuf,
const std::vector<std::pair<zeus::CVector3f, zeus::CVector3f>>& vn) const;
2016-02-13 00:57:09 +00:00
};
2016-03-29 23:14:14 +00:00
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
2016-03-29 23:14:14 +00:00
2016-02-13 00:57:09 +00:00
}
2016-04-13 06:07:23 +00:00
#endif // __URDE_CMODEL_HPP__