// CFTTModel - [2020-04-13 11:57:46]
#ifndef _CFTTMODEL_H_
#define _CFTTMODEL_H_

#include "CFTTAnimBlend.h"
#include "CFTTMatSetupData.h"
#include "CFTTMatrix32.h"
#include "CFTTRenderHelper.h"
#include "sh_struct.h"
#include "FTTGraphics.h"
#include "FTTUPtr.h"
#include "CFTTFrustum32.h"
#include "CFTTAABB32.h"

/*
00217B74 CFTTModel::CFTTModel(ushort,EModelLoadFlags)
00217BFC CFTTModel::CFTTModel(char const*,CFTTMatSetupData const&,EModelLoadFlags)
00217C94 CFTTModel::CFTTModel(CFTTFile *,CFTTMatSetupData const&,EModelLoadFlags)
00218FE0 CFTTModel::CFTTModel(CFTTModel const*,CFTTMatSetupData const&,EModelCopyFlags)
0021A058 CFTTModel::~CFTTModel()
0021A64A CFTTModel::~CFTTModel()
0018A494 CFTTModel::Render()
002178B8 CFTTModel::SetInsideCulling(bool)
002178C8 CFTTModel::GetInsideCulling()
00217930 CFTTModel::InitMembers()
002179D0 CFTTModel::LoadExtendedHeader(CFTTFile *,int)
00217C44 CFTTModel::InitModel_Filename(char const*,CFTTMatSetupData const&,EModelLoadFlags)
00217CDC CFTTModel::InitModel_FileHandle(CFTTFile *,CFTTMatSetupData const&,EModelLoadFlags)
00217D00 CFTTModel::InitModel(CFTTFile *,CFTTMatSetupData const&,EModelLoadFlags)
00218EA0 CFTTModel::AllocArrays(int)
00218F24 CFTTModel::SetVertexType()
00219028 CFTTModel::CopyModel(CFTTModel const*,CFTTMatSetupData const&,EModelCopyFlags)
0021A048 CFTTModel::GetNumBones(int)
0021A658 CFTTModel::GetMaterialIDs(int *,int,int)
0021A784 CFTTModel::GetMaxNumMaterials()
0021A7BC CFTTModel::SetupRenderStates(ushort)
0021A7CC CFTTModel::RestoreRenderStates(ushort)
0021A7DC CFTTModel::GetInvBindMatrix(uint,uint)
0021A7F0 CFTTModel::GetTrueBone(uint)
0021A81C CFTTModel::ModelsFromMeshes(EMeshModelFlags)
0021A92A CFTTModel::ModelsToMeshes(EMeshModelFlags)
0021AA74 CFTTModel::DeleteModels()
0021AAB8 CFTTModel::SetVerts(bool)
0021AAE4 CFTTModel::SetPhysiqueVerts(int,int)
0021AAE8 CFTTModel::BuildRenderData(uint,CFTTMatSetupData const*)
0021AB30 CFTTModel::FreeHWBuffers(bool,bool)
0021AB70 CFTTModel::CreateVolatileResources()
0021ABB4 CFTTModel::CreateManagedResources()
0021ABF2 CFTTModel::PrebuildSkin(float,int)
0021AC60 CFTTModel::Render(CFTTMatrix32 *,float)
0021AD98 CFTTModel::RenderPart(CFTTMatrix32 *,float,bool *,int)
0021AE94 CFTTModel::RenderMaterial(CFTTMatrix32 *,float,int,ushort)
0021B0D8 CFTTModel::DeleteVolatileResources()
0021B106 CFTTModel::DeleteManagedResources()
0021B13A CFTTModel::PrePhysiqueVerts(float)
0021B13C CFTTModel::PostPhysiqueVerts()
0021B13E CFTTModel::LoadPlatformModel(CFTTFile *,TFTTPlatformModel *,int,ushort **&,int &)
0021CC02 CFTTModel::GenerateAnimationDataT(float,TFTTAnimHeader **)
0021CC4C CFTTModel::GenerateAnimationData(float,TFTTAnimHeader **)
0021DA94 CFTTModel::GenerateAnimationData_Physique(int,int,float,int,TFTTAnimHeader **)
0021DE68 CFTTModel::GenerateAnimationData_Hierarchical(int,int,float,int,TFTTAnimHeader **)

vptr_CFTTModel_328700:
  CFTTModel::~CFTTModel()
  CFTTModel::~CFTTModel()

0x15C
*/
//-------------------------------------------------------------------------------------------------
enum EModelLoadFlags {
  EModelLoadFlags_0,
  EModelLoadFlags_1,
  EModelLoadFlags_2,
  EModelLoadFlags_3,
  EModelLoadFlags_4,
  EModelLoadFlags_5,
  EModelLoadFlags_6,
};
//-------------------------------------------------------------------------------------------------
enum EModelCopyFlags {
  EModelCopyFlags_0,
  EModelCopyFlags_1,
  EModelCopyFlags_2,
  EModelCopyFlags_3,
  EModelCopyFlags_4,
  EModelCopyFlags_5,
};
//-------------------------------------------------------------------------------------------------
enum EMeshModelFlags {
  EMeshModelFlags_0,
  EMeshModelFlags_1,
  EMeshModelFlags_2,
  EMeshModelFlags_3,
  EMeshModelFlags_4,
  EMeshModelFlags_5,
  EMeshModelFlags_6,
  EMeshModelFlags_7,
  EMeshModelFlags_8,
  EMeshModelFlags_9,
  EMeshModelFlags_10,
  EMeshModelFlags_11,
  EMeshModelFlags_12,
  EMeshModelFlags_13,
  EMeshModelFlags_14,
  EMeshModelFlags_15,
  EMeshModelFlags_16,
};
//-------------------------------------------------------------------------------------------------
//结构大小确定为0x12, 具体的类型不确定
#pragma pack(1)
struct CFTTModel_struct_12 {
  ushort us_0;
  ushort us_2;
  int field_4;
  int field_8;
  int field_C;
  ushort field_10;
};
#pragma pack()

struct CFTTModel_Wrap_12 {
  CFTTModel_struct_12 *pStruct_0;
};
//-------------------------------------------------------------------------------------------------
// 0x14
#pragma pack(1)
struct CFTTModel_struct_14 {
  short field_0;
  CFTTModel_struct_12 tStr12_2;
};
#pragma pack()
//-------------------------------------------------------------------------------------------------
struct CFTTModel_Wrap_14 {
  CFTTModel_struct_14 *pCFTTModel_struct_14_0;
};
//-------------------------------------------------------------------------------------------------
// 0x2C  float32x2_t 默认要求8字节对齐, 因此，这里要强制加上4字节对齐
#pragma pack(4)
struct TFTTPlatformModel {
  FTM_Section_Head tFTMHead_0;
  ushort field_8;
  ushort field_A;
  float32x2_t tfloat32x2_C;
  float32x2_t tfloat32x2_14;
  float32x2_t tfloat32x2_1C;
  float32x2_t tfloat32x2_24;
};
#pragma pack()
//-------------------------------------------------------------------------------------------------
//大小确定 0xC0 ModelsToMeshes 中确定的
struct CFTTPlatformMesh {
  TFTTPlatformModel tPlatformModel_0;
  union {
    int offset;
    uint8 *pData;
  } uOPData_2C;

  int field_30;

  union {
    int offset;
    ushort *pusData;
  } uOPData_34;

  int buflen_38;
  union {
    int offset;
    TFTTVertexDescriptor *pTFTTVertexDescriptor;
  } uOPData_3C;

  int count_40;

  union {
    int offset;
    // CFTTModel_Wrap_14 *pData;  //
    CFTTModel_struct_14 *list_model;
    CFTTModel_struct_12 *list_model_2;
  } uOPData_44;

  union {
    int offset;
    uint8 *pData;
  } uOPData_48;

  int dMatrix32Count_4C;  // list_CFTTMatrix32_28[dMeshIndex] count

  union {
    int offset;
    uint8 *pData;
  } uOPData_50;

  uint dMeshCount_54;
  ushort field_58;
  ushort field_5A;
  float pfloat_array_5C[3];
  float pfloat_array_68[3];
  CFTTVector32x4 pfTTVector32x4_74;
  CFTTVector32x4 pfTTVector32x4_84;
  FTTUPtr<CFTTRenderHelper> pCFTTRenderHelper_94;

  union {
    int offset;
    CFTTMatrix32 *pCFTTMatrix32;
  } uOPData_98;

  int field_9C;
  int field_A0;
  int field_A4;
  int field_A8;
  int field_AC;
  int field_B0;
  int field_B4;
  int field_B8;
  int field_BC;
};
//-------------------------------------------------------------------------------------------------
struct CFTTModel_TFTTAnimKeyFrame_4 {
  union {
    // TFTTAnimKeyFrame *pTFTTAnimKeyFrame_0;
    TFTTAnimHeader *pTFTTAnimHeader_0;
  } u_0;
};
//-------------------------------------------------------------------------------------------------
struct CFTTModel_Bone_8 {
  int field_0;
  ushort dCFTTMatrix32Count_4;
  ushort field_6;
};
//-------------------------------------------------------------------------------------------------
struct CFTTModel_TFTTHierarchyHeader_4 {
  TFTTHierarchyHeader *pTFTTHierarchyHeader_0;
};
//-------------------------------------------------------------------------------------------------
// 0x20
// 0021863C 2E40  MOVS            R0, #0x20 @ ' '
struct CFTTModel_struct_20 {
  int field_0;
  int field_4;
  int field_8;
  int field_C;
  int field_10;
  int field_14;
  int field_18;
  int field_1C;
};
//-------------------------------------------------------------------------------------------------
struct TBoneDesInfo {
  char info_0[32];
};
//-------------------------------------------------------------------------------------------------
class CFTTPlatformMesh32 {
public:
  // copy a1 -> a2
  void Convert(CFTTPlatformMesh *pOther);  // 0021B26E
  CFTTPlatformMesh mesh_0;
};
//-------------------------------------------------------------------------------------------------
// 0x40 //0021B074 6B8   ADD.W R10, R10, #0x40 @ '@' 此处可以判断该结构大小为0x40
class TModelAABBDC {
public:
  ~TModelAABBDC();
  bool Render(CFTTFrustum32 const &, CFTTVector32 const &);  // 002178D8
  ushort us_0;                                               // 0021B060 6B8   LDRH.W          R3, [R6,R10]
  ushort us_2;
  CFTTAABB32 tAABB32_4;
  int field_34;
  CFTTAABB32 *pAABB32_38;
  uchar ub_3C;
  uchar ub_3D;
  uchar ub_3E;
  uchar ub_3F;
};
//-------------------------------------------------------------------------------------------------
class TModelSplit {
public:
  ~TModelSplit(){
      // 0021A61C
  };

  uchar ub_0;
  uchar ub_1;
  ushort us_2;
  TModelAABBDC *pModelAABBDC_4;
};
//-------------------------------------------------------------------------------------------------
class CFTTModel {
public:
  CFTTModel(ushort a1, EModelLoadFlags eFlag);                              // 00217B74
  CFTTModel(char const *, CFTTMatSetupData const &, EModelLoadFlags);       // 00217BFC
  CFTTModel(CFTTFile *, CFTTMatSetupData const &, EModelLoadFlags);         // 00217C94
  CFTTModel(CFTTModel const *, CFTTMatSetupData const &, EModelCopyFlags);  // 00218FE0
  virtual ~CFTTModel();                                                     // 0021A058 0021A64A

  void Render();                                                                           // 0018A494
  static void SetInsideCulling(bool);                                                      // 002178B8
  static bool GetInsideCulling();                                                          // 002178C8
  void InitMembers();                                                                      // 00217930
  bool LoadExtendedHeader(CFTTFile *, int);                                                // 002179D0
  void InitModel_Filename(char const *, CFTTMatSetupData const &, EModelLoadFlags);        // 00217C44
  void InitModel_FileHandle(CFTTFile *, CFTTMatSetupData const &, EModelLoadFlags);        // 00217CDC
  bool InitModel(CFTTFile *, CFTTMatSetupData const &, EModelLoadFlags);                   // 00217D00
  void AllocArrays(int);                                                                   // 00218EA0
  void SetVertexType();                                                                    // 00218F24
  void CopyModel(CFTTModel const *, CFTTMatSetupData const &, EModelCopyFlags);            // 00219028
  ushort GetNumBones(int) const;                                                           // 0021A048
  int GetMaterialIDs(int *, int, int);                                                     // 0021A658
  uint GetMaxNumMaterials();                                                               // 0021A784
  void SetupRenderStates(ushort);                                                          // 0021A7BC
  void RestoreRenderStates(ushort);                                                        // 0021A7CC
  CFTTMatrix32 *GetInvBindMatrix(uint index, uint a3);                                     // 0021A7DC
  bool GetTrueBone(uint);                                                                  // 0021A7F0
  void ModelsFromMeshes(EMeshModelFlags);                                                  // 0021A81C
  void ModelsToMeshes(EMeshModelFlags);                                                    // 0021A92A
  void DeleteModels();                                                                     // 0021AA74
  void SetVerts(bool);                                                                     // 0021AAB8
  void SetPhysiqueVerts(int, int);                                                         // 0021AAE4
  void BuildRenderData(uint, CFTTMatSetupData const *);                                    // 0021AAE8
  void FreeHWBuffers(bool, bool);                                                          // 0021AB30
  bool CreateVolatileResources();                                                          // 0021AB70
  bool CreateManagedResources();                                                           // 0021ABB4
  void PrebuildSkin(float, int);                                                           // 0021ABF2
  void Render(CFTTMatrix32 *, float);                                                      // 0021AC60
  void RenderPart(CFTTMatrix32 *, float, bool *, int);                                     // 0021AD98
  void RenderMaterial(CFTTMatrix32 *, float, int, ushort);                                 // 0021AE94
  int DeleteVolatileResources();                                                           // 0021B0D8
  void DeleteManagedResources();                                                           // 0021B106
  void PrePhysiqueVerts(float);                                                            // 0021B13A
  void PostPhysiqueVerts();                                                                // 0021B13C
  int LoadPlatformModel(CFTTFile *, TFTTPlatformModel *, int, ushort **&ppStruct, int &);  // 0021B13E
  void GenerateAnimationDataT(float, TFTTAnimHeader **);                                   // 0021CC02
  void GenerateAnimationData(float, TFTTAnimHeader **);                                    // 0021CC4C
  void GenerateAnimationData_Physique(int, int, float, int, TFTTAnimHeader **);            // 0021DA94
  void GenerateAnimationData_Hierarchical(int, int, float, int, TFTTAnimHeader **);        // 0021DE68

  int field_4;
  uint dVertexCount_8;
  // CFTTModel_Mesh_4 * list_PlatformMesh_C;
  CFTTPlatformMesh **ppPlatformMesh_C;
  bool bIsCreateManageRes_10;  // true 表示已经Create
  bool bool_11;
  bool bool_12;
  bool field_13;
  float f_14;
  int file_open_err_18;
  float f_1C;
  int field_20;
  CFTTModel_TFTTAnimKeyFrame_4 *pTFTTAnimKeyFrame_24;  // loc_217FAE 说明是 TFTTAnimHeader
                                                       //还有可能是 TFTTAnimKeyFrame
  CFTTMatrix32 **ppCFTTMatrix32_28;

  float f_2C;
  float f_30;
  uint8 byte_34;  // bool
  float f_38;
  float f_3C;
  int dAnimBlock_40;
  float f_44;
  TBone *pTBone_48;  // CFTTModel_Bone_8 *list_bones_48;
  TBoneDesInfo **ppTBone_4C;

  CFTTModel_struct_20 **ppStruct20_50;
  uint8 byte_54;                                             //.text:0021ACB2   LDR R1, [R6,#0x54] 这儿是取4个字节
  TBoneBlendInfo *list_TBoneBlendInfo_58;                    // TBoneBlendInfo
  CFTTModel_TFTTHierarchyHeader_4 *pTFTTHierarchyHeader_5C;  // TFTTHierarchyHeader list CFTTModel_TFTTHierarchyHeader_4
  CFTTAnimBlend *pCFTTAnimBlend_60;
  int func_64;  //没有调用到
  int field_68;
  ushort dModelCount_6C;
  ushort dCount_6E;           // list_TCollBlock_7C count
  int dTMarkupBlockCount_70;  // list_TMarkupBlock_88 count
  TFTTModel **ppTFTTModel_74;
  int field_78;
  TCollBlock *list_TCollBlock_7C;  // struct size 0x58
  float *list_float_80;
  ushort *list_ushort_84;
  TMarkupBlock *pTMarkupBlock_88;  // 0x5C array
  int field_8C;
  int field_90;
  int field_94;
  int **pArray_4_98;           //??? 类型暂时未知
  TFTTCamera *pTFTTCamera_9C;  // 0x38 array
  TFTTHelper *pTFTTHelper_A0;  // 0x58 array
  TFTTSpline *pTFTTSpline_A4;  // 0x2C array
  TFTTLight *pTFTTLight_A8;    // 0x34 array
  int dTFTTCameraCount_AC;
  int dCount_B0;  // list_TFTTHelper_A0 count
  int dCount_B4;  // list_TFTTSpline_A4 count
  int dCount_B8;  // list_TFTTLight_A8 count
  uint8 *pArray_4_BC;
  int dTotalCount_C0;  // list_TFTTHelper_A0 all node
  TModelSplit **ppTModelSplit_C4;
  TPVSBlock *list_TPVSBlock_C8;
  int field_CC;
  float float_D0;
  CFTTVector32 cfttVector32_D4; //001C286E 这一块确定
  CFTTVector32 cfttVector32_E0; //001C286E 这一块确定
  CFTTVector32 cfttVector32_EC; //001C286E 这一块确定
  int field_F8;
  int field_FC;
  int field_100;
  int field_104;
  int field_108;
  int field_10C;
  int field_110;
  float float_114;
  int field_118;
  int field_11C;
  int field_120;
  int field_124;
  float float_128;
  int field_12C;
  int field_130;
  int field_134;
  int field_138;
  float float_13C;
  int field_140;
  int field_144;
  int field_148;
  int field_14C;
  float float_150;
  int field_154;
  int field_158;

  static bool ms_bInsideCulling;
};

#endif  //_CFTTMODEL_H_