OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
StdMeshInstance Class Reference

#include <StdMesh.h>

Collaboration diagram for StdMeshInstance:
[legend]

Classes

class  AttachedMesh
 
class  SerializableValueProvider
 

Public Types

enum  AttachMeshFlags { AM_None = 0, AM_DrawBefore = 1 << 0, AM_MatchSkeleton = 1 << 1 }
 
typedef
StdMeshInstanceAnimationNode 
AnimationNode
 
typedef
StdSubMeshInstance::FaceOrdering 
FaceOrdering
 
typedef
StdMeshInstanceValueProvider 
ValueProvider
 
typedef std::vector
< AttachedMesh * > 
AttachedMeshList
 
typedef
AttachedMeshList::const_iterator 
AttachedMeshIter
 

Public Member Functions

 StdMeshInstance (const StdMesh &mesh, float completion=1.0f)
 
 ~StdMeshInstance ()
 
void SetFaceOrdering (FaceOrdering ordering)
 
void SetFaceOrderingForClrModulation (uint32_t clrmod)
 
const std::vector
< StdMeshVertex > & 
GetSharedVertices () const
 
size_t GetNumSharedVertices () const
 
void SetCompletion (float completion)
 
float GetCompletion () const
 
AnimationNodePlayAnimation (const StdStrBuf &animation_name, int slot, AnimationNode *sibling, ValueProvider *position, ValueProvider *weight, bool stop_previous_animation)
 
AnimationNodePlayAnimation (const StdMeshAnimation &animation, int slot, AnimationNode *sibling, ValueProvider *position, ValueProvider *weight, bool stop_previous_animation)
 
AnimationNodePlayAnimation (const StdMeshBone *bone, const StdMeshTransformation &trans, int slot, AnimationNode *sibling, ValueProvider *weight, bool stop_previous_animation)
 
void StopAnimation (AnimationNode *node)
 
AnimationNodeGetAnimationNodeByNumber (unsigned int number)
 
AnimationNodeGetRootAnimationForSlot (int slot)
 
void SetAnimationPosition (AnimationNode *node, ValueProvider *position)
 
void SetAnimationBoneTransform (AnimationNode *node, const StdMeshTransformation &trans)
 
void SetAnimationWeight (AnimationNode *node, ValueProvider *weight)
 
void ExecuteAnimation (float dt)
 
AttachedMeshAttachMesh (const StdMesh &mesh, AttachedMesh::Denumerator *denumerator, const StdStrBuf &parent_bone, const StdStrBuf &child_bone, const StdMeshMatrix &transformation=StdMeshMatrix::Identity(), uint32_t flags=AM_None, unsigned int attach_number=0)
 
AttachedMeshAttachMesh (StdMeshInstance &instance, AttachedMesh::Denumerator *denumerator, const StdStrBuf &parent_bone, const StdStrBuf &child_bone, const StdMeshMatrix &transformation=StdMeshMatrix::Identity(), uint32_t flags=AM_None, bool own_child=false, unsigned int attach_number=0)
 
bool DetachMesh (unsigned int number)
 
AttachedMeshGetAttachedMeshByNumber (unsigned int number) const
 
AttachedMeshIter AttachedMeshesBegin () const
 
AttachedMeshIter AttachedMeshesEnd () const
 
AttachedMeshGetAttachParent () const
 
size_t GetNumSubMeshes () const
 
StdSubMeshInstanceGetSubMesh (size_t i)
 
const StdSubMeshInstanceGetSubMesh (size_t i) const
 
const StdSubMeshInstanceGetSubMeshOrdered (size_t i) const
 
void SetMaterial (size_t i, const StdMeshMaterial &material)
 
const StdMeshMatrix & GetBoneTransform (size_t i) const
 
size_t GetBoneCount () const
 
bool UpdateBoneTransforms ()
 
void ReorderFaces (StdMeshMatrix *global_trans)
 
void CompileFunc (StdCompiler *pComp, AttachedMesh::DenumeratorFactoryFunc Factory)
 
void DenumeratePointers ()
 
void ClearPointers (class C4Object *pObj)
 
const StdMeshGetMesh () const
 
GLuint GetIBO () const
 
unsigned int GetVAOID () const
 

Protected Types

typedef std::vector
< AnimationNode * > 
AnimationNodeList
 

Protected Member Functions

void UpdateIBO ()
 
AttachedMeshAttachMeshImpl (StdMeshInstance &instance, AttachedMesh::Denumerator *denumerator, const StdStrBuf &parent_bone, const StdStrBuf &child_bone, const StdMeshMatrix &transformation, uint32_t flags, bool own_child, unsigned int new_attach_number)
 
AnimationNodeList::iterator GetStackIterForSlot (int slot, bool create)
 
void InsertAnimationNode (AnimationNode *node, int slot, AnimationNode *sibling, ValueProvider *weight, bool stop_previous_animation)
 
bool ExecuteAnimationNode (AnimationNode *node)
 
void ApplyBoneTransformToVertices (const std::vector< StdSubMesh::Vertex > &mesh_vertices, std::vector< StdMeshVertex > &instance_vertices)
 
void SetBoneTransformsDirty (bool value)
 

Static Protected Member Functions

template<typename IteratorType , typename FuncObj >
static bool ScanAttachTree (IteratorType begin, IteratorType end, const FuncObj &obj)
 

Protected Attributes

const StdMeshMesh
 
float Completion
 
AnimationNodeList AnimationNodes
 
AnimationNodeList AnimationStack
 
std::vector< StdMeshMatrix > BoneTransforms
 
std::vector< StdSubMeshInstance * > SubMeshInstances
 
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
 
std::vector< AttachedMesh * > AttachChildren
 
AttachedMeshAttachParent
 
bool BoneTransformsDirty
 
GLuint ibo
 
unsigned int vaoid
 

Friends

class StdMeshMaterialUpdate
 
class StdMeshAnimationUpdate
 
class StdMeshUpdate
 

Detailed Description

Definition at line 393 of file StdMesh.h.

Member Typedef Documentation

typedef std::vector<AnimationNode*> StdMeshInstance::AnimationNodeList
protected

Definition at line 639 of file StdMesh.h.

typedef AttachedMeshList::const_iterator StdMeshInstance::AttachedMeshIter

Definition at line 544 of file StdMesh.h.

Definition at line 543 of file StdMesh.h.

Member Enumeration Documentation

Enumerator
AM_None 
AM_DrawBefore 
AM_MatchSkeleton 

Definition at line 405 of file StdMesh.h.

Constructor & Destructor Documentation

StdMeshInstance::StdMeshInstance ( const StdMesh mesh,
float  completion = 1.0f 
)

Definition at line 1070 of file StdMesh.cpp.

References StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), SubMeshInstances, and SubMeshInstancesOrdered.

Referenced by AttachMesh().

1070  :
1071  Mesh(&mesh), Completion(completion),
1072  BoneTransforms(Mesh->GetSkeleton().GetNumBones(), StdMeshMatrix::Identity()),
1074  BoneTransformsDirty(false)
1075 #ifndef USE_CONSOLE
1076  , ibo(0), vaoid(0)
1077 #endif
1078 {
1079  // Create submesh instances
1080  for (unsigned int i = 0; i < Mesh->GetNumSubMeshes(); ++i)
1081  {
1082  const StdSubMesh& submesh = Mesh->GetSubMesh(i);
1083  SubMeshInstances[i] = new StdSubMeshInstance(*this, submesh, completion);
1084  }
1085 
1086  // copy, order is fine at the moment since only default materials are used.
1088 }
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
Definition: StdMesh.h:656
bool BoneTransformsDirty
Definition: StdMesh.h:663
unsigned int vaoid
Definition: StdMesh.h:671
GLuint ibo
Definition: StdMesh.h:670
const StdMeshSkeleton & GetSkeleton() const
Definition: StdMesh.h:203
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
const StdMesh * Mesh
Definition: StdMesh.h:647
float Completion
Definition: StdMesh.h:649
AttachedMesh * AttachParent
Definition: StdMesh.h:661
std::vector< StdMeshMatrix > BoneTransforms
Definition: StdMesh.h:653
size_t GetNumBones() const
Definition: StdMesh.h:117
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

StdMeshInstance::~StdMeshInstance ( )

Definition at line 1090 of file StdMesh.cpp.

References AnimationNodes, AnimationStack, AttachChildren, AttachParent, DetachMesh(), CStdGL::FreeVAOID(), ibo, StdMeshInstance::AttachedMesh::Number, StdMeshInstance::AttachedMesh::Parent, pGL, StopAnimation(), SubMeshInstances, and vaoid.

1091 {
1092 #ifndef USE_CONSOLE
1093  if (ibo) glDeleteBuffers(1, &ibo);
1094  if (vaoid) pGL->FreeVAOID(vaoid);
1095 #endif
1096 
1097  // If we are attached then detach from parent
1098  if (AttachParent)
1100 
1101  // Remove all attach children
1102  while (!AttachChildren.empty())
1103  DetachMesh(AttachChildren.back()->Number);
1104 
1105  while (!AnimationStack.empty())
1106  StopAnimation(AnimationStack.front());
1107  assert(AnimationNodes.empty());
1108 
1109  // Delete submeshes
1110  for (auto & SubMeshInstance : SubMeshInstances)
1111  {
1112  delete SubMeshInstance;
1113  }
1114 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
unsigned int vaoid
Definition: StdMesh.h:671
GLuint ibo
Definition: StdMesh.h:670
void FreeVAOID(unsigned int vaoid)
Definition: C4DrawGL.cpp:967
void StopAnimation(AnimationNode *node)
Definition: StdMesh.cpp:1188
bool DetachMesh(unsigned int number)
Definition: StdMesh.cpp:1393
AttachedMesh * AttachParent
Definition: StdMesh.h:661
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
CStdGL * pGL
Definition: C4DrawGL.cpp:905
StdMeshInstance * Parent
Definition: StdMesh.h:510
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Member Function Documentation

void StdMeshInstance::ApplyBoneTransformToVertices ( const std::vector< StdSubMesh::Vertex > &  mesh_vertices,
std::vector< StdMeshVertex > &  instance_vertices 
)
protected
AttachedMeshIter StdMeshInstance::AttachedMeshesBegin ( ) const
inline

Definition at line 584 of file StdMesh.h.

Referenced by StdMeshUpdate::Update().

584 { return AttachChildren.begin(); }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660

Here is the caller graph for this function:

AttachedMeshIter StdMeshInstance::AttachedMeshesEnd ( ) const
inline

Definition at line 585 of file StdMesh.h.

Referenced by StdMeshUpdate::Update().

585 { return AttachChildren.end(); }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660

Here is the caller graph for this function:

StdMeshInstance::AttachedMesh * StdMeshInstance::AttachMesh ( const StdMesh mesh,
AttachedMesh::Denumerator denumerator,
const StdStrBuf parent_bone,
const StdStrBuf child_bone,
const StdMeshMatrix &  transformation = StdMeshMatrix::Identity(),
uint32_t  flags = AM_None,
unsigned int  attach_number = 0 
)

Definition at line 1331 of file StdMesh.cpp.

References StdMeshInstance().

1332 {
1333  std::unique_ptr<AttachedMesh::Denumerator> auto_denumerator(denumerator);
1334 
1335  StdMeshInstance* instance = new StdMeshInstance(mesh, 1.0f);
1336  AttachedMesh* attach = AttachMesh(*instance, auto_denumerator.release(), parent_bone, child_bone, transformation, flags, true, attach_number);
1337  if (!attach) { delete instance; return nullptr; }
1338  return attach;
1339 }
StdMeshInstance(const StdMesh &mesh, float completion=1.0f)
Definition: StdMesh.cpp:1070
AttachedMesh * AttachMesh(const StdMesh &mesh, AttachedMesh::Denumerator *denumerator, const StdStrBuf &parent_bone, const StdStrBuf &child_bone, const StdMeshMatrix &transformation=StdMeshMatrix::Identity(), uint32_t flags=AM_None, unsigned int attach_number=0)
Definition: StdMesh.cpp:1331

Here is the call graph for this function:

StdMeshInstance::AttachedMesh * StdMeshInstance::AttachMesh ( StdMeshInstance instance,
AttachedMesh::Denumerator denumerator,
const StdStrBuf parent_bone,
const StdStrBuf child_bone,
const StdMeshMatrix &  transformation = StdMeshMatrix::Identity(),
uint32_t  flags = AM_None,
bool  own_child = false,
unsigned int  attach_number = 0 
)

Definition at line 1341 of file StdMesh.cpp.

References AttachChildren, AttachMeshImpl(), AttachParent, StdMeshInstance::AttachedMesh::Child, GetAttachedMeshByNumber(), StdMeshInstance::AttachedMesh::OwnChild, and ScanAttachTree().

1342 {
1343  std::unique_ptr<AttachedMesh::Denumerator> auto_denumerator(denumerator);
1344 
1345  // Owned attach children must be set via the topmost instance, to ensure
1346  // attach number uniqueness.
1347  if (AttachParent && AttachParent->OwnChild) return nullptr;
1348 
1349  // Find free index.
1350  unsigned int number = 0;
1351  ScanAttachTree(AttachChildren.begin(), AttachChildren.end(), [&number](AttachedMeshList::const_iterator iter) { number = std::max(number, (*iter)->Number); return true; });
1352  number += 1; // One above highest
1353 
1354  StdMeshInstance* direct_parent = this;
1355  if (attach_number != 0)
1356  {
1357  AttachedMesh* attach = GetAttachedMeshByNumber(attach_number);
1358  if (attach == nullptr) return nullptr;
1359  direct_parent = attach->Child;
1360  }
1361 
1362  return direct_parent->AttachMeshImpl(instance, auto_denumerator.release(), parent_bone, child_bone, transformation, flags, own_child, number);
1363 }
AttachedMesh * GetAttachedMeshByNumber(unsigned int number) const
Definition: StdMesh.cpp:1417
AttachedMesh * AttachMeshImpl(StdMeshInstance &instance, AttachedMesh::Denumerator *denumerator, const StdStrBuf &parent_bone, const StdStrBuf &child_bone, const StdMeshMatrix &transformation, uint32_t flags, bool own_child, unsigned int new_attach_number)
Definition: StdMesh.cpp:1365
AttachedMesh * AttachParent
Definition: StdMesh.h:661
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
static bool ScanAttachTree(IteratorType begin, IteratorType end, const FuncObj &obj)
Definition: StdMesh.cpp:1700

Here is the call graph for this function:

StdMeshInstance::AttachedMesh * StdMeshInstance::AttachMeshImpl ( StdMeshInstance instance,
AttachedMesh::Denumerator denumerator,
const StdStrBuf parent_bone,
const StdStrBuf child_bone,
const StdMeshMatrix &  transformation,
uint32_t  flags,
bool  own_child,
unsigned int  new_attach_number 
)
protected

Definition at line 1365 of file StdMesh.cpp.

References AM_DrawBefore, AttachChildren, AttachParent, StdMeshSkeleton::GetBoneByName(), StdMesh::GetSkeleton(), StdMeshBone::Index, Mesh, and StdMeshInstance::AttachedMesh::Parent.

Referenced by AttachMesh().

1366 {
1367  std::unique_ptr<AttachedMesh::Denumerator> auto_denumerator(denumerator);
1368 
1369  // We don't allow an instance to be attached to multiple parent instances for now
1370  if (instance.AttachParent) return nullptr;
1371 
1372  // Make sure there are no cyclic attachments
1373  for (StdMeshInstance* Parent = this; Parent->AttachParent != nullptr; Parent = Parent->AttachParent->Parent)
1374  if (Parent == &instance)
1375  return nullptr;
1376 
1377  const StdMeshBone* parent_bone_obj = Mesh->GetSkeleton().GetBoneByName(parent_bone);
1378  const StdMeshBone* child_bone_obj = instance.Mesh->GetSkeleton().GetBoneByName(child_bone);
1379  if (!parent_bone_obj || !child_bone_obj) return nullptr;
1380 
1381  AttachedMesh* attach = new AttachedMesh(new_attach_number, this, &instance, own_child, auto_denumerator.release(), parent_bone_obj->Index, child_bone_obj->Index, transformation, flags);
1382  instance.AttachParent = attach;
1383 
1384  // If DrawInFront is set then sort before others so that drawing order is easy
1385  if(flags & AM_DrawBefore)
1386  AttachChildren.insert(AttachChildren.begin(), attach);
1387  else
1388  AttachChildren.insert(AttachChildren.end(), attach);
1389 
1390  return attach;
1391 }
const StdMeshSkeleton & GetSkeleton() const
Definition: StdMesh.h:203
const StdMesh * Mesh
Definition: StdMesh.h:647
const StdMeshBone * GetBoneByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:386
AttachedMesh * AttachParent
Definition: StdMesh.h:661
unsigned int Index
Definition: StdMesh.h:32
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
StdMeshInstance * Parent
Definition: StdMesh.h:510

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::ClearPointers ( class C4Object pObj)

Definition at line 1684 of file StdMesh.cpp.

References AnimationNodes, AttachChildren, StdMeshInstanceAnimationNode::ClearPointers(), and DetachMesh().

Referenced by C4Object::ClearPointers().

1685 {
1686  for(auto & AnimationNode : AnimationNodes)
1687  if(AnimationNode)
1689 
1690  std::vector<unsigned int> Removal;
1691  for(auto & i : AttachChildren)
1692  if(!i->ClearPointers(pObj))
1693  Removal.push_back(i->Number);
1694 
1695  for(unsigned int i : Removal)
1696  DetachMesh(i);
1697 }
void ClearPointers(class C4Object *pObj)
Definition: StdMesh.cpp:951
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
bool DetachMesh(unsigned int number)
Definition: StdMesh.cpp:1393
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::CompileFunc ( StdCompiler pComp,
AttachedMesh::DenumeratorFactoryFunc  Factory 
)

Definition at line 1576 of file StdMesh.cpp.

References AnimationNodes, AnimationStack, AttachChildren, AttachParent, StdCompiler::excCorrupt(), GetStackIterForSlot(), StdCompiler::isDeserializer(), StdMeshInstanceAnimationNode::LinearInterpolationNode, mkNamingAdapt(), mkNamingCountAdapt(), mkNamingPtrAdapt(), mkParAdapt(), StdMeshInstanceAnimationNode::Number, StdMeshInstance::AttachedMesh::Parent, SetBoneTransformsDirty(), StdMeshInstanceAnimationNode::Slot, SubMeshInstances, SubMeshInstancesOrdered, StdMeshInstanceAnimationNode::Type, and StdCompiler::Value().

1577 {
1578  if(pComp->isDeserializer())
1579  {
1580  // Only initially created instances can be compiled
1581  assert(!AttachParent);
1582  assert(AttachChildren.empty());
1583  assert(AnimationStack.empty());
1584  SetBoneTransformsDirty(true);
1585 
1586  bool valid;
1587  pComp->Value(mkNamingAdapt(valid, "Valid"));
1588  if(!valid) pComp->excCorrupt("Mesh instance is invalid");
1589 
1590  int32_t iSubMeshCnt;
1591  pComp->Value(mkNamingCountAdapt(iSubMeshCnt, "SubMesh"));
1592  if(static_cast<uint32_t>(iSubMeshCnt) != SubMeshInstances.size())
1593  pComp->excCorrupt("Invalid number of submeshes");
1594  for(int32_t i = 0; i < iSubMeshCnt; ++i)
1595  pComp->Value(mkNamingAdapt(*SubMeshInstances[i], "SubMesh"));
1596 #ifndef USE_CONSOLE
1597  // The sorting predicate depends on having a gfx implementation.
1598  std::stable_sort(SubMeshInstancesOrdered.begin(), SubMeshInstancesOrdered.end(), StdMeshSubMeshInstanceVisibilityCmpPred());
1599 #endif
1600 
1601  int32_t iAnimCnt = AnimationStack.size();
1602  pComp->Value(mkNamingCountAdapt(iAnimCnt, "AnimationNode"));
1603 
1604  for(int32_t i = 0; i < iAnimCnt; ++i)
1605  {
1606  AnimationNode* node = nullptr;
1607  pComp->Value(mkParAdapt(mkNamingPtrAdapt(node, "AnimationNode"), Mesh));
1608  AnimationNodeList::iterator iter = GetStackIterForSlot(node->Slot, true);
1609  if(*iter != nullptr) { delete node; pComp->excCorrupt("Duplicate animation slot index"); }
1610  *iter = node;
1611 
1612  // Add nodes into lookup table
1613  std::vector<AnimationNode*> nodes(1, node);
1614  while(!nodes.empty())
1615  {
1616  node = nodes.back();
1617  nodes.erase(nodes.end()-1);
1618 
1619  if (AnimationNodes.size() <= node->Number)
1620  AnimationNodes.resize(node->Number+1);
1621  if(AnimationNodes[node->Number] != nullptr) pComp->excCorrupt("Duplicate animation node number");
1622  AnimationNodes[node->Number] = node;
1623 
1624  if(node->Type == AnimationNode::LinearInterpolationNode)
1625  {
1626  nodes.push_back(node->LinearInterpolation.ChildLeft);
1627  nodes.push_back(node->LinearInterpolation.ChildRight);
1628  }
1629  }
1630  }
1631 
1632  int32_t iAttachedCnt;
1633  pComp->Value(mkNamingCountAdapt(iAttachedCnt, "Attached"));
1634 
1635  for(int32_t i = 0; i < iAttachedCnt; ++i)
1636  {
1637  AttachChildren.push_back(new AttachedMesh);
1638  AttachedMesh* attach = AttachChildren.back();
1639 
1640  attach->Parent = this;
1641  pComp->Value(mkNamingAdapt(mkParAdapt(*attach, Factory), "Attached"));
1642  }
1643  }
1644  else
1645  {
1646  // Write something to make sure that the parent
1647  // named section ([Mesh] or [ChildInstance]) is written.
1648  // StdCompilerIni does not make a difference between
1649  // non-existing and empty named sections.
1650  bool valid = true;
1651  pComp->Value(mkNamingAdapt(valid, "Valid"));
1652 
1653  int32_t iSubMeshCnt = SubMeshInstances.size();
1654  pComp->Value(mkNamingCountAdapt(iSubMeshCnt, "SubMesh"));
1655  for(int32_t i = 0; i < iSubMeshCnt; ++i)
1656  pComp->Value(mkNamingAdapt(*SubMeshInstances[i], "SubMesh"));
1657 
1658  int32_t iAnimCnt = AnimationStack.size();
1659  pComp->Value(mkNamingCountAdapt(iAnimCnt, "AnimationNode"));
1660 
1661  for(auto & iter : AnimationStack)
1662  pComp->Value(mkParAdapt(mkNamingPtrAdapt(iter, "AnimationNode"), Mesh));
1663 
1664  int32_t iAttachedCnt = AttachChildren.size();
1665  pComp->Value(mkNamingCountAdapt(iAttachedCnt, "Attached"));
1666 
1667  for(auto & i : AttachChildren)
1668  pComp->Value(mkNamingAdapt(mkParAdapt(*i, Factory), "Attached"));
1669  }
1670 }
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
Definition: StdMesh.h:656
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
StdNamingCountAdapt< int_t > mkNamingCountAdapt(int_t &iCount, const char *szName)
Definition: StdAdaptors.h:976
void excCorrupt(const char *szMessage,...)
Definition: StdCompiler.h:249
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
const StdMesh * Mesh
Definition: StdMesh.h:647
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual bool isDeserializer()
Definition: StdCompiler.h:53
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
AttachedMesh * AttachParent
Definition: StdMesh.h:661
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:458
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create)
Definition: StdMesh.cpp:1716
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
StdPtrAdapt< T > mkNamingPtrAdapt(T *&rpObj, const char *szNaming)
Definition: StdAdaptors.h:604
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

void StdMeshInstance::DenumeratePointers ( )

Definition at line 1672 of file StdMesh.cpp.

References AnimationNodes, AttachChildren, and StdMeshInstanceAnimationNode::DenumeratePointers().

Referenced by C4Object::Denumerate().

1673 {
1674  for(auto & AnimationNode : AnimationNodes)
1675  if(AnimationNode)
1677 
1678  for(auto & i : AttachChildren)
1679  {
1680  i->DenumeratePointers();
1681  }
1682 }
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660

Here is the call graph for this function:

Here is the caller graph for this function:

bool StdMeshInstance::DetachMesh ( unsigned int  number)

Definition at line 1393 of file StdMesh.cpp.

References AttachChildren, AttachParent, StdMeshInstance::AttachedMesh::Child, StdMeshInstance::AttachedMesh::Parent, and ScanAttachTree().

Referenced by ClearPointers(), StdMeshUpdate::Update(), C4Object::UpdateGraphics(), and ~StdMeshInstance().

1394 {
1395  return !ScanAttachTree(AttachChildren.begin(), AttachChildren.end(), [this, number](AttachedMeshList::iterator iter)
1396  {
1397  if ((*iter)->Number == number)
1398  {
1399  AttachedMesh* attached = *iter;
1400 
1401  // Reset attach parent of child so it does not try
1402  // to detach itself on destruction.
1403  attached->Child->AttachParent = nullptr;
1404  attached->Parent->AttachChildren.erase(iter);
1405 
1406  delete attached;
1407 
1408  // Finish scan
1409  return false;
1410  }
1411 
1412  // Continue scan
1413  return true;
1414  });
1415 }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
static bool ScanAttachTree(IteratorType begin, IteratorType end, const FuncObj &obj)
Definition: StdMesh.cpp:1700

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::ExecuteAnimation ( float  dt)

Definition at line 1286 of file StdMesh.cpp.

References AnimationStack, AttachChildren, StdMeshMaterial::BestTechniqueIndex, StdMeshMaterialTextureUnit::Duration, ExecuteAnimationNode(), StdSubMeshInstance::GetMaterial(), StdMeshMaterialTextureUnit::GetNumTextures(), StdMeshMaterialTextureUnit::HasFrameAnimation(), StdMeshMaterialTextureUnit::HasTexCoordAnimation(), StdSubMeshInstance::PassData, StdMeshMaterialTechnique::Passes, StdSubMeshInstance::TexUnit::Phase, StdSubMeshInstance::TexUnit::PhaseDelay, StdSubMeshInstance::TexUnit::Position, StopAnimation(), SubMeshInstances, StdMeshMaterial::Techniques, and StdSubMeshInstance::Pass::TexUnits.

Referenced by C4Object::Execute().

1287 {
1288  // Iterate from the back since slots might be removed
1289  for (unsigned int i = AnimationStack.size(); i > 0; --i)
1292 
1293 #ifndef USE_CONSOLE
1294  // Update animated textures
1295  for (auto & SubMeshInstance : SubMeshInstances)
1296  {
1297  StdSubMeshInstance& submesh = *SubMeshInstance;
1298  const StdMeshMaterial& material = submesh.GetMaterial();
1299  const StdMeshMaterialTechnique& technique = material.Techniques[material.BestTechniqueIndex];
1300  for (unsigned int j = 0; j < submesh.PassData.size(); ++j)
1301  {
1302  StdSubMeshInstance::Pass& pass = submesh.PassData[j];
1303  for (unsigned int k = 0; k < pass.TexUnits.size(); ++k)
1304  {
1305  const StdMeshMaterialTextureUnit& texunit = technique.Passes[j].TextureUnits[k];
1306  StdSubMeshInstance::TexUnit& texunit_instance = submesh.PassData[j].TexUnits[k];
1307  if (texunit.HasFrameAnimation())
1308  {
1309  const unsigned int NumPhases = texunit.GetNumTextures();
1310  const float PhaseDuration = texunit.Duration / NumPhases;
1311 
1312  const float Position = texunit_instance.PhaseDelay + dt;
1313  const unsigned int AddPhases = static_cast<unsigned int>(Position / PhaseDuration);
1314 
1315  texunit_instance.Phase = (texunit_instance.Phase + AddPhases) % NumPhases;
1316  texunit_instance.PhaseDelay = Position - AddPhases * PhaseDuration;
1317  }
1318 
1319  if (texunit.HasTexCoordAnimation())
1320  texunit_instance.Position += dt;
1321  }
1322  }
1323  }
1324 #endif
1325 
1326  // Update animation for attached meshes
1327  for (auto & iter : AttachChildren)
1328  iter->Child->ExecuteAnimation(dt);
1329 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
const StdMeshMaterial & GetMaterial() const
Definition: StdMesh.h:270
std::vector< TexUnit > TexUnits
Definition: StdMesh.h:297
size_t GetNumTextures() const
void StopAnimation(AnimationNode *node)
Definition: StdMesh.cpp:1188
std::vector< Pass > PassData
Definition: StdMesh.h:300
bool HasTexCoordAnimation() const
bool ExecuteAnimationNode(AnimationNode *node)
Definition: StdMesh.cpp:1814
std::vector< StdMeshMaterialPass > Passes
std::vector< StdMeshMaterialTechnique > Techniques
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

bool StdMeshInstance::ExecuteAnimationNode ( AnimationNode node)
protected

Definition at line 1814 of file StdMesh.cpp.

References Clamp(), StdMeshInstanceAnimationNode::CustomNode, StdMeshInstanceValueProvider::Execute(), Fix0, ftofix(), StdMeshInstanceAnimationNode::GetAnimation(), StdMeshInstanceAnimationNode::GetLeftChild(), StdMeshInstanceAnimationNode::GetPositionProvider(), StdMeshInstanceAnimationNode::GetRightChild(), StdMeshInstanceAnimationNode::GetType(), StdMeshInstanceAnimationNode::GetWeight(), StdMeshInstanceAnimationNode::GetWeightProvider(), itofix(), StdMeshInstanceAnimationNode::LeafNode, StdMeshAnimation::Length, StdMeshInstanceAnimationNode::LinearInterpolationNode, SetBoneTransformsDirty(), StopAnimation(), and StdMeshInstanceValueProvider::Value.

Referenced by ExecuteAnimation().

1815 {
1816  ValueProvider* provider = nullptr;
1817  C4Real min;
1818  C4Real max;
1819 
1820  switch (node->GetType())
1821  {
1823  provider = node->GetPositionProvider();
1824  min = Fix0;
1825  max = ftofix(node->GetAnimation()->Length);
1826  break;
1828  // No execution necessary
1829  return true;
1831  provider = node->GetWeightProvider();
1832  min = Fix0;
1833  max = itofix(1);
1834  break;
1835  default:
1836  assert(false);
1837  break;
1838  }
1839 
1840  assert(provider);
1841  const C4Real old_value = provider->Value;
1842 
1843  if (!provider->Execute())
1844  {
1845  if (node->GetType() == AnimationNode::LeafNode) return false;
1846 
1847  // Remove the child with less weight (normally weight reaches 0.0 or 1.0)
1848  if (node->GetWeight() > itofix(1, 2))
1849  {
1850  // Remove both children (by parent) if other wants to be deleted as well
1851  if (!ExecuteAnimationNode(node->GetRightChild())) return false;
1852  // Remove left child as it has less weight
1853  StopAnimation(node->LinearInterpolation.ChildLeft);
1854  }
1855  else
1856  {
1857  // Remove both children (by parent) if other wants to be deleted as well
1858  if (!ExecuteAnimationNode(node->GetLeftChild())) return false;
1859  // Remove right child as it has less weight
1860  StopAnimation(node->LinearInterpolation.ChildRight);
1861  }
1862  }
1863  else
1864  {
1865  if (provider->Value != old_value)
1866  {
1867  provider->Value = Clamp(provider->Value, min, max);
1868  SetBoneTransformsDirty(true);
1869  }
1870 
1871  if (node->GetType() == AnimationNode::LinearInterpolationNode)
1872  {
1873  const bool left_result = ExecuteAnimationNode(node->GetLeftChild());
1874  const bool right_result = ExecuteAnimationNode(node->GetRightChild());
1875 
1876  // Remove this node completely
1877  if (!left_result && !right_result)
1878  return false;
1879 
1880  // Note that either of this also removes node
1881  if (!left_result)
1882  StopAnimation(node->GetLeftChild());
1883  if (!right_result)
1884  StopAnimation(node->GetRightChild());
1885  }
1886  }
1887 
1888  return true;
1889 }
StdMeshInstanceValueProvider ValueProvider
Definition: StdMesh.h:411
Definition: C4Real.h:58
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
void StopAnimation(AnimationNode *node)
Definition: StdMesh.cpp:1188
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
C4Fixed ftofix(float x)
Definition: C4Real.h:258
bool ExecuteAnimationNode(AnimationNode *node)
Definition: StdMesh.cpp:1814
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

Here is the caller graph for this function:

StdMeshInstance::AnimationNode * StdMeshInstance::GetAnimationNodeByNumber ( unsigned int  number)

Definition at line 1245 of file StdMesh.cpp.

References AnimationNodes.

1246 {
1247  if (number >= AnimationNodes.size()) return nullptr;
1248  return AnimationNodes[number];
1249 }
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
StdMeshInstance::AttachedMesh * StdMeshInstance::GetAttachedMeshByNumber ( unsigned int  number) const

Definition at line 1417 of file StdMesh.cpp.

References AttachChildren, and ScanAttachTree().

Referenced by AttachMesh().

1418 {
1419  StdMeshInstance::AttachedMesh* result = nullptr;
1420 
1421  ScanAttachTree(AttachChildren.begin(), AttachChildren.end(), [number, &result](AttachedMeshList::const_iterator iter)
1422  {
1423  if ((*iter)->Number == number)
1424  {
1425  result = *iter;
1426  return false;
1427  }
1428 
1429  return true;
1430  });
1431 
1432  return result;
1433 }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
static bool ScanAttachTree(IteratorType begin, IteratorType end, const FuncObj &obj)
Definition: StdMesh.cpp:1700

Here is the call graph for this function:

Here is the caller graph for this function:

AttachedMesh* StdMeshInstance::GetAttachParent ( ) const
inline

Definition at line 586 of file StdMesh.h.

Referenced by C4Object::Execute(), and C4Object::UpdateGraphics().

586 { return AttachParent; }
AttachedMesh * AttachParent
Definition: StdMesh.h:661

Here is the caller graph for this function:

size_t StdMeshInstance::GetBoneCount ( ) const

Definition at line 1461 of file StdMesh.cpp.

References AM_MatchSkeleton, AttachParent, BoneTransforms, and StdMeshInstance::AttachedMesh::GetFlags().

1462 {
1463  if ((AttachParent != nullptr) && (AttachParent->GetFlags() & AM_MatchSkeleton))
1464  return AttachParent->MatchedBoneInParentSkeleton.size();
1465  else
1466  return BoneTransforms.size();
1467 }
uint32_t GetFlags() const
Definition: StdMesh.h:519
AttachedMesh * AttachParent
Definition: StdMesh.h:661
std::vector< StdMeshMatrix > BoneTransforms
Definition: StdMesh.h:653

Here is the call graph for this function:

const StdMeshMatrix & StdMeshInstance::GetBoneTransform ( size_t  i) const

Definition at line 1444 of file StdMesh.cpp.

References AM_MatchSkeleton, AttachParent, BoneTransforms, StdMeshInstance::AttachedMesh::GetFlags(), and StdMeshInstance::AttachedMesh::Parent.

Referenced by UpdateBoneTransforms().

1445 {
1446  if ((AttachParent != nullptr) && (AttachParent->GetFlags() & AM_MatchSkeleton))
1447  {
1448  assert(i < AttachParent->MatchedBoneInParentSkeleton.size());
1449 
1450  int parent_bone_index = AttachParent->MatchedBoneInParentSkeleton[i];
1451 
1452  if (parent_bone_index > -1)
1453  {
1454  return AttachParent->Parent->BoneTransforms[i];
1455  }
1456  }
1457 
1458  return BoneTransforms[i];
1459 }
uint32_t GetFlags() const
Definition: StdMesh.h:519
AttachedMesh * AttachParent
Definition: StdMesh.h:661
std::vector< StdMeshMatrix > BoneTransforms
Definition: StdMesh.h:653
StdMeshInstance * Parent
Definition: StdMesh.h:510

Here is the call graph for this function:

Here is the caller graph for this function:

float StdMeshInstance::GetCompletion ( ) const
inline

Definition at line 554 of file StdMesh.h.

Referenced by StdSubMeshInstance::SetFaceOrdering(), and StdMeshUpdate::Update().

554 { return Completion; }
float Completion
Definition: StdMesh.h:649

Here is the caller graph for this function:

GLuint StdMeshInstance::GetIBO ( ) const
inline

Definition at line 625 of file StdMesh.h.

625 { return ibo ? ibo : Mesh->GetIBO(); }
GLuint ibo
Definition: StdMesh.h:670
GLuint GetIBO() const
Definition: StdMesh.h:213
const StdMesh * Mesh
Definition: StdMesh.h:647
const StdMesh& StdMeshInstance::GetMesh ( ) const
inline

Definition at line 622 of file StdMesh.h.

Referenced by StdMeshInstance::AttachedMesh::AttachedMesh(), C4Object::DrawFaceImpl(), CStdGL::PerformMesh(), StdMeshMaterialUpdate::Update(), StdMeshUpdate::Update(), and C4Object::UpdateGraphics().

622 { return *Mesh; }
const StdMesh * Mesh
Definition: StdMesh.h:647

Here is the caller graph for this function:

size_t StdMeshInstance::GetNumSharedVertices ( ) const
inline

Definition at line 550 of file StdMesh.h.

550 { return GetSharedVertices().size(); }
const std::vector< StdMeshVertex > & GetSharedVertices() const
Definition: StdMesh.h:549
size_t StdMeshInstance::GetNumSubMeshes ( ) const
inline

Definition at line 588 of file StdMesh.h.

588 { return SubMeshInstances.size(); }
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
StdMeshInstance::AnimationNode * StdMeshInstance::GetRootAnimationForSlot ( int  slot)

Definition at line 1251 of file StdMesh.cpp.

References AnimationStack, and GetStackIterForSlot().

Referenced by C4Object::CompileFunc(), and InsertAnimationNode().

1252 {
1253  AnimationNodeList::iterator iter = GetStackIterForSlot(slot, false);
1254  if (iter == AnimationStack.end()) return nullptr;
1255  return *iter;
1256 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create)
Definition: StdMesh.cpp:1716

Here is the call graph for this function:

Here is the caller graph for this function:

const std::vector<StdMeshVertex>& StdMeshInstance::GetSharedVertices ( ) const
inline

Definition at line 549 of file StdMesh.h.

Referenced by StdSubMeshInstance::LoadFacesForCompletion(), and ReorderFaces().

549 { return Mesh->GetSharedVertices(); }
const std::vector< Vertex > & GetSharedVertices() const
Definition: StdMesh.h:201
const StdMesh * Mesh
Definition: StdMesh.h:647

Here is the caller graph for this function:

StdMeshInstance::AnimationNodeList::iterator StdMeshInstance::GetStackIterForSlot ( int  slot,
bool  create 
)
protected

Definition at line 1716 of file StdMesh.cpp.

References AnimationStack.

Referenced by CompileFunc(), GetRootAnimationForSlot(), InsertAnimationNode(), and StopAnimation().

1717 {
1718  // TODO: bsearch
1719  for (AnimationNodeList::iterator iter = AnimationStack.begin(); iter != AnimationStack.end(); ++iter)
1720  {
1721  if ((*iter)->Slot == slot)
1722  {
1723  return iter;
1724  }
1725  else if ((*iter)->Slot > slot)
1726  {
1727  if (!create)
1728  return AnimationStack.end();
1729  else
1730  return AnimationStack.insert(iter, nullptr);
1731  }
1732  }
1733 
1734  if (!create)
1735  return AnimationStack.end();
1736  else
1737  return AnimationStack.insert(AnimationStack.end(), nullptr);
1738 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652

Here is the caller graph for this function:

StdSubMeshInstance& StdMeshInstance::GetSubMesh ( size_t  i)
inline

Definition at line 589 of file StdMesh.h.

589 { return *SubMeshInstances[i]; }
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
const StdSubMeshInstance& StdMeshInstance::GetSubMesh ( size_t  i) const
inline

Definition at line 590 of file StdMesh.h.

590 { return *SubMeshInstances[i]; }
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
const StdSubMeshInstance& StdMeshInstance::GetSubMeshOrdered ( size_t  i) const
inline

Definition at line 591 of file StdMesh.h.

591 { return *SubMeshInstancesOrdered[i]; }
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
Definition: StdMesh.h:656
unsigned int StdMeshInstance::GetVAOID ( ) const
inline

Definition at line 626 of file StdMesh.h.

626 { return vaoid ? vaoid : Mesh->GetVAOID(); }
unsigned int vaoid
Definition: StdMesh.h:671
const StdMesh * Mesh
Definition: StdMesh.h:647
unsigned int GetVAOID() const
Definition: StdMesh.h:214
void StdMeshInstance::InsertAnimationNode ( AnimationNode node,
int  slot,
AnimationNode sibling,
ValueProvider weight,
bool  stop_previous_animation 
)
protected

Definition at line 1740 of file StdMesh.cpp.

References AnimationNodes, AnimationStack, Clamp(), Fix0, GetRootAnimationForSlot(), GetStackIterForSlot(), itofix(), StdMeshInstanceAnimationNode::Number, StdMeshInstanceAnimationNode::Parent, SetBoneTransformsDirty(), StdMeshInstanceAnimationNode::Slot, StopAnimation(), and StdMeshInstanceValueProvider::Value.

Referenced by PlayAnimation().

1741 {
1742  assert(!sibling || !stop_previous_animation);
1743  // Default
1744  if (!sibling) sibling = GetRootAnimationForSlot(slot);
1745  assert(!sibling || sibling->Slot == slot);
1746 
1747  // Stop any animation already running in this slot?
1748  if (sibling && stop_previous_animation)
1749  {
1750  StopAnimation(sibling);
1751  sibling = nullptr;
1752  }
1753 
1754  // Find two subsequent numbers in case we need to create two nodes, so
1755  // script can deduce the second node.
1756  unsigned int Number1, Number2;
1757  for (Number1 = 0; Number1 < AnimationNodes.size(); ++Number1)
1758  if (AnimationNodes[Number1] == nullptr && (!sibling || Number1+1 == AnimationNodes.size() || AnimationNodes[Number1+1] == nullptr))
1759  break;
1760  /* for(Number2 = Number1+1; Number2 < AnimationNodes.size(); ++Number2)
1761  if(AnimationNodes[Number2] == nullptr)
1762  break;*/
1763  Number2 = Number1 + 1;
1764 
1765  weight->Value = Clamp(weight->Value, Fix0, itofix(1));
1766 
1767  if (Number1 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) nullptr);
1768  if (sibling && Number2 == AnimationNodes.size()) AnimationNodes.push_back( (StdMeshInstance::AnimationNode*) nullptr);
1769 
1770  AnimationNodes[Number1] = node;
1771  node->Number = Number1;
1772  node->Slot = slot;
1773 
1774  if (sibling)
1775  {
1776  AnimationNode* parent = new AnimationNode(node, sibling, weight);
1777  AnimationNodes[Number2] = parent;
1778  parent->Number = Number2;
1779  parent->Slot = slot;
1780 
1781  node->Parent = parent;
1782  parent->Parent = sibling->Parent;
1783  parent->LinearInterpolation.ChildLeft = sibling;
1784  parent->LinearInterpolation.ChildRight = node;
1785  if (sibling->Parent)
1786  {
1787  if (sibling->Parent->LinearInterpolation.ChildLeft == sibling)
1788  sibling->Parent->LinearInterpolation.ChildLeft = parent;
1789  else
1790  sibling->Parent->LinearInterpolation.ChildRight = parent;
1791  }
1792  else
1793  {
1794  // set new parent
1795  AnimationNodeList::iterator iter = GetStackIterForSlot(slot, false);
1796  // slot must not be empty, since sibling uses same slot
1797  assert(iter != AnimationStack.end() && *iter != nullptr);
1798  *iter = parent;
1799  }
1800 
1801  sibling->Parent = parent;
1802  }
1803  else
1804  {
1805  delete weight;
1806  AnimationNodeList::iterator iter = GetStackIterForSlot(slot, true);
1807  assert(!*iter); // we have a sibling if slot is not empty
1808  *iter = node;
1809  }
1810 
1811  SetBoneTransformsDirty(true);
1812 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
AnimationNode * GetRootAnimationForSlot(int slot)
Definition: StdMesh.cpp:1251
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
void StopAnimation(AnimationNode *node)
Definition: StdMesh.cpp:1188
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create)
Definition: StdMesh.cpp:1716
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

Here is the caller graph for this function:

StdMeshInstance::AnimationNode * StdMeshInstance::PlayAnimation ( const StdStrBuf animation_name,
int  slot,
AnimationNode sibling,
ValueProvider position,
ValueProvider weight,
bool  stop_previous_animation 
)

Definition at line 1165 of file StdMesh.cpp.

References StdMeshSkeleton::GetAnimationByName(), and StdMesh::GetSkeleton().

Referenced by C4Object::SetAction(), and C4GraphicsOverlay::UpdateFacet().

1166 {
1167  const StdMeshAnimation* animation = Mesh->GetSkeleton().GetAnimationByName(animation_name);
1168  if (!animation) { delete position; delete weight; return nullptr; }
1169 
1170  return PlayAnimation(*animation, slot, sibling, position, weight, stop_previous_animation);
1171 }
const StdMeshSkeleton & GetSkeleton() const
Definition: StdMesh.h:203
AnimationNode * PlayAnimation(const StdStrBuf &animation_name, int slot, AnimationNode *sibling, ValueProvider *position, ValueProvider *weight, bool stop_previous_animation)
Definition: StdMesh.cpp:1165
const StdMeshAnimation * GetAnimationByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:396
const StdMesh * Mesh
Definition: StdMesh.h:647

Here is the call graph for this function:

Here is the caller graph for this function:

StdMeshInstance::AnimationNode * StdMeshInstance::PlayAnimation ( const StdMeshAnimation animation,
int  slot,
AnimationNode sibling,
ValueProvider position,
ValueProvider weight,
bool  stop_previous_animation 
)

Definition at line 1173 of file StdMesh.cpp.

References Clamp(), Fix0, ftofix(), InsertAnimationNode(), StdMeshAnimation::Length, and StdMeshInstanceValueProvider::Value.

1174 {
1175  position->Value = Clamp(position->Value, Fix0, ftofix(animation.Length));
1176  AnimationNode* child = new AnimationNode(&animation, position);
1177  InsertAnimationNode(child, slot, sibling, weight, stop_previous_animation);
1178  return child;
1179 }
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
void InsertAnimationNode(AnimationNode *node, int slot, AnimationNode *sibling, ValueProvider *weight, bool stop_previous_animation)
Definition: StdMesh.cpp:1740
C4Fixed ftofix(float x)
Definition: C4Real.h:258
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
float Length
Definition: StdMesh.h:98
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

StdMeshInstance::AnimationNode * StdMeshInstance::PlayAnimation ( const StdMeshBone bone,
const StdMeshTransformation &  trans,
int  slot,
AnimationNode sibling,
ValueProvider weight,
bool  stop_previous_animation 
)

Definition at line 1181 of file StdMesh.cpp.

References InsertAnimationNode().

1182 {
1183  AnimationNode* child = new AnimationNode(bone, trans);
1184  InsertAnimationNode(child, slot, sibling, weight, stop_previous_animation);
1185  return child;
1186 }
void InsertAnimationNode(AnimationNode *node, int slot, AnimationNode *sibling, ValueProvider *weight, bool stop_previous_animation)
Definition: StdMesh.cpp:1740
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399

Here is the call graph for this function:

void StdMeshInstance::ReorderFaces ( StdMeshMatrix *  global_trans)

Definition at line 1550 of file StdMesh.cpp.

References StdSubMeshInstance::CurrentFaceOrdering, StdSubMeshInstance::Faces, StdSubMeshInstance::FO_Fixed, StdSubMesh::GetNumVertices(), GetSharedVertices(), StdSubMeshInstance::GetSubMesh(), StdSubMesh::GetVertices(), SubMeshInstances, and UpdateIBO().

Referenced by C4Draw::RenderMesh().

1551 {
1552 #ifndef USE_CONSOLE
1553  for (auto & SubMeshInstance : SubMeshInstances)
1554  {
1555  StdSubMeshInstance& inst = *SubMeshInstance;
1556  assert((inst.Faces.size() > 0) && "StdMeshInstance sub-mesh instance has zero faces");
1557 
1558  if(inst.Faces.size() > 0 && inst.CurrentFaceOrdering != StdSubMeshInstance::FO_Fixed)
1559  {
1560  const StdMeshVertex* vertices;
1561  if(inst.GetSubMesh().GetNumVertices() > 0)
1562  vertices = &inst.GetSubMesh().GetVertices()[0];
1563  else
1564  vertices = &GetSharedVertices()[0];
1565  SortFacesArray(vertices, inst.Faces, inst.CurrentFaceOrdering, global_trans ? *global_trans : StdMeshMatrix::Identity());
1566  }
1567  }
1568 
1569  // TODO: Also reorder submeshes, attached meshes and include AttachTransformation for attached meshes...
1570 
1571  // Faces have been reordered: upload new order to GPU
1572  UpdateIBO();
1573 #endif
1574 }
FaceOrdering CurrentFaceOrdering
Definition: StdMesh.h:301
const StdSubMesh & GetSubMesh() const
Definition: StdMesh.h:265
const std::vector< StdMeshVertex > & GetSharedVertices() const
Definition: StdMesh.h:549
size_t GetNumVertices() const
Definition: StdMesh.h:165
const std::vector< Vertex > & GetVertices() const
Definition: StdMesh.h:163
std::vector< StdMeshFace > Faces
Definition: StdMesh.h:280
void UpdateIBO()
Definition: StdMesh.cpp:1910
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

template<typename IteratorType , typename FuncObj >
bool StdMeshInstance::ScanAttachTree ( IteratorType  begin,
IteratorType  end,
const FuncObj &  obj 
)
staticprotected

Definition at line 1700 of file StdMesh.cpp.

Referenced by AttachMesh(), DetachMesh(), and GetAttachedMeshByNumber().

1701 {
1702  for (IteratorType iter = begin; iter != end; ++iter)
1703  {
1704  if (!obj(iter)) return false;
1705 
1706  // Scan attached tree of own children. For non-owned children,
1707  // we can't guarantee unique attach numbers.
1708  if( (*iter)->OwnChild)
1709  if (!ScanAttachTree((*iter)->Child->AttachChildren.begin(), (*iter)->Child->AttachChildren.end(), obj))
1710  return false;
1711  }
1712 
1713  return true;
1714 }
static bool ScanAttachTree(IteratorType begin, IteratorType end, const FuncObj &obj)
Definition: StdMesh.cpp:1700

Here is the caller graph for this function:

void StdMeshInstance::SetAnimationBoneTransform ( AnimationNode node,
const StdMeshTransformation &  trans 
)

Definition at line 1269 of file StdMesh.cpp.

References StdMeshInstanceAnimationNode::CustomNode, StdMeshInstanceAnimationNode::GetType(), and SetBoneTransformsDirty().

1270 {
1271  assert(node->GetType() == AnimationNode::CustomNode);
1272  *node->Custom.Transformation = trans;
1273  SetBoneTransformsDirty(true);
1274 }
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891

Here is the call graph for this function:

void StdMeshInstance::SetAnimationPosition ( AnimationNode node,
ValueProvider position 
)

Definition at line 1258 of file StdMesh.cpp.

References Clamp(), Fix0, ftofix(), StdMeshInstanceAnimationNode::GetType(), StdMeshInstanceAnimationNode::LeafNode, SetBoneTransformsDirty(), and StdMeshInstanceValueProvider::Value.

1259 {
1260  assert(node->GetType() == AnimationNode::LeafNode);
1261  delete node->Leaf.Position;
1262  node->Leaf.Position = position;
1263 
1264  position->Value = Clamp(position->Value, Fix0, ftofix(node->Leaf.Animation->Length));
1265 
1266  SetBoneTransformsDirty(true);
1267 }
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
C4Fixed ftofix(float x)
Definition: C4Real.h:258
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

void StdMeshInstance::SetAnimationWeight ( AnimationNode node,
ValueProvider weight 
)

Definition at line 1276 of file StdMesh.cpp.

References Clamp(), Fix0, StdMeshInstanceAnimationNode::GetType(), itofix(), StdMeshInstanceAnimationNode::LinearInterpolationNode, SetBoneTransformsDirty(), and StdMeshInstanceValueProvider::Value.

1277 {
1278  assert(node->GetType() == AnimationNode::LinearInterpolationNode);
1279  delete node->LinearInterpolation.Weight; node->LinearInterpolation.Weight = weight;
1280 
1281  weight->Value = Clamp(weight->Value, Fix0, itofix(1));
1282 
1283  SetBoneTransformsDirty(true);
1284 }
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

void StdMeshInstance::SetBoneTransformsDirty ( bool  value)
protected

Definition at line 1891 of file StdMesh.cpp.

References AM_MatchSkeleton, AttachChildren, and BoneTransformsDirty.

Referenced by CompileFunc(), ExecuteAnimationNode(), InsertAnimationNode(), SetAnimationBoneTransform(), SetAnimationPosition(), SetAnimationWeight(), StopAnimation(), and UpdateBoneTransforms().

1892 {
1893  BoneTransformsDirty = value;
1894 
1895  // only if the value is true, so that updates happen
1896  if (value)
1897  {
1898  // Update attachment's attach transformations. Note this is done recursively.
1899  for (auto attach : AttachChildren)
1900  {
1901  if (attach->GetFlags() & AM_MatchSkeleton)
1902  {
1903  attach->Child->SetBoneTransformsDirty(value);
1904  }
1905  }
1906  }
1907 }
bool BoneTransformsDirty
Definition: StdMesh.h:663
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660

Here is the caller graph for this function:

void StdMeshInstance::SetCompletion ( float  completion)

Definition at line 1150 of file StdMesh.cpp.

References Completion, StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), SubMeshInstances, and UpdateIBO().

Referenced by C4Object::DoCon().

1151 {
1152  Completion = completion;
1153 
1154 #ifndef USE_CONSOLE
1155  // TODO: Load all submesh faces and then determine the ones to use from the
1156  // full pool.
1157  for(unsigned int i = 0; i < Mesh->GetNumSubMeshes(); ++i)
1158  SubMeshInstances[i]->LoadFacesForCompletion(*this, Mesh->GetSubMesh(i), completion);
1159 
1160  // Faces have been reordered: upload new order to GPU
1161  UpdateIBO();
1162 #endif
1163 }
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
const StdMesh * Mesh
Definition: StdMesh.h:647
float Completion
Definition: StdMesh.h:649
void UpdateIBO()
Definition: StdMesh.cpp:1910
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::SetFaceOrdering ( FaceOrdering  ordering)

Definition at line 1116 of file StdMesh.cpp.

References AttachChildren, StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), SubMeshInstances, and UpdateIBO().

Referenced by C4EditCursor::DrawObject().

1117 {
1118 #ifndef USE_CONSOLE
1119  for (unsigned int i = 0; i < Mesh->GetNumSubMeshes(); ++i)
1120  SubMeshInstances[i]->SetFaceOrdering(*this, Mesh->GetSubMesh(i), ordering);
1121 
1122  // Faces have been reordered: upload new order to GPU
1123  UpdateIBO();
1124 
1125  // Update attachments (only own meshes for now... others might be displayed both attached and non-attached...)
1126  // still not optimal.
1127  for (AttachedMeshIter iter = AttachChildren.begin(); iter != AttachChildren.end(); ++iter)
1128  if ((*iter)->OwnChild)
1129  (*iter)->Child->SetFaceOrdering(ordering);
1130 #endif
1131 }
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
const StdMesh * Mesh
Definition: StdMesh.h:647
AttachedMeshList::const_iterator AttachedMeshIter
Definition: StdMesh.h:544
void SetFaceOrdering(FaceOrdering ordering)
Definition: StdMesh.cpp:1116
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
void UpdateIBO()
Definition: StdMesh.cpp:1910
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::SetFaceOrderingForClrModulation ( uint32_t  clrmod)

Definition at line 1133 of file StdMesh.cpp.

References AttachChildren, StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), SubMeshInstances, and UpdateIBO().

Referenced by C4Object::CompileFunc(), C4GraphicsOverlay::Draw(), C4EditCursor::DrawObject(), C4GraphicsOverlay::DrawPicture(), C4Object::Init(), and C4Object::UpdateGraphics().

1134 {
1135 #ifndef USE_CONSOLE
1136  for (unsigned int i = 0; i < Mesh->GetNumSubMeshes(); ++i)
1138 
1139  // Faces have been reordered: upload new order to GPU
1140  UpdateIBO();
1141 
1142  // Update attachments (only own meshes for now... others might be displayed both attached and non-attached...)
1143  // still not optimal.
1144  for (AttachedMeshIter iter = AttachChildren.begin(); iter != AttachChildren.end(); ++iter)
1145  if ((*iter)->OwnChild)
1146  (*iter)->Child->SetFaceOrderingForClrModulation(clrmod);
1147 #endif
1148 }
void SetFaceOrderingForClrModulation(uint32_t clrmod)
Definition: StdMesh.cpp:1133
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
const StdMesh * Mesh
Definition: StdMesh.h:647
AttachedMeshList::const_iterator AttachedMeshIter
Definition: StdMesh.h:544
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
void UpdateIBO()
Definition: StdMesh.cpp:1910
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::SetMaterial ( size_t  i,
const StdMeshMaterial material 
)

Definition at line 1435 of file StdMesh.cpp.

References SubMeshInstances, and SubMeshInstancesOrdered.

1436 {
1437  assert(i < SubMeshInstances.size());
1438  SubMeshInstances[i]->SetMaterial(material);
1439 #ifndef USE_CONSOLE
1440  std::stable_sort(SubMeshInstancesOrdered.begin(), SubMeshInstancesOrdered.end(), StdMeshSubMeshInstanceVisibilityCmpPred());
1441 #endif
1442 }
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
Definition: StdMesh.h:656
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
void StdMeshInstance::StopAnimation ( AnimationNode node)

Definition at line 1188 of file StdMesh.cpp.

References AnimationNodes, AnimationStack, GetStackIterForSlot(), StdMeshInstanceAnimationNode::LinearInterpolationNode, StdMeshInstanceAnimationNode::Number, StdMeshInstanceAnimationNode::Parent, SetBoneTransformsDirty(), StdMeshInstanceAnimationNode::Slot, and StdMeshInstanceAnimationNode::Type.

Referenced by ExecuteAnimation(), ExecuteAnimationNode(), InsertAnimationNode(), C4Object::SetAction(), StdMeshUpdate::Update(), StdMeshAnimationUpdate::Update(), and ~StdMeshInstance().

1189 {
1190  ClearAnimationListRecursively(AnimationNodes, node);
1191 
1192  AnimationNode* parent = node->Parent;
1193  if (parent == nullptr)
1194  {
1195  AnimationNodeList::iterator iter = GetStackIterForSlot(node->Slot, false);
1196  assert(iter != AnimationStack.end() && *iter == node);
1197  AnimationStack.erase(iter);
1198  delete node;
1199  }
1200  else
1201  {
1202  assert(parent->Type == AnimationNode::LinearInterpolationNode);
1203 
1204  // Remove parent interpolation node and re-link
1205  AnimationNode* other_child;
1206  if (parent->LinearInterpolation.ChildLeft == node)
1207  {
1208  other_child = parent->LinearInterpolation.ChildRight;
1209  parent->LinearInterpolation.ChildRight = nullptr;
1210  }
1211  else
1212  {
1213  other_child = parent->LinearInterpolation.ChildLeft;
1214  parent->LinearInterpolation.ChildLeft = nullptr;
1215  }
1216 
1217  if (parent->Parent)
1218  {
1219  assert(parent->Parent->Type == AnimationNode::LinearInterpolationNode);
1220  if (parent->Parent->LinearInterpolation.ChildLeft == parent)
1221  parent->Parent->LinearInterpolation.ChildLeft = other_child;
1222  else
1223  parent->Parent->LinearInterpolation.ChildRight = other_child;
1224  other_child->Parent = parent->Parent;
1225  }
1226  else
1227  {
1228  AnimationNodeList::iterator iter = GetStackIterForSlot(node->Slot, false);
1229  assert(iter != AnimationStack.end() && *iter == parent);
1230  *iter = other_child;
1231 
1232  other_child->Parent = nullptr;
1233  }
1234 
1235  AnimationNodes[parent->Number] = nullptr;
1236  // Recursively deletes parent and its descendants
1237  delete parent;
1238  }
1239 
1240  while (!AnimationNodes.empty() && AnimationNodes.back() == nullptr)
1241  AnimationNodes.erase(AnimationNodes.end()-1);
1242  SetBoneTransformsDirty(true);
1243 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
AnimationNode * Parent
Definition: StdMesh.h:367
StdMeshInstanceAnimationNode AnimationNode
Definition: StdMesh.h:399
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create)
Definition: StdMesh.cpp:1716

Here is the call graph for this function:

Here is the caller graph for this function:

bool StdMeshInstance::UpdateBoneTransforms ( )

Definition at line 1469 of file StdMesh.cpp.

References AnimationStack, AttachChildren, BoneTransforms, BoneTransformsDirty, StdMeshSkeleton::GetBone(), GetBoneTransform(), StdMeshBone::GetParent(), StdMesh::GetSkeleton(), StdMeshBone::Index, StdMeshBone::InverseTransformation, SetBoneTransformsDirty(), and StdMeshBone::Transformation.

Referenced by C4Draw::RenderMesh().

1470 {
1471  bool was_dirty = BoneTransformsDirty;
1472 
1473  // Nothing changed since last time
1474  if (BoneTransformsDirty)
1475  {
1476  // Compute transformation matrix for each bone.
1477  for (unsigned int i = 0; i < BoneTransforms.size(); ++i)
1478  {
1479  StdMeshTransformation Transformation;
1480 
1481  const StdMeshBone& bone = Mesh->GetSkeleton().GetBone(i);
1482  const StdMeshBone* parent = bone.GetParent();
1483  assert(!parent || parent->Index < i);
1484 
1485  bool have_transform = false;
1486  for (auto & j : AnimationStack)
1487  {
1488  if (have_transform)
1489  {
1490  StdMeshTransformation other;
1491  if (j->GetBoneTransform(i, other))
1492  Transformation = StdMeshTransformation::Nlerp(Transformation, other, 1.0f); // TODO: Allow custom weighing for slot combination
1493  }
1494  else
1495  {
1496  have_transform = j->GetBoneTransform(i, Transformation);
1497  }
1498  }
1499 
1500  if (!have_transform)
1501  {
1502  if (parent)
1503  BoneTransforms[i] = BoneTransforms[parent->Index];
1504  else
1505  BoneTransforms[i] = StdMeshMatrix::Identity();
1506  }
1507  else
1508  {
1509  BoneTransforms[i] = StdMeshMatrix::Transform(bone.Transformation * Transformation * bone.InverseTransformation);
1510  if (parent) BoneTransforms[i] = BoneTransforms[parent->Index] * BoneTransforms[i];
1511  }
1512  }
1513  }
1514 
1515  // Update attachment's attach transformations. Note this is done recursively.
1516  for (auto attach : AttachChildren)
1517  {
1518  const bool ChildBoneTransformsDirty = attach->Child->BoneTransformsDirty;
1519  attach->Child->UpdateBoneTransforms();
1520 
1521  if (BoneTransformsDirty || ChildBoneTransformsDirty || attach->FinalTransformDirty)
1522  {
1523  was_dirty = true;
1524 
1525  // Compute matrix to change the coordinate system to the one of the attached bone:
1526  // The idea is that a vertex at the child bone's position transforms to the parent bone's position.
1527  // Therefore (read from right to left) we first apply the inverse of the child bone transformation,
1528  // then an optional scaling matrix, and finally the parent bone transformation
1529 
1530  // TODO: we can cache the three matrices in the middle since they don't change over time,
1531  // reducing this to two matrix multiplications instead of four each frame.
1532  // Might even be worth to compute the complete transformation directly when rendering then
1533  // (saves per-instance memory, but requires recomputation if the animation does not change).
1534  // TODO: We might also be able to cache child inverse, and only recomupte it if
1535  // child bone transforms are dirty (saves matrix inversion for unanimated attach children).
1536  attach->FinalTrans = GetBoneTransform(attach->ParentBone)
1537  * StdMeshMatrix::Transform(Mesh->GetSkeleton().GetBone(attach->ParentBone).Transformation)
1538  * attach->AttachTrans
1539  * StdMeshMatrix::Transform(attach->Child->Mesh->GetSkeleton().GetBone(attach->ChildBone).InverseTransformation)
1540  * StdMeshMatrix::Inverse(attach->Child->GetBoneTransform(attach->ChildBone));
1541 
1542  attach->FinalTransformDirty = false;
1543  }
1544  }
1545 
1546  SetBoneTransformsDirty(false);
1547  return was_dirty;
1548 }
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
bool BoneTransformsDirty
Definition: StdMesh.h:663
StdMeshTransformation Transformation
Definition: StdMesh.h:37
const StdMeshSkeleton & GetSkeleton() const
Definition: StdMesh.h:203
const StdMeshMatrix & GetBoneTransform(size_t i) const
Definition: StdMesh.cpp:1444
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:116
const StdMesh * Mesh
Definition: StdMesh.h:647
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
StdMeshTransformation InverseTransformation
Definition: StdMesh.h:39
unsigned int Index
Definition: StdMesh.h:32
std::vector< StdMeshMatrix > BoneTransforms
Definition: StdMesh.h:653
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
const StdMeshBone * GetParent() const
Definition: StdMesh.h:41

Here is the call graph for this function:

Here is the caller graph for this function:

void StdMeshInstance::UpdateIBO ( )
protected

Definition at line 1910 of file StdMesh.cpp.

References StdSubMeshInstance::FO_Fixed, CStdGL::FreeVAOID(), CStdGL::GenVAOID(), StdSubMesh::GetNumFaces(), StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), ibo, pGL, SubMeshInstances, and vaoid.

Referenced by ReorderFaces(), SetCompletion(), SetFaceOrdering(), and SetFaceOrderingForClrModulation().

1911 {
1912  // First, find out whether we have fixed face ordering or not
1913  bool all_submeshes_fixed = true;
1914  for (StdSubMeshInstance* inst : SubMeshInstances)
1915  {
1916  all_submeshes_fixed = (inst->GetFaceOrdering() == StdSubMeshInstance::FO_Fixed);
1917  if (!all_submeshes_fixed) break;
1918 
1919  // If true, submesh is 100% complete
1920  all_submeshes_fixed = inst->GetNumFaces() == inst->GetSubMesh().GetNumFaces();
1921  if (!all_submeshes_fixed) break;
1922  }
1923 
1924  // If the face ordering is fixed, then we don't need a custom
1925  // IBO. This is typically the case for all meshes without transparency
1926  // and 100% completion.
1927  if (all_submeshes_fixed)
1928  {
1929  if (ibo) glDeleteBuffers(1, &ibo);
1930  if (vaoid) pGL->FreeVAOID(vaoid);
1931  ibo = 0; vaoid = 0;
1932  }
1933  else
1934  {
1935  // We have a custom face ordering, or we render only a subset
1936  // of our faces. Create a custom IBO and upload the index
1937  // data.
1938  if (ibo == 0)
1939  {
1940  // This is required, because the IBO binding is part
1941  // of the VAO state. If we create a new IBO we cannot
1942  // keep using any old VAO. But we always create and
1943  // destroy them together, so we can assert here.
1944  assert(vaoid == 0);
1945 
1946  size_t total_faces = 0;
1947  for (unsigned int i = 0; i < Mesh->GetNumSubMeshes(); ++i)
1948  total_faces += Mesh->GetSubMesh(i).GetNumFaces();
1949 
1950  glGenBuffers(1, &ibo);
1951  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
1952 
1953  // TODO: Optimize mode. In many cases this is still fairly static.
1954  glBufferData(GL_ELEMENT_ARRAY_BUFFER, total_faces * 3 * sizeof(GLuint), nullptr, GL_STREAM_DRAW);
1955  }
1956  else
1957  {
1958  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
1959  }
1960 
1961  for (StdSubMeshInstance* inst : SubMeshInstances)
1962  {
1963  assert(inst->GetNumFaces() <= inst->GetSubMesh().GetNumFaces());
1964  glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, inst->GetSubMesh().GetOffsetInIBO(), inst->GetNumFaces() * 3 * sizeof(GLuint), &inst->Faces[0]);
1965  }
1966 
1967  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1968 
1969  if (vaoid == 0)
1970  vaoid = pGL->GenVAOID();
1971  }
1972 }
unsigned int vaoid
Definition: StdMesh.h:671
GLuint ibo
Definition: StdMesh.h:670
size_t GetNumFaces() const
Definition: StdMesh.h:168
void FreeVAOID(unsigned int vaoid)
Definition: C4DrawGL.cpp:967
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
const StdMesh * Mesh
Definition: StdMesh.h:647
unsigned int GenVAOID()
Definition: C4DrawGL.cpp:925
CStdGL * pGL
Definition: C4DrawGL.cpp:905
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655

Here is the call graph for this function:

Here is the caller graph for this function:

Friends And Related Function Documentation

friend class StdMeshAnimationUpdate
friend

Definition at line 396 of file StdMesh.h.

friend class StdMeshMaterialUpdate
friend

Definition at line 395 of file StdMesh.h.

friend class StdMeshUpdate
friend

Definition at line 397 of file StdMesh.h.

Member Data Documentation

AnimationNodeList StdMeshInstance::AnimationNodes
protected
AttachedMesh* StdMeshInstance::AttachParent
protected
std::vector<StdMeshMatrix> StdMeshInstance::BoneTransforms
protected
bool StdMeshInstance::BoneTransformsDirty
protected

Definition at line 663 of file StdMesh.h.

Referenced by SetBoneTransformsDirty(), StdMeshUpdate::Update(), and UpdateBoneTransforms().

float StdMeshInstance::Completion
protected

Definition at line 649 of file StdMesh.h.

Referenced by SetCompletion().

GLuint StdMeshInstance::ibo
protected

Definition at line 670 of file StdMesh.h.

Referenced by UpdateIBO(), and ~StdMeshInstance().

const StdMesh* StdMeshInstance::Mesh
protected

Definition at line 647 of file StdMesh.h.

Referenced by AttachMeshImpl(), and StdMeshUpdate::Update().

std::vector<StdSubMeshInstance*> StdMeshInstance::SubMeshInstancesOrdered
protected

Definition at line 656 of file StdMesh.h.

Referenced by CompileFunc(), SetMaterial(), StdMeshInstance(), and StdMeshUpdate::Update().

unsigned int StdMeshInstance::vaoid
protected

Definition at line 671 of file StdMesh.h.

Referenced by UpdateIBO(), and ~StdMeshInstance().


The documentation for this class was generated from the following files: