46 Ogre::Quaternion
const & rot,
47 std::vector<unsigned int> & node_indices
49 m_center_offset(offset)
54 , m_gfx_actor(gfx_actor)
59 Ogre::Vector3* vertices =
nullptr;
60 std::string mesh_name = ent->getMesh()->getName();
62 Vector3 normal = Vector3::UNIT_Y;
63 Vector3 position = Vector3::ZERO;
64 Quaternion orientation = Quaternion::ZERO;
70 Vector3 diffX =
nodes[nx].AbsPosition-
nodes[ref].AbsPosition;
71 Vector3 diffY =
nodes[ny].AbsPosition-
nodes[ref].AbsPosition;
73 normal = (diffY.crossProduct(diffX)).normalisedCopy();
76 position =
nodes[ref].AbsPosition + offset.x * diffX + offset.y * diffY;
77 position = position + offset.z * normal;
80 Vector3 refX = diffX.normalisedCopy();
81 Vector3 refY = refX.crossProduct(normal);
82 orientation = Quaternion(refX, normal, refY) * rot;
87 normal = Vector3::UNIT_Y;
88 position =
nodes[0].AbsPosition + offset;
92 Ogre::MeshPtr mesh=ent->getMesh();
94 int num_submeshes =
static_cast<int>(mesh->getNumSubMeshes());
95 if (preloaded_from_cache ==
nullptr)
98 if (mesh->sharedVertexData && mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_TEXTURE_COORDINATES)==0)
102 for (
int i=0; i<num_submeshes; i++)
104 if (!mesh->getSubMesh(i)->useSharedVertices && mesh->getSubMesh(i)->vertexData->vertexDeclaration->findElementBySemantic(VES_TEXTURE_COORDINATES)==0)
111 LOG(
"FLEXBODY Warning: at least one part of this mesh does not have texture coordinates, switching off texturing!");
116 bool havenormal=
true;
117 if (mesh->sharedVertexData && mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL)==0)
121 for (
int i=0; i<num_submeshes; i++)
123 if (!mesh->getSubMesh(i)->useSharedVertices && mesh->getSubMesh(i)->vertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL)==0)
130 LOG(
"FLEXBODY Error: at least one part of this mesh does not have normal vectors, export your mesh with normal vectors! Disabling flexbody");
141 VertexDeclaration* optimalVD=HardwareBufferManager::getSingleton().createVertexDeclaration();
142 optimalVD->addElement(0, 0, VET_FLOAT3, VES_POSITION);
143 optimalVD->addElement(1, 0, VET_FLOAT3, VES_NORMAL);
145 if (
m_has_texture) optimalVD->addElement(3, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
147 optimalVD->closeGapsInSource();
148 BufferUsageList optimalBufferUsages;
149 for (
size_t u = 0; u <= optimalVD->getMaxSource(); ++u)
151 optimalBufferUsages.push_back(HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
157 if (mesh->sharedVertexData)
159 if (mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)==0)
162 int index=mesh->sharedVertexData->vertexDeclaration->getMaxSource()+1;
163 mesh->sharedVertexData->vertexDeclaration->addElement(index, 0, VET_COLOUR_ARGB, VES_DIFFUSE);
164 mesh->sharedVertexData->vertexDeclaration->sort();
165 index=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)->getSource();
166 HardwareVertexBufferSharedPtr vbuf=HardwareBufferManager::getSingleton().createVertexBuffer(VertexElement::getTypeSize(VET_COLOUR_ARGB), mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
167 mesh->sharedVertexData->vertexBufferBinding->setBinding(index, vbuf);
170 for (
int i=0; i<num_submeshes; i++)
172 if (!mesh->getSubMesh(i)->useSharedVertices)
174 Ogre::VertexData* vertex_data = mesh->getSubMesh(i)->vertexData;
175 Ogre::VertexDeclaration* vertex_decl = vertex_data->vertexDeclaration;
176 if (vertex_decl->findElementBySemantic(VES_DIFFUSE)==0)
179 int index = vertex_decl->getMaxSource()+1;
180 vertex_decl->addElement(index, 0, VET_COLOUR_ARGB, VES_DIFFUSE);
182 vertex_decl->findElementBySemantic(VES_DIFFUSE)->getSource();
183 HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
184 VertexElement::getTypeSize(VET_COLOUR_ARGB), vertex_data->vertexCount, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
185 vertex_data->vertexBufferBinding->setBinding(index, vbuf);
193 if (mesh->sharedVertexData)
195 mesh->sharedVertexData->reorganiseBuffers(optimalVD, optimalBufferUsages);
196 mesh->sharedVertexData->removeUnusedBuffers();
197 mesh->sharedVertexData->closeGapsInBindings();
199 Mesh::SubMeshIterator smIt = mesh->getSubMeshIterator();
200 while (smIt.hasMoreElements())
202 SubMesh* sm = smIt.getNext();
203 if (!sm->useSharedVertices)
205 sm->vertexData->reorganiseBuffers(optimalVD->clone(), optimalBufferUsages);
206 sm->vertexData->removeUnusedBuffers();
207 sm->vertexData->closeGapsInBindings();
219 if (preloaded_from_cache ==
nullptr)
224 if (mesh->sharedVertexData)
229 for (
int i=0; i<num_submeshes; i++)
231 if (!mesh->getSubMesh(i)->useSharedVertices)
245 double stat_manual_buffers_created_time = -1;
246 double stat_transformed_time = -1;
247 double stat_located_time = -1;
248 if (preloaded_from_cache !=
nullptr)
260 if (mesh->sharedVertexData)
265 int source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
266 m_shared_vbuf_pos=mesh->sharedVertexData->vertexBufferBinding->getBuffer(source);
268 source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL)->getSource();
273 source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)->getSource();
277 unsigned int curr_submesh_idx = 0;
278 for (
int i=0; i<num_submeshes; i++)
280 const Ogre::SubMesh* submesh = mesh->getSubMesh(i);
281 if (submesh->useSharedVertices)
285 const Ogre::VertexData* vertex_data = submesh->vertexData;
288 int source_pos = vertex_data->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
289 int source_norm = vertex_data->vertexDeclaration->findElementBySemantic(VES_NORMAL)->getSource();
290 m_submesh_vbufs_pos [curr_submesh_idx] = vertex_data->vertexBufferBinding->getBuffer(source_pos);
291 m_submesh_vbufs_norm[curr_submesh_idx] = vertex_data->vertexBufferBinding->getBuffer(source_norm);
295 int source_color = vertex_data->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)->getSource();
312 Vector3* vpt=vertices;
314 if (mesh->sharedVertexData)
318 int source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
319 m_shared_vbuf_pos=mesh->sharedVertexData->vertexBufferBinding->getBuffer(source);
320 m_shared_vbuf_pos->readData(0, mesh->sharedVertexData->vertexCount*
sizeof(Vector3), (
void*)vpt);
321 vpt+=mesh->sharedVertexData->vertexCount;
323 source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL)->getSource();
325 m_shared_vbuf_norm->readData(0, mesh->sharedVertexData->vertexCount*
sizeof(Vector3), (
void*)npt);
326 npt+=mesh->sharedVertexData->vertexCount;
330 source=mesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)->getSource();
336 for (
int i=0; i<num_submeshes; i++)
338 const Ogre::SubMesh* submesh = mesh->getSubMesh(i);
339 if (submesh->useSharedVertices)
343 const Ogre::VertexData* vertex_data = submesh->vertexData;
344 int vertex_count = (int)vertex_data->vertexCount;
347 int source = vertex_data->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource();
352 source = vertex_data->vertexDeclaration->findElementBySemantic(VES_NORMAL)->getSource();
359 source = vertex_data->vertexDeclaration->findElementBySemantic(VES_DIFFUSE)->getSource();
369 vertices[i]=(orientation*vertices[i])+position;
376 float closest_node_distance = std::numeric_limits<float>::max();
377 int closest_node_index = -1;
378 for (
auto node_index : node_indices)
380 float node_distance = vertices[i].squaredDistance(
nodes[node_index].AbsPosition);
381 if (node_distance < closest_node_distance)
383 closest_node_distance = node_distance;
384 closest_node_index = node_index;
387 if (closest_node_index == -1)
389 LOG(
"FLEXBODY ERROR on mesh "+mesh_name+
": REF node not found");
390 closest_node_index = 0;
395 closest_node_distance = std::numeric_limits<float>::max();
396 closest_node_index = -1;
397 for (
auto node_index : node_indices)
403 float node_distance = vertices[i].squaredDistance(
nodes[node_index].AbsPosition);
404 if (node_distance < closest_node_distance)
406 closest_node_distance = node_distance;
407 closest_node_index = node_index;
410 if (closest_node_index == -1)
412 LOG(
"FLEXBODY ERROR on mesh "+mesh_name+
": VX node not found");
413 closest_node_index = 0;
418 closest_node_distance = std::numeric_limits<float>::max();
419 closest_node_index = -1;
421 for (
auto node_index : node_indices)
427 float node_distance = vertices[i].squaredDistance(
nodes[node_index].AbsPosition);
428 if (node_distance < closest_node_distance)
431 float cost = vx.dotProduct(vt);
432 if (std::abs(cost) > std::sqrt(2.0f) / 2.0f)
436 closest_node_distance = node_distance;
437 closest_node_index = node_index;
440 if (closest_node_index == -1)
442 LOG(
"FLEXBODY ERROR on mesh "+mesh_name+
": VY node not found");
443 closest_node_index = 0;
451 mat.SetColumn(0, diffX);
452 mat.SetColumn(1, diffY);
453 mat.SetColumn(2, (diffX.crossProduct(diffY)).normalisedCopy());
466 AxisAlignedBox aab=mesh->getBounds();
467 Vector3 v=aab.getMinimum();
478 aab.setMinimum(Vector3(-ma,-ma,-ma));
479 aab.setMaximum(Vector3(ma,ma,ma));
480 mesh->_setBounds(aab,
true);
487 if (preloaded_from_cache ==
nullptr)
495 mat.SetColumn(0, diffX);
496 mat.SetColumn(1, diffY);
497 mat.SetColumn(2, diffX.crossProduct(diffY).normalisedCopy());
506 if (vertices !=
nullptr) { free(vertices); }
509 for (
unsigned int nodenum : node_indices)
575 Ogre::MeshManager::getSingleton().remove(mesh->getHandle());
614 Ogre::Vector3 flexit_normal =
fast_normalise(diffY.crossProduct(diffX));
712 if (nd->
nd_is_wet ^ ((col&0x000000FF)>0))
748 template<
typename u
int_T>
void reorderIndexBuffer(Ogre::IndexData* idx_data, std::vector<int>
const& new_index_lookup)
750 uint_T* workibuf =
new uint_T[idx_data->indexCount];
751 idx_data->indexBuffer->readData(0, idx_data->indexBuffer->getSizeInBytes(), workibuf);
752 for (
size_t i = 0; i < idx_data->indexCount; i++)
754 workibuf[i] = new_index_lookup[workibuf[i]];
756 idx_data->indexBuffer->writeData(0, idx_data->indexBuffer->getSizeInBytes(), workibuf);
760 void reorderVertexBuffer(Ogre::HardwareVertexBufferSharedPtr vert_buf,
const Ogre::VertexElement* vert_elem, std::vector<int>
const& new_index_lookup)
762 char* workbuf_src =
new char[vert_buf->getSizeInBytes()];
763 char* workbuf_dst =
new char[vert_buf->getSizeInBytes()];
764 vert_buf->readData(0, vert_buf->getSizeInBytes(), workbuf_src);
765 for (
size_t i = 0; i < vert_buf->getNumVertices(); i++)
767 void* src = workbuf_src + (i * vert_elem->getSize());
768 void* dst = workbuf_dst + (new_index_lookup[i] * vert_elem->getSize());
769 std::memcpy(dst, src, vert_elem->getSize());
771 vert_buf->writeData(0, vert_buf->getSizeInBytes(), workbuf_dst);
772 delete[] workbuf_src;
773 delete[] workbuf_dst;
779 NodeNum_t forset_max = std::numeric_limits<NodeNum_t>::min();
780 NodeNum_t forset_min = std::numeric_limits<NodeNum_t>::max();
783 if (n > forset_max) { forset_max = n; }
784 if (n < forset_min) { forset_min = n; }
790 new_index_lookup[i] = i;
795 prev_loc.
ref = forset_min;
796 prev_loc.
nx = forset_min;
797 prev_loc.
ny = forset_min;
804 int closest_loc_penalty = INT_MAX;
808 if (penalty < closest_loc_penalty)
810 closest_loc_penalty = penalty;
818 int idx_tmp = new_index_lookup[closest_loc];
822 new_index_lookup[closest_loc] = new_index_lookup[i];
826 new_index_lookup[i] = idx_tmp;
837 inverted_lookup[new_index_lookup[i]] = i;
841 new_index_lookup[i] = inverted_lookup[i];
850 Ogre::VertexData* vert_data =
nullptr;
860 const Ogre::VertexElement* uv_elem = vert_data->vertexDeclaration->findElementBySemantic(Ogre::VES_TEXTURE_COORDINATES);
861 Ogre::HardwareVertexBufferSharedPtr uv_buf = vert_data->vertexBufferBinding->getBuffer(uv_elem->getSource());
868 Ogre::IndexData* idx_data =
m_scene_entity->getMesh()->getSubMesh(0)->indexData;
870 if (idx_data->indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_16BIT)
872 reorderIndexBuffer<uint16_t>(idx_data, new_index_lookup);
876 reorderIndexBuffer<uint32_t>(idx_data, new_index_lookup);