metaforce/Runtime/Graphics/CModel.hpp

121 lines
3.5 KiB
C++
Raw Normal View History

2018-10-07 03:42:33 +00:00
#pragma once
2016-02-13 00:57:09 +00:00
#include <memory>
#include <vector>
#include "CToken.hpp"
#include "GCNTypes.hpp"
2022-02-26 07:05:59 +00:00
#include "Graphics/CCubeModel.hpp"
2022-03-08 23:35:40 +00:00
#include "Graphics/CCubeSurface.hpp"
#include "Graphics/CTexture.hpp"
#include "IObjectStore.hpp"
2016-03-30 19:16:01 +00:00
2021-04-10 08:42:06 +00:00
namespace metaforce {
class CCubeMaterial;
2016-02-13 00:57:09 +00:00
enum class CModelFlagBits : u16 {
DepthTest = 0x1,
DepthUpdate = 0x2,
NoTextureLock = 0x4,
DepthGreater = 0x8,
DepthNonInclusive = 0x10,
DrawNormal = 0x20,
Unknown1 = 0x40,
};
using CModelFlagsFlags = Flags<CModelFlagBits>;
2018-12-08 05:30:43 +00:00
struct CModelFlags {
/**
* 2: add color
* >6: additive
* >4: blend
* else opaque
*/
u8 x0_blendMode = 0;
2018-12-08 05:30:43 +00:00
u8 x1_matSetIdx = 0;
CModelFlagsFlags x2_flags{};
/**
* Set into kcolor slot specified by material
*/
zeus::CColor x4_color;
2018-12-08 05:30:43 +00:00
constexpr CModelFlags() = default;
constexpr CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col)
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {}
constexpr CModelFlags(u8 blendMode, u8 shadIdx, CModelFlagsFlags flags, const zeus::CColor& col)
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {}
2018-12-08 05:30:43 +00:00
bool operator==(const CModelFlags& other) const {
return x0_blendMode == other.x0_blendMode && x1_matSetIdx == other.x1_matSetIdx && x2_flags == other.x2_flags &&
x4_color == other.x4_color;
}
bool operator!=(const CModelFlags& other) const { return !operator==(other); }
2016-02-13 00:57:09 +00:00
};
class CModel {
2016-03-29 23:14:14 +00:00
public:
struct SShader {
std::vector<TCachedToken<CTexture>> x0_textures;
u8* x10_data;
2018-12-08 05:30:43 +00:00
explicit SShader(u8* data) : x10_data(data) {}
2018-12-08 05:30:43 +00:00
void UnlockTextures();
};
2018-12-08 05:30:43 +00:00
private:
static u32 sTotalMemory;
static u32 sFrameCounter;
static bool sIsTextureTimeoutEnabled;
static CModel* sThisFrameList;
static CModel* sOneFrameList;
static CModel* sTwoFrameList;
std::unique_ptr<u8[]> x0_data;
u32 x4_dataLen;
std::vector<CCubeSurface> x8_surfaces; // was rstl::vector<void*>
2018-12-08 05:30:43 +00:00
std::vector<SShader> x18_matSets;
std::unique_ptr<CCubeModel> x28_modelInst = nullptr;
u16 x2c_currentMatIdx = 0;
u16 x2e_lastFrame = 0; // Last frame that the model switched materials
CModel* x30_prev = nullptr;
CModel* x34_next;
u32 x38_lastFrame;
/* Resident copies of maintained data */
std::vector<zeus::CVector3f> m_positions;
std::vector<zeus::CVector3f> m_normals;
std::vector<zeus::CColor> m_colors;
2022-03-08 07:44:46 +00:00
std::vector<aurora::Vec2<float>> m_floatUVs;
std::vector<aurora::Vec2<float>> m_shortUVs;
2016-03-29 23:14:14 +00:00
public:
CModel(std::unique_ptr<u8[]> in, u32 dataLen, IObjectStore* store);
void UpdateLastFrame();
void MoveToThisFrameList();
void RemoveFromList();
void VerifyCurrentShader(u32 matIdx);
void Touch(u32 matIdx);
void Draw(CModelFlags flags);
void Draw(TVectorRef positions, TVectorRef normals, const CModelFlags& flags);
void DrawSortedParts(CModelFlags flags);
void DrawUnsortedParts(CModelFlags flags);
bool IsLoaded(u32 matIdx);
TVectorRef GetPositions() const;
TVectorRef GetNormals() const;
2019-11-09 23:48:46 +00:00
u32 GetNumMaterialSets() const { return x18_matSets.size(); }
bool IsOpaque() const { return x28_modelInst->x3c_firstSortedSurf == nullptr; }
const zeus::CAABox& GetAABB() const { return x28_modelInst->x20_worldAABB; }
2018-12-08 05:30:43 +00:00
static void FrameDone();
static void EnableTextureTimeout();
static void DisableTextureTimeout();
2016-02-13 00:57:09 +00:00
};
CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr<u8[]>&& in, u32 len,
2021-04-10 08:42:06 +00:00
const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef);
} // namespace metaforce