Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
Mesh.cpp
Go to the documentation of this file.
1
2
3#include "Headers/Mesh.h"
4#include "Headers/SubMesh.h"
5
15
16namespace Divide {
17
18Mesh::Mesh( const ResourceDescriptor<Mesh>& descriptor )
19 : Object3D(descriptor, GetSceneNodeType<Mesh>() )
20{
21 setBounds(_boundingBox);
22}
23
24void Mesh::addSubMesh(const Handle<SubMesh> subMesh, const U32 index)
25{
26 _subMeshList.emplace_back(MeshData{ subMesh, index });
27}
28
29void Mesh::setNodeData(const MeshNodeData& nodeStructure)
30{
31 _nodeStructure = nodeStructure;
32}
33
34void Mesh::setMaterialTpl( const Handle<Material> material)
35{
36 Object3D::setMaterialTpl(material);
37
38 for (const Mesh::MeshData& subMesh : _subMeshList)
39 {
40 Get(subMesh._mesh)->setMaterialTpl(material);
41 }
42}
43
44void Mesh::setAnimationCount( const size_t animationCount )
45{
46 _animationCount = animationCount;
47 if ( _animationCount == 0 && _animator != nullptr)
48 {
49 _animator.reset();
50 }
51 else if ( _animationCount > 0u && _animator == nullptr)
52 {
53 _animator = std::make_unique<SceneAnimator>();
54 }
55}
56
57SceneAnimator* Mesh::getAnimator() const noexcept
58{
59 return _animator.get();
60}
61
62SceneGraphNode* Mesh::addSubMeshNode(SceneGraphNode* parentNode, const U32 meshIndex)
63{
64 constexpr U32 normalMask = to_base(ComponentType::NAVIGATION) |
65 to_base(ComponentType::TRANSFORM) |
66 to_base(ComponentType::BOUNDS) |
67 to_base(ComponentType::RENDERING) |
68 to_base(ComponentType::RIGID_BODY) |
69 to_base(ComponentType::NAVIGATION);
70
71 constexpr U32 skinnedMask = to_base(ComponentType::ANIMATION) |
72 to_base(ComponentType::INVERSE_KINEMATICS) |
73 to_base(ComponentType::RAGDOLL);
74
75 DIVIDE_ASSERT(meshIndex < _subMeshList.size());
76
77 const MeshData& meshData = _subMeshList[meshIndex];
78 DIVIDE_ASSERT(meshData._index == meshIndex);
79 SubMesh* subMesh = Get( meshData._mesh );
80
81 SceneGraphNodeDescriptor subMeshDescriptor;
82 subMeshDescriptor._usageContext = parentNode->usageContext();
83 subMeshDescriptor._instanceCount = parentNode->instanceCount();
84 subMeshDescriptor._nodeHandle = FromHandle(meshData._mesh);
85 subMeshDescriptor._componentMask = normalMask;
86
87 if ( subMesh->boneCount() > 0u )
88 {
89 subMeshDescriptor._componentMask |= skinnedMask;
90 }
91
92 Util::StringFormat( subMeshDescriptor._name, "{}_{}", parentNode->name().c_str(), meshIndex );
93
94 SceneGraphNode* sgn = parentNode->addChildNode(subMeshDescriptor);
95 sgn->get<TransformComponent>()->setPosition(subMesh->getWorldOffset());
96
97 return sgn;
98}
99
100void Mesh::processNode(SceneGraphNode* parentNode, const MeshNodeData& node)
101{
102 for (const U32 idx : node._meshIndices)
103 {
104 addSubMeshNode(parentNode, idx);
105 }
106
107 if (!node._children.empty())
108 {
109 ResourceDescriptor<TransformNode> nodeDescriptor{ node._name + "_transform" };
110
111 SceneGraphNodeDescriptor tempNodeDescriptor;
112 tempNodeDescriptor._usageContext = parentNode->usageContext();
113 tempNodeDescriptor._instanceCount = parentNode->instanceCount();
114 tempNodeDescriptor._name = node._name.c_str();
115 tempNodeDescriptor._nodeHandle = FromHandle(CreateResource( nodeDescriptor ));
116 tempNodeDescriptor._componentMask = to_base(ComponentType::TRANSFORM) |
117 to_base(ComponentType::NETWORKING);
118 for (const MeshNodeData& it : node._children)
119 {
120 SceneGraphNode* targetSGN = parentNode;
121 if (!it._transform.isIdentity())
122 {
123 targetSGN = parentNode->addChildNode(tempNodeDescriptor);
124 targetSGN->get<TransformComponent>()->setTransforms(it._transform);
125 }
126 processNode(targetSGN, it);
127 }
128 }
129}
130
132void Mesh::postLoad(SceneGraphNode* sgn)
133{
134 sgn->get<TransformComponent>()->setTransforms(_nodeStructure._transform);
135 processNode(sgn, _nodeStructure);
136 if (_animator)
137 {
138 PlatformContext& pContext = sgn->context();
139
140 Attorney::SceneAnimatorMeshImporter::buildBuffers(*_animator, pContext.gfx() );
141
142 registerEditorComponent( pContext );
143 DIVIDE_ASSERT( _editorComponent != nullptr );
144
145 EditorComponentField playAnimationsField = {};
146 playAnimationsField._name = "Toogle Animation Playback";
147 playAnimationsField._data = &_playAnimationsOverride;
148 playAnimationsField._type = EditorComponentFieldType::SWITCH_TYPE;
149 playAnimationsField._basicType = PushConstantType::BOOL;
150 playAnimationsField._readOnly = false;
151 _editorComponent->registerField( MOV( playAnimationsField ) );
152 }
153
154 Object3D::postLoad(sgn);
155}
156
157bool Mesh::postLoad()
158{
159 return Object3D::postLoad();
160}
161
162bool Mesh::load( PlatformContext& context )
163{
164 if ( MeshImporter::loadMesh( context, this ) )
165 {
166 return Object3D::load(context);
167 }
168
169 return false;
170}
171
172bool Mesh::unload()
173{
174 for ( Mesh::MeshData& subMesh : _subMeshList )
175 {
176 DestroyResource(subMesh._mesh);
177 }
178 _subMeshList.clear();
179 return Object3D::unload();
180}
181
182bool MeshNodeData::serialize(ByteBuffer& dataOut) const {
183 dataOut << _transform;
184 dataOut << _meshIndices;
185 dataOut << to_U32(_children.size());
186 for (const MeshNodeData& child : _children)
187 {
188 child.serialize(dataOut);
189 }
190 dataOut << _name;
191 return true;
192}
193
194bool MeshNodeData::deserialize(ByteBuffer& dataIn) {
195 dataIn >> _transform;
196 dataIn >> _meshIndices;
197 U32 childCount = 0u;
198 dataIn >> childCount;
199 _children.resize(childCount);
200 for (MeshNodeData& child : _children)
201 {
202 child.deserialize(dataIn);
203 }
204 dataIn >> _name;
205 return true;
206}
207
208}; //namespace Divide
#define MOV(...)
#define DIVIDE_ASSERT(...)
void resize(size_t newsize)
Resizes the underlying storage to 'newsize' bytes and resets the read and write head positions.
Definition: ByteBuffer.inl:365
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
constexpr SceneNodeType GetSceneNodeType()
Definition: SceneNodeFwd.h:111
constexpr U32 to_U32(const T value)
FORCE_INLINE void DestroyResource(Handle< T > &handle, const bool immediate=false)
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
SceneNodeHandle FromHandle(const Handle< T > handle)
FORCE_INLINE T * Get(const Handle< T > handle)
uint32_t U32
constexpr auto to_base(const Type value) -> Type