1  //


2  // Orbital


3  //


4  // Copyright: (c) 20092012 Cédric Lecacheur <jordx@free.fr>


5  // (c) 20092012 Benjamin Huet <huet.benjamin@gmail.com>


6  // (c) 2012 Sam Hocevar <sam@hocevar.net>


7  //


8 


9  /* FIXME: this file is pure crap; it's only a test. */


10 


11  #if !defined __CHARACTER_H__


12  #define __CHARACTER_H__


13 


14  enum body_parts


15  {


16  EBP_Torso,


17  EBP_Head,


18  EBP_LeftArm,


19  EBP_LeftForeArm,


20  EBP_LeftThigh,


21  EBP_LeftLowerLeg,


22  EBP_RightArm,


23  EBP_RightForeArm,


24  EBP_RightThigh,


25  EBP_RightLowerLeg,


26 


27  EBP_MAX


28  };


29 


30  #define HEAD_SIZE_X 5.0f


31  #define HEAD_SIZE_Y (HEAD_SIZE_X * 1.5f)


32  #define HEAD_SIZE_Z (HEAD_SIZE_X * 1.0f)


33  #define HEAD_CHAMFER (HEAD_SIZE_X * 0.1f)


34 


35  class Character : public WorldEntity


36  {


37  public:


38  Character()


39  : m_ready(false)


40  {


41  //m_rotation = quat::rotate(RandF(0.f, 360.f), vec3(0, 1, 0));


42 


43  //Mesh size calculation


44  Array<vec4> MeshSize;


45  Array<vec3> MeshOffset;


46  for (int i = 0; i < EBP_MAX; ++i)


47  {


48  vec4 NewSize = vec4(.0f);


49  vec3 NewOffset = vec3(.0f);


50  switch (i)


51  {


52  case EBP_Head:


53  {


54  NewSize = vec4(HEAD_SIZE_X, HEAD_SIZE_Y, HEAD_SIZE_Z, HEAD_CHAMFER);


55  NewOffset = vec3(.5f, HEAD_SIZE_Y * 0.5f, .0f);


56  break;


57  }


58  case EBP_Torso:


59  {


60  //Man : Torse : 3 TetesH H (dont 1/4 cou), 2 TetesH L


61  NewSize = vec4(HEAD_SIZE_X, HEAD_SIZE_Y * 3.0f, HEAD_SIZE_Z * 2.0f, HEAD_CHAMFER);


62  break;


63  }


64  case EBP_RightArm:


65  case EBP_LeftArm:


66  {


67  //Man : bras : 3 TetesH + 1 TetesL (epaule) (1H+1L + 2H)


68  NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_X, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);


69  NewOffset = vec3(.0f, NewSize.y * 0.4f, .0f);


70  break;


71  }


72  case EBP_RightForeArm:


73  case EBP_LeftForeArm:


74  {


75  NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);


76  NewOffset = vec3(.0f, NewSize.y * 0.5f, .0f);


77  break;


78  }


79  case EBP_RightThigh:


80  case EBP_LeftThigh:


81  {


82  //Man : Jambe : 4 TetesH (2H * 2H)


83  NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);


84  NewOffset = vec3(.0f, NewSize.y * 0.5f, .0f);


85  break;


86  }


87  case EBP_RightLowerLeg:


88  case EBP_LeftLowerLeg:


89  {


90  NewSize = vec4(HEAD_SIZE_X * 0.8f, HEAD_SIZE_Y + HEAD_SIZE_Y, HEAD_SIZE_Z * 0.8f, HEAD_CHAMFER);


91  NewOffset = vec3(.0f, NewSize.y * 0.5f, .0f);


92  break;


93  }


94  }


95  MeshSize << NewSize;


96  MeshOffset << NewOffset;


97  }


98 


99  //Mesh ref matrix calculation


100  mat4 NewMatrix;


101  int ParentMatrix = EBP_Torso;


102  for (int i = 0; i < EBP_MAX; ++i)


103  {


104  vec3 BaseCos = vec3(0.0f);


105  switch (i)


106  {


107  case EBP_Head:


108  {


109  NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_Torso].y, .0f) * .5f);


110  ParentMatrix = EBP_Torso;


111  break;


112  }


113  case EBP_Torso:


114  {


115  //Man : Torse : 3 TetesH H (dont 1/4 cou), 2 TetesH L


116  NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_Torso].y * .5f + MeshSize[EBP_RightLowerLeg].y + MeshSize[EBP_RightThigh].y, .0f));


117  ParentMatrix = EBP_Torso;


118  break;


119  }


120  case EBP_RightArm:


121  case EBP_LeftArm:


122  {


123  //Man : bras : 3 TetesH + 1 TetesL (epaule) (1H+1L + 2H)


124  vec3 NewTranslation = vec3(.0f, MeshSize[EBP_Torso].y * .5f  MeshSize[EBP_RightArm].y * .1f, MeshSize[EBP_RightArm].z + MeshSize[EBP_Torso].z) * vec3(.0f, 1.0f, .5f);


125  if (i == EBP_LeftArm)


126  NewTranslation *= vec3(1.0f, 1.0f, 1.0f);


127  NewMatrix = mat4::translate(NewTranslation);


128  ParentMatrix = EBP_Torso;


129  break;


130  }


131  case EBP_RightForeArm:


132  case EBP_LeftForeArm:


133  {


134  NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_RightArm].y * .3f + MeshSize[EBP_RightForeArm].y * .5f, .0f) * 1.0f);


135  if (i == EBP_RightForeArm)


136  ParentMatrix = EBP_RightArm;


137  else


138  ParentMatrix = EBP_LeftArm;


139  break;


140  }


141  case EBP_RightThigh:


142  case EBP_LeftThigh:


143  {


144  //Man : Jambe : 4 TetesH (2H * 2H)


145  vec3 NewTranslation = vec3(.0f, MeshSize[EBP_Torso].y * .5f, MeshSize[EBP_Torso].z  MeshSize[EBP_RightThigh].z) * vec3(.0f, 1.0f, .5f);


146  if (i == EBP_LeftThigh)


147  NewTranslation *= vec3(1.0f, 1.0f, 1.0f);


148  NewMatrix = mat4::translate(NewTranslation);


149  ParentMatrix = EBP_Torso;


150  if (i == EBP_LeftThigh)


151  BaseCos = vec3(M_PI);


152  break;


153  }


154  case EBP_RightLowerLeg:


155  case EBP_LeftLowerLeg:


156  {


157  NewMatrix = mat4::translate(vec3(.0f, MeshSize[EBP_RightThigh].y + MeshSize[EBP_RightLowerLeg].y, .0f) * .5f);


158  if (i == EBP_RightLowerLeg)


159  ParentMatrix = EBP_RightThigh;


160  else


161  ParentMatrix = EBP_LeftThigh;


162  break;


163  }


164  }


165  m_body_matrix_local << NewMatrix;


166  m_body_parent << ParentMatrix;


167  m_body_matrix_world << mat4(1.0);


168  m_body_rotation << vec3(.0f);


169  m_body_cos << BaseCos;


170 


171  char NewMesh[200];


172  EasyMesh TmpMesh;


173  sprintf(NewMesh, "[sc#ddd afcb%.3f %.3f %.3f %.3f t%.3f %.3f %.3f]", MeshSize[i].x, MeshSize[i].y, MeshSize[i].z, MeshSize[i].w, MeshOffset[i].x, MeshOffset[i].y, MeshOffset[i].z);


174  TmpMesh.Compile(NewMesh);


175  m_body_parts << TmpMesh;


176  }


177  }


178 


179  ~Character()


180  {


181  }


182 


183  char const *GetName() { return "<Character>"; }


184 


185  protected:


186  virtual void TickGame(float seconds)


187  {


188  WorldEntity::TickGame(seconds);


189 


190  for (int i = 0; i < EBP_MAX; ++i)


191  {


192  switch (i)


193  {


194  case EBP_Head:


195  {


196  //m_body_rotation[i].y += 10.0f * seconds;


197  break;


198  }


199  case EBP_Torso:


200  {


201  break;


202  }


203  case EBP_RightArm:


204  case EBP_LeftArm:


205  {


206  m_body_rotation[i].z = lol::cos(m_body_cos[i  (EBP_LeftArm  EBP_LeftThigh)].z) * 10.0f;


207  break;


208  }


209  case EBP_RightForeArm:


210  case EBP_LeftForeArm:


211  {


212  m_body_rotation[i].z = 5.0f + m_body_rotation[i  (EBP_LeftForeArm  EBP_LeftLowerLeg)].z * .25f;


213  break;


214  }


215  case EBP_LeftThigh:


216  case EBP_RightThigh:


217  {


218  m_body_cos[i].z += 2.0f * seconds;


219  m_body_rotation[i].z = lol::cos(m_body_cos[i].z) * 30.0f;


220  break;


221  }


222  case EBP_LeftLowerLeg:


223  case EBP_RightLowerLeg:


224  {


225  float NewSin = lol::sin(m_body_cos[i  (EBP_LeftLowerLeg  EBP_LeftThigh)].z);


226  float NewCos = lol::cos(m_body_cos[i  (EBP_LeftLowerLeg  EBP_LeftThigh)].z);


227  if (NewSin <= .0f)


228  m_body_rotation[i].z = 0.0f;


229  else if (NewSin > .0f && NewCos < .0f)


230  m_body_rotation[i].z = NewSin * NewSin * NewSin * 40.0f;


231  else if (NewSin > .0f && NewCos > .0f)


232  m_body_rotation[i].z = (1.0f  NewCos * NewCos * NewCos * NewCos) * 40.0f;


233  break;


234  }


235  }


236  }


237 


238  for (int i = 0; i < EBP_MAX; ++i)


239  {


240  mat4 WorldMatrix = mat4(1.0f);


241  int CurParent = m_body_parent[i];


242 


243  if (CurParent != i)


244  WorldMatrix = m_body_matrix_world[CurParent];


245 


246  m_body_matrix_world[i] = WorldMatrix * m_body_matrix_local[i] * mat4(quat::fromeuler_xyz(m_body_rotation[i]));


247  }


248 


249  m_velocity = vec3(20.f, .0f, .0f);


250 


251  m_position += m_rotation.transform(m_velocity) * seconds;


252  }


253 


254  virtual void TickDraw(float seconds)


255  {


256  WorldEntity::TickDraw(seconds);


257 


258  if (!m_ready)


259  {


260  for (int i = 0; i < m_body_parts.Count(); i++)


261  m_body_parts[i].MeshConvert();


262  m_ready = true;


263  }


264 


265  m_rotation *= quat::rotate(seconds * 30.0f, vec3(0, 1, 0));


266  mat4 main_matrix = mat4::translate(m_position) * mat4(m_rotation);


267 


268  for (int i = 0; i < EBP_MAX; ++i)


269  m_body_parts[i].Render(main_matrix * m_body_matrix_world[i]);


270  }


271 


272  private:


273  //Base datas


274  Array<EasyMesh> m_body_parts;


275  Array<int> m_body_parent;


276  Array<mat4> m_body_matrix_local;


277  //Frame datas


278  Array<mat4> m_body_matrix_world;


279  Array<vec3> m_body_rotation;


280  Array<vec3> m_body_cos;


281 


282  bool m_ready;


283  };


284 


285  #endif /* __CHARACTER_H__ */


286 

