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:1697

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 1681 of file StdMesh.cpp.

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

Referenced by C4Object::ClearPointers().

1682 {
1683  for(auto & AnimationNode : AnimationNodes)
1684  if(AnimationNode)
1686 
1687  std::vector<unsigned int> Removal;
1688  for(auto & i : AttachChildren)
1689  if(!i->ClearPointers(pObj))
1690  Removal.push_back(i->Number);
1691 
1692  for(unsigned int i : Removal)
1693  DetachMesh(i);
1694 }
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  std::stable_sort(SubMeshInstancesOrdered.begin(), SubMeshInstancesOrdered.end(), StdMeshSubMeshInstanceVisibilityCmpPred());
1597 
1598  int32_t iAnimCnt = AnimationStack.size();
1599  pComp->Value(mkNamingCountAdapt(iAnimCnt, "AnimationNode"));
1600 
1601  for(int32_t i = 0; i < iAnimCnt; ++i)
1602  {
1603  AnimationNode* node = nullptr;
1604  pComp->Value(mkParAdapt(mkNamingPtrAdapt(node, "AnimationNode"), Mesh));
1605  AnimationNodeList::iterator iter = GetStackIterForSlot(node->Slot, true);
1606  if(*iter != nullptr) { delete node; pComp->excCorrupt("Duplicate animation slot index"); }
1607  *iter = node;
1608 
1609  // Add nodes into lookup table
1610  std::vector<AnimationNode*> nodes(1, node);
1611  while(!nodes.empty())
1612  {
1613  node = nodes.back();
1614  nodes.erase(nodes.end()-1);
1615 
1616  if (AnimationNodes.size() <= node->Number)
1617  AnimationNodes.resize(node->Number+1);
1618  if(AnimationNodes[node->Number] != nullptr) pComp->excCorrupt("Duplicate animation node number");
1619  AnimationNodes[node->Number] = node;
1620 
1621  if(node->Type == AnimationNode::LinearInterpolationNode)
1622  {
1623  nodes.push_back(node->LinearInterpolation.ChildLeft);
1624  nodes.push_back(node->LinearInterpolation.ChildRight);
1625  }
1626  }
1627  }
1628 
1629  int32_t iAttachedCnt;
1630  pComp->Value(mkNamingCountAdapt(iAttachedCnt, "Attached"));
1631 
1632  for(int32_t i = 0; i < iAttachedCnt; ++i)
1633  {
1634  AttachChildren.push_back(new AttachedMesh);
1635  AttachedMesh* attach = AttachChildren.back();
1636 
1637  attach->Parent = this;
1638  pComp->Value(mkNamingAdapt(mkParAdapt(*attach, Factory), "Attached"));
1639  }
1640  }
1641  else
1642  {
1643  // Write something to make sure that the parent
1644  // named section ([Mesh] or [ChildInstance]) is written.
1645  // StdCompilerIni does not make a difference between
1646  // non-existing and empty named sections.
1647  bool valid = true;
1648  pComp->Value(mkNamingAdapt(valid, "Valid"));
1649 
1650  int32_t iSubMeshCnt = SubMeshInstances.size();
1651  pComp->Value(mkNamingCountAdapt(iSubMeshCnt, "SubMesh"));
1652  for(int32_t i = 0; i < iSubMeshCnt; ++i)
1653  pComp->Value(mkNamingAdapt(*SubMeshInstances[i], "SubMesh"));
1654 
1655  int32_t iAnimCnt = AnimationStack.size();
1656  pComp->Value(mkNamingCountAdapt(iAnimCnt, "AnimationNode"));
1657 
1658  for(auto & iter : AnimationStack)
1659  pComp->Value(mkParAdapt(mkNamingPtrAdapt(iter, "AnimationNode"), Mesh));
1660 
1661  int32_t iAttachedCnt = AttachChildren.size();
1662  pComp->Value(mkNamingCountAdapt(iAttachedCnt, "Attached"));
1663 
1664  for(auto & i : AttachChildren)
1665  pComp->Value(mkNamingAdapt(mkParAdapt(*i, Factory), "Attached"));
1666  }
1667 }
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:1888
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:1713
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 1669 of file StdMesh.cpp.

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

Referenced by C4Object::Denumerate().

1670 {
1671  for(auto & AnimationNode : AnimationNodes)
1672  if(AnimationNode)
1674 
1675  for(auto & i : AttachChildren)
1676  {
1677  i->DenumeratePointers();
1678  }
1679 }
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:1697

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:1811
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 1811 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().

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

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:1713

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 1713 of file StdMesh.cpp.

References AnimationStack.

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

1714 {
1715  // TODO: bsearch
1716  for (AnimationNodeList::iterator iter = AnimationStack.begin(); iter != AnimationStack.end(); ++iter)
1717  {
1718  if ((*iter)->Slot == slot)
1719  {
1720  return iter;
1721  }
1722  else if ((*iter)->Slot > slot)
1723  {
1724  if (!create)
1725  return AnimationStack.end();
1726  else
1727  return AnimationStack.insert(iter, nullptr);
1728  }
1729  }
1730 
1731  if (!create)
1732  return AnimationStack.end();
1733  else
1734  return AnimationStack.insert(AnimationStack.end(), nullptr);
1735 }
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 1737 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().

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

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

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

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:1888

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:1888
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:1888
const C4Real Fix0
Definition: C4Real.h:312

Here is the call graph for this function:

void StdMeshInstance::SetBoneTransformsDirty ( bool  value)
protected

Definition at line 1888 of file StdMesh.cpp.

References AM_MatchSkeleton, AttachChildren, and BoneTransformsDirty.

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

1889 {
1890  BoneTransformsDirty = value;
1891 
1892  // only if the value is true, so that updates happen
1893  if (value)
1894  {
1895  // Update attachment's attach transformations. Note this is done recursively.
1896  for (auto attach : AttachChildren)
1897  {
1898  if (attach->GetFlags() & AM_MatchSkeleton)
1899  {
1900  attach->Child->SetBoneTransformsDirty(value);
1901  }
1902  }
1903  }
1904 }
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:1907
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:1907
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:1907
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:1888
AnimationNodeList AnimationNodes
Definition: StdMesh.h:651
AnimationNodeList::iterator GetStackIterForSlot(int slot, bool create)
Definition: StdMesh.cpp:1713

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:1888
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 1907 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().

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