OpenClonk
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 StdMeshMatrixGetBoneTransform (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< StdMeshMatrixBoneTransforms
 
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

◆ AnimationNode

◆ AnimationNodeList

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

Definition at line 639 of file StdMesh.h.

◆ AttachedMeshIter

typedef AttachedMeshList::const_iterator StdMeshInstance::AttachedMeshIter

Definition at line 544 of file StdMesh.h.

◆ AttachedMeshList

Definition at line 543 of file StdMesh.h.

◆ FaceOrdering

◆ ValueProvider

Member Enumeration Documentation

◆ AttachMeshFlags

Enumerator
AM_None 
AM_DrawBefore 
AM_MatchSkeleton 

Definition at line 405 of file StdMesh.h.

Constructor & Destructor Documentation

◆ StdMeshInstance()

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

Definition at line 1070 of file StdMesh.cpp.

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

Referenced by AttachMesh().

1070  :
1071  Mesh(&mesh), Completion(completion),
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 }
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
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
static StdMeshMatrix Identity()
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 GetNumSubMeshes() const
Definition: StdMesh.h:199
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::~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:980
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:918
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

◆ ApplyBoneTransformToVertices()

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

◆ AttachedMeshesBegin()

AttachedMeshIter StdMeshInstance::AttachedMeshesBegin ( ) const
inline

Definition at line 584 of file StdMesh.h.

Referenced by C4DefGraphicsPtrBackupEntry::AssignRemoval(), C4DefGraphicsPtrBackup::AssignUpdate(), and StdMeshUpdate::Update().

584 { return AttachChildren.begin(); }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
Here is the caller graph for this function:

◆ AttachedMeshesEnd()

AttachedMeshIter StdMeshInstance::AttachedMeshesEnd ( ) const
inline

Definition at line 585 of file StdMesh.h.

Referenced by C4DefGraphicsPtrBackupEntry::AssignRemoval(), C4DefGraphicsPtrBackup::AssignUpdate(), and StdMeshUpdate::Update().

585 { return AttachChildren.end(); }
std::vector< AttachedMesh * > AttachChildren
Definition: StdMesh.h:660
Here is the caller graph for this function:

◆ AttachMesh() [1/2]

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:

◆ AttachMesh() [2/2]

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:

◆ AttachMeshImpl()

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 StdMeshBone * GetBoneByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:386
const StdMesh * Mesh
Definition: StdMesh.h:647
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:

◆ ClearPointers()

void StdMeshInstance::ClearPointers ( class C4Object pObj)

Definition at line 1684 of file StdMesh.cpp.

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

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:

◆ CompileFunc()

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, Mesh, 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:994
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:476
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:622
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
Here is the call graph for this function:

◆ DenumeratePointers()

void StdMeshInstance::DenumeratePointers ( )

Definition at line 1672 of file StdMesh.cpp.

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

Referenced by StdMeshInstance::AttachedMesh::DenumeratePointers().

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:

◆ DetachMesh()

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 C4DefGraphicsPtrBackupEntry::AssignRemoval(), 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:

◆ ExecuteAnimation()

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.

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
void StopAnimation(AnimationNode *node)
Definition: StdMesh.cpp:1188
std::vector< Pass > PassData
Definition: StdMesh.h:300
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:

◆ ExecuteAnimationNode()

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:

◆ GetAnimationNodeByNumber()

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

◆ GetAttachedMeshByNumber()

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:

◆ GetAttachParent()

AttachedMesh* StdMeshInstance::GetAttachParent ( ) const
inline

Definition at line 586 of file StdMesh.h.

Referenced by C4DefGraphicsPtrBackupEntry::AssignRemoval().

586 { return AttachParent; }
AttachedMesh * AttachParent
Definition: StdMesh.h:661
Here is the caller graph for this function:

◆ GetBoneCount()

size_t StdMeshInstance::GetBoneCount ( ) const

Definition at line 1461 of file StdMesh.cpp.

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

Referenced by CStdGL::PrepareMaterial().

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:
Here is the caller graph for this function:

◆ GetBoneTransform()

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 CStdGL::PrepareMaterial(), and 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:

◆ GetCompletion()

float StdMeshInstance::GetCompletion ( ) const
inline

Definition at line 554 of file StdMesh.h.

References StdMeshMatrix::Identity().

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

554 { return Completion; }
float Completion
Definition: StdMesh.h:649
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetIBO()

GLuint StdMeshInstance::GetIBO ( ) const
inline

Definition at line 625 of file StdMesh.h.

Referenced by CStdGL::PrepareMaterial().

625 { return ibo ? ibo : Mesh->GetIBO(); }
GLuint ibo
Definition: StdMesh.h:670
const StdMesh * Mesh
Definition: StdMesh.h:647
GLuint GetIBO() const
Definition: StdMesh.h:213
Here is the caller graph for this function:

◆ GetMesh()

const StdMesh& StdMeshInstance::GetMesh ( ) const
inline

Definition at line 622 of file StdMesh.h.

Referenced by C4DefGraphicsPtrBackupEntry::AssignRemoval(), StdMeshInstance::AttachedMesh::AttachedMesh(), StdMeshInstance::AttachedMesh::DenumeratePointers(), CStdGL::PerformMesh(), CStdGL::PrepareMaterial(), StdMeshInstance::AttachedMesh::SetChildBone(), StdMeshInstance::AttachedMesh::SetParentBone(), StdMeshMaterialUpdate::Update(), and StdMeshUpdate::Update().

622 { return *Mesh; }
const StdMesh * Mesh
Definition: StdMesh.h:647
Here is the caller graph for this function:

◆ GetNumSharedVertices()

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

◆ GetNumSubMeshes()

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

◆ GetRootAnimationForSlot()

StdMeshInstance::AnimationNode * StdMeshInstance::GetRootAnimationForSlot ( int  slot)

Definition at line 1251 of file StdMesh.cpp.

References AnimationStack, and GetStackIterForSlot().

Referenced by 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:

◆ GetSharedVertices()

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

Definition at line 549 of file StdMesh.h.

Referenced by StdSubMeshInstance::LoadFacesForCompletion(), CStdGL::PrepareMaterial(), 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:

◆ GetStackIterForSlot()

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:

◆ GetSubMesh() [1/2]

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

◆ GetSubMesh() [2/2]

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

◆ GetSubMeshOrdered()

const StdSubMeshInstance& StdMeshInstance::GetSubMeshOrdered ( size_t  i) const
inline

Definition at line 591 of file StdMesh.h.

References CompileFunc().

591 { return *SubMeshInstancesOrdered[i]; }
std::vector< StdSubMeshInstance * > SubMeshInstancesOrdered
Definition: StdMesh.h:656
Here is the call graph for this function:

◆ GetVAOID()

unsigned int StdMeshInstance::GetVAOID ( ) const
inline

Definition at line 626 of file StdMesh.h.

Referenced by CStdGL::PrepareMaterial().

626 { return vaoid ? vaoid : Mesh->GetVAOID(); }
unsigned int vaoid
Definition: StdMesh.h:671
unsigned int GetVAOID() const
Definition: StdMesh.h:214
const StdMesh * Mesh
Definition: StdMesh.h:647
Here is the caller graph for this function:

◆ InsertAnimationNode()

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:

◆ PlayAnimation() [1/3]

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(), StdMesh::GetSkeleton(), and Mesh.

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 StdMesh * Mesh
Definition: StdMesh.h:647
const StdMeshAnimation * GetAnimationByName(const StdStrBuf &name) const
Definition: StdMesh.cpp:396
Here is the call graph for this function:

◆ PlayAnimation() [2/3]

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:

◆ PlayAnimation() [3/3]

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:

◆ ReorderFaces()

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(), StdMeshMatrix::Identity(), 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
size_t GetNumVertices() const
Definition: StdMesh.h:165
const std::vector< Vertex > & GetVertices() const
Definition: StdMesh.h:163
static StdMeshMatrix Identity()
const std::vector< StdMeshVertex > & GetSharedVertices() const
Definition: StdMesh.h:549
const StdSubMesh & GetSubMesh() const
Definition: StdMesh.h:265
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:

◆ ScanAttachTree()

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:

◆ SetAnimationBoneTransform()

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:

◆ SetAnimationPosition()

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:

◆ SetAnimationWeight()

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:

◆ SetBoneTransformsDirty()

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:

◆ SetCompletion()

void StdMeshInstance::SetCompletion ( float  completion)

Definition at line 1150 of file StdMesh.cpp.

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

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 }
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
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
Here is the call graph for this function:

◆ SetFaceOrdering()

void StdMeshInstance::SetFaceOrdering ( FaceOrdering  ordering)

Definition at line 1116 of file StdMesh.cpp.

References AttachChildren, StdMesh::GetNumSubMeshes(), StdMesh::GetSubMesh(), Mesh, 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 }
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
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetFaceOrderingForClrModulation()

void StdMeshInstance::SetFaceOrderingForClrModulation ( uint32_t  clrmod)

Definition at line 1133 of file StdMesh.cpp.

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

Referenced by C4EditCursor::DrawObject().

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 }
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
void SetFaceOrderingForClrModulation(uint32_t clrmod)
Definition: StdMesh.cpp:1133
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
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
std::vector< StdSubMeshInstance * > SubMeshInstances
Definition: StdMesh.h:655
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetMaterial()

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

◆ StopAnimation()

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(), 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:

◆ UpdateBoneTransforms()

bool StdMeshInstance::UpdateBoneTransforms ( )

Definition at line 1469 of file StdMesh.cpp.

References AnimationStack, AttachChildren, BoneTransforms, BoneTransformsDirty, StdMeshSkeleton::GetBone(), GetBoneTransform(), StdMeshBone::GetParent(), StdMesh::GetSkeleton(), StdMeshMatrix::Identity(), StdMeshBone::Index, StdMeshMatrix::Inverse(), StdMeshBone::InverseTransformation, Mesh, StdMeshTransformation::Nlerp(), SetBoneTransformsDirty(), StdMeshMatrix::Transform(), 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
1506  }
1507  else
1508  {
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)
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 }
const StdMeshBone & GetBone(size_t i) const
Definition: StdMesh.h:116
AnimationNodeList AnimationStack
Definition: StdMesh.h:652
bool BoneTransformsDirty
Definition: StdMesh.h:663
StdMeshTransformation Transformation
Definition: StdMesh.h:37
static StdMeshTransformation Nlerp(const StdMeshTransformation &lhs, const StdMeshTransformation &rhs, float w)
const StdMeshSkeleton & GetSkeleton() const
Definition: StdMesh.h:203
static StdMeshMatrix Identity()
const StdMeshMatrix & GetBoneTransform(size_t i) const
Definition: StdMesh.cpp:1444
static StdMeshMatrix Inverse(const StdMeshMatrix &mat)
const StdMesh * Mesh
Definition: StdMesh.h:647
void SetBoneTransformsDirty(bool value)
Definition: StdMesh.cpp:1891
const StdMeshBone * GetParent() const
Definition: StdMesh.h:41
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
static StdMeshMatrix Transform(const StdMeshTransformation &transform)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateIBO()

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, Mesh, 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 }
const StdSubMesh & GetSubMesh(size_t i) const
Definition: StdMesh.h:198
size_t GetNumFaces() const
Definition: StdMesh.h:168
unsigned int vaoid
Definition: StdMesh.h:671
GLuint ibo
Definition: StdMesh.h:670
void FreeVAOID(unsigned int vaoid)
Definition: C4DrawGL.cpp:980
const StdMesh * Mesh
Definition: StdMesh.h:647
unsigned int GenVAOID()
Definition: C4DrawGL.cpp:938
CStdGL * pGL
Definition: C4DrawGL.cpp:918
size_t GetNumSubMeshes() const
Definition: StdMesh.h:199
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

◆ StdMeshAnimationUpdate

friend class StdMeshAnimationUpdate
friend

Definition at line 396 of file StdMesh.h.

◆ StdMeshMaterialUpdate

friend class StdMeshMaterialUpdate
friend

Definition at line 395 of file StdMesh.h.

◆ StdMeshUpdate

friend class StdMeshUpdate
friend

Definition at line 397 of file StdMesh.h.

Member Data Documentation

◆ AnimationNodes

AnimationNodeList StdMeshInstance::AnimationNodes
protected

◆ AnimationStack

◆ AttachChildren

◆ AttachParent

◆ BoneTransforms

std::vector<StdMeshMatrix> StdMeshInstance::BoneTransforms
protected

◆ BoneTransformsDirty

bool StdMeshInstance::BoneTransformsDirty
protected

Definition at line 663 of file StdMesh.h.

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

◆ Completion

float StdMeshInstance::Completion
protected

Definition at line 649 of file StdMesh.h.

Referenced by SetCompletion().

◆ ibo

GLuint StdMeshInstance::ibo
protected

Definition at line 670 of file StdMesh.h.

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

◆ Mesh

◆ SubMeshInstances

◆ SubMeshInstancesOrdered

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

Definition at line 656 of file StdMesh.h.

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

◆ vaoid

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: