// GFXNET - [2020-04-13 11:57:47]
#ifndef _GFXNET_H_
#define _GFXNET_H_

#include "CFTTVector32.h"
#include "AABB.h"
#include "CFTTRenderHelper.h"
#include "Matrix.h"

/*
001B14A4 intInit()
001B1664 intmInit()
001B1750 intcInit()
001B1864 intShutdown()
001B19DC intAABBTreeShutdown(AABB *)
001B1A0A intmShutdown()
001B1A5C intRender(bool)
001B1AAC intmRender(bool)
001B1C80 intReset()
001B1CA8 intmReset()
001B1D48 intUpdate(float)
001B1D88 intmUpdate(float)
001B24DC intIsInControl()
001B24EC intIsFirstControl()
001B24FC intGetV(int,int,int)
001B2534 intGetP(int,int,int)
001B2558 intGetMinMax(CFTTVector32 &,CFTTVector32 &,GFXNETTri *)
001B26A8 intGetMinMax2(CFTTVector32 &,CFTTVector32 &,GFXNETTri *)
001B2718 intCreateAABB(ushort)
001B2734 intCreateAABB(GFXNETTri const*)
001B2DE0 intAlreadyExists(GFXNETConstraint const&)
001B2E6C intAlreadyExists(CFTTVector32 const&)
001B2EA4 intCreateVertex(CFTTVector32 const&)
001B2F28 intCommonInit()
001B3124 intInitParticles()
001B38DC intPinParticles()
001B3A44 intInitConstraints()
001B3FB0 intInitTris()
001B4294 intBuild(ushort *,int)
001B4558 intRefit()
001B4568 intRefit(AABB *)
001B469C intTraverse(AABB const*,AABB const&)
001B47F8 intcTriSphere(CFTTVector32 const&,CFTTVector32 const&,int,int,int,float)
001B4D50 intTriSphere(CFTTVector32 const&,CFTTVector32 const&,int,int,int)
001B4FE0 intEdgeSphere(CFTTVector32 const&,int,int)
001B50D8 intVertSphere(CFTTVector32 const&,int)
001B5180 intApplyForces(float)
001B51A8 intPredictPosition(float)
001B51D0 intDistanceConstrain(float)
001B51F8 intInternalConstrain(float,float,float)
001B5238 intGroundConstrain()
001B525C intRecalculateVelocity(float)
001B5284 intcTriSphere(CFTTVector32 const&,CFTTVector32 const&,float)
001B52E0 intTriSphere(CFTTVector32 const&,CFTTVector32 const&)
001B5394 intPVCollisionConstrain(CFTTVector32 &,CFTTVector32 &)
001B5478 intPCollisionConstrain(CFTTVector32 &)
001B5548 intCopyPosition()
001B5570 intPredictPosition(float,int)
001B55BC intApplyForces(float,int)
001B566C intCopyPosition(int)
001B56B4 intRecalculateVelocity(float,int)
001B570C intVVCollisionConstrain(int,CFTTVector32 &)
001B57E8 intVECollisionConstrain(int,CFTTVector32 &)
001B596C intVTCollisionConstrain(int,CFTTVector32 &)
001B5B78 intFTCollisionConstrain(int,CFTTVector32 &,CFTTVector32 &,bool)
001B5EEC intTCollisionConstrain(int,CFTTVector32 &,float)
001B61B0 intECollisionConstrain(int,CFTTVector32 &,float)
001B6404 intVCollisionConstrain(int,CFTTVector32 &,float)
001B6560 intDistanceConstrain(int,float)
001B664C intGroundConstrain(int)
001B6690 intInternalConstrain(int,float,float,float)

*/

struct Lockvert1 {
  CFTTVector32 fttVector32_0;
  float f_C;
  float f_10;
};
struct Lockvert2 {
  float f_0;
  float f_4;
  float f_8;
  uint ui_C;
};

// sizeof = 0x14
struct DisConstraint {
  ushort us_0;
  ushort us_2;
  CFTTVector32 vec32_4;
  float f_10;
};

// sizeof = 0x14
struct GFXverts {
  CFTTVector32 fttVector32_0;
  float f_C;
  float f_10;

  GFXverts &operator=(GFXverts const &other) {
    memcpy(this, &other, sizeof(GFXverts));
    return *this;
  }
};

// sizeof = 0x14
struct GFXvert {
  CFTTVector32 fttVector32_0;
  float f_C;
  ushort us_10;

  GFXvert() {
  }

  GFXvert(CFTTVector32 ftt1, float f2, ushort us3) {
    fttVector32_0 = ftt1;
    f_C = f2;
    us_10 = us3;
  }

  GFXvert &operator=(GFXvert const &other) {
    memcpy(this, &other, sizeof(GFXvert));
    return *this;
  }
};

// sizeof = 0x18
struct GFXedge {
  CFTTVector32 fttVector32_0;
  float f_C;
  ushort us_10;
  ushort us_12;
  float f_14;

  GFXedge() {
  }

  GFXedge(CFTTVector32 ftt1, float f2, ushort us3, ushort us4, float f5) {
    fttVector32_0 = ftt1;
    f_C = f2;
    us_10 = us3;
    us_12 = us4;
    f_14 = f5;
  }

  GFXedge &operator=(GFXedge const &other) {
    memcpy(this, &other, sizeof(GFXedge));
    return *this;
  }
};

// sizeof = 0x48
struct GFXtri {
  CFTTVector32 fttVector32_0;
  CFTTVector32 fttVector32_C[2];
  // CFTTVector32  fttVector32_18;

  float f_24;
  float f_28[2];
  ushort us_30;
  ushort us_32;
  ushort us_34;
  float f_38;
  float f_3C;
  float f_40;
  float f_44;

  GFXtri &operator=(GFXtri const &other) {
    memcpy(this, &other, sizeof(GFXtri));
    return *this;
  }
};

// sizeof = 0x0C
struct GFXNETConstraint {
  float f_0;
  ushort us_4;
  ushort us_6;
  uchar uc_8;
  uchar uc_9;
  ushort us_A;

  __attribute__((always_inline))
  GFXNETConstraint &
  operator=(GFXNETConstraint const &other) {
    memcpy(this, &other, sizeof(GFXNETConstraint));
    return *this;
  }
};

// 001B2E28
bool operator==(GFXNETConstraint const &arg_1, GFXNETConstraint const &arg_2);

class GFXNET {
public:
  GFXNET() { memset(this, 0, sizeof(GFXNET)); }

  static void Init();                                                                 // 001B14A4
  void mInit();                                                                       // 001B1664
  void cInit();                                                                       // 001B1750
  static void Shutdown();                                                             // 001B1864
  static void AABBTreeShutdown(AABB *);                                               // 001B19DC
  void mShutdown();                                                                   // 001B1A0A
  static void Render(bool);                                                           // 001B1A5C
  void mRender(bool);                                                                 // 001B1AAC
  static void Reset();                                                                // 001B1C80
  void mReset();                                                                      // 001B1CA8
  static void Update(float);                                                          // 001B1D48
  void mUpdate(float);                                                                // 001B1D88
  static bool IsInControl();                                                          // 001B24DC
  static bool IsFirstControl();                                                       // 001B24EC
  ushort GetV(int, int, int);                                                         // 001B24FC
  ushort GetP(int, int, int);                                                         // 001B2534
  void GetMinMax(CFTTVector32 &, CFTTVector32 &, GFXNETTri *);                        // 001B2558
  void GetMinMax2(CFTTVector32 &, CFTTVector32 &, GFXNETTri *);                       // 001B26A8
  AABB CreateAABB(ushort);                                                            // 001B2718
  AABB CreateAABB(GFXNETTri const *);                                                 // 001B2734
  bool AlreadyExists(GFXNETConstraint const &arg_1);                                  // 001B2DE0
  ushort AlreadyExists(CFTTVector32 const &arg_1);                                    // 001B2E6C
  void CreateVertex(CFTTVector32 const &);                                            // 001B2EA4
  void CommonInit();                                                                  // 001B2F28
  void InitParticles();                                                               // 001B3124
  void PinParticles();                                                                // 001B38DC
  void InitConstraints();                                                             // 001B3A44
  void InitTris();                                                                    // 001B3FB0
  AABB *Build(ushort *, int);                                                         // 001B4294
  void Refit();                                                                       // 001B4558
  void Refit(AABB *);                                                                 // 001B4568
  void Traverse(AABB const *, AABB const &);                                          // 001B469C
  void cTriSphere(CFTTVector32 const &, CFTTVector32 const &, int, int, int, float);  // 001B47F8
  void TriSphere(CFTTVector32 const &, CFTTVector32 const &, int, int, int);          // 001B4D50
  void EdgeSphere(CFTTVector32 const &, int, int);                                    // 001B4FE0
  void VertSphere(CFTTVector32 const &, int);                                         // 001B50D8
  void ApplyForces(float);                                                            // 001B5180
  void PredictPosition(float);                                                        // 001B51A8
  void DistanceConstrain(float);                                                      // 001B51D0
  void InternalConstrain(float, float, float);                                        // 001B51F8
  void GroundConstrain();                                                             // 001B5238
  void RecalculateVelocity(float);                                                    // 001B525C
  void cTriSphere(CFTTVector32 const &, CFTTVector32 const &, float);                 // 001B5284
  void TriSphere(CFTTVector32 const &, CFTTVector32 const &);                         // 001B52E0
  void PVCollisionConstrain(CFTTVector32 &, CFTTVector32 &);                          // 001B5394
  void PCollisionConstrain(CFTTVector32 &);                                           // 001B5478
  void CopyPosition();                                                                // 001B5548
  void PredictPosition(float, int);                                                   // 001B5570
  void ApplyForces(float, int);                                                       // 001B55BC
  void CopyPosition(int);                                                             // 001B566C
  void RecalculateVelocity(float, int);                                               // 001B56B4
  void VVCollisionConstrain(int, CFTTVector32 &);                                     // 001B570C
  void VECollisionConstrain(int, CFTTVector32 &);                                     // 001B57E8
  void VTCollisionConstrain(int, CFTTVector32 &);                                     // 001B596C
  void FTCollisionConstrain(int, CFTTVector32 &, CFTTVector32 &, bool);               // 001B5B78
  void TCollisionConstrain(int, CFTTVector32 &, float);                               // 001B5EEC
  void ECollisionConstrain(int, CFTTVector32 &, float);                               // 001B61B0
  void VCollisionConstrain(int, CFTTVector32 &, float);                               // 001B6404
  void DistanceConstrain(int, float);                                                 // 001B6560
  void GroundConstrain(int);                                                          // 001B664C
  void InternalConstrain(int, float, float, float);                                   // 001B6690

  CFTTVector32 *m_pFTTVector32List_0;
  CFTTVector32 *m_pFTTVector32List_4;
  CFTTVector32 *m_pFTTVector32List_8;
  float *m_pFloatList_C;
  bool m_b_10;
  bool m_b_11;
  bool m_b_12;
  int *m_piList_14[4];
  int *m_piList_24[4];
  int m_i_34[4];
  int m_i_44[4];  // m_piList_14[4] m_piList_14[4] Length
  CFTTRenderHelper *m_pFTTRenderHelper_54;
  CFTTRenderHelper *m_pFTTRenderHelper_58;

  static AABB *AABBTree;                            // 004760D0
  static bool GFXNET_bSquare;                       // 00476114
  static int GFXNET_iStyle;                         // 00476110
  static CFTTVector32 *a;                           // 004760D4
  static CFTTVector32 *sx;                          // 004760D8
  static bool ms_bFirstInControl;                   // 00476105
  static bool ms_bInControl;                        // 00476104
  static GFXNETTri **ms_broadCollisions;            // 004760BC
  static DisConstraint *ms_distanceConstraints;     // 004760A8
  static float ms_fFirstCollision;                  // 00476100
  static int ms_iNumBroadCollisions;                // 004760FC
  static int ms_iNumDConstraints;                   // 004760E8
  static int ms_iNumIConstraints;                   // 004760E4
  static int ms_iNumParticles;                      // 004760DC
  static int ms_iNumTriCollisions;                  // 004760F0
  static int ms_iNumTris;                           // 004760EC
  static int ms_iNumVertCollisions;                 // 004760F8
  static int ms_iNumVertices;                       // 004760E0
  static ushort *ms_iVerts;                         // 004760CC
  static GFXNETConstraint *ms_internalConstraints;  // 004760AC
  static GFXNETTri *ms_tris;                        // 004760C0
  static GFXNETTri *ms_trisP;                       // 004760C4
  static GFXvert *ms_vertCollisions;                // 004760B8
  static GFXverts *ms_verts;                        // 004760C8
  static GFXedge *ms_edgeCollisions;                // 004760B4
  static int ms_iNumEdgeCollisions;                 // 004760F4
  static GFXtri *ms_triCollisions;                  // 004760B0
  static GFXNET *net1;                              // 00476108
  static GFXNET *net2;                              // 0047610C
  static int s_iGoalNetMat;                         // 00342D08
};

void sub_1B2620(CFTTVector32 &, CFTTVector32 &);  // 001B2620

void GFXNET_GoalFrameInit();       // 001B12E0
void GFXNET_GoalFrameKill();       // 001B1334
void GFXNET_GoalFrameRender(int);  // 001B1374

extern int GFXNET_uGoalCulled[2];  // 0047609C

#endif  //_GFXNET_H_