//----------------------------------------------------------------------- VertexDeclaration* VertexDeclaration::getAutoOrganisedDeclaration( bool skeletalAnimation, bool vertexAnimation) { VertexDeclaration* newDecl = this->clone(); // Set all sources to the same buffer (for now) const VertexDeclaration::VertexElementList& elems = newDecl->getElements(); VertexDeclaration::VertexElementList::const_iterator i; unsigned short c = 0; for (i = elems.begin(); i != elems.end(); ++i, ++c) { const VertexElement& elem = *i; // Set source & offset to 0 for now, before sort newDecl->modifyElement(c, 0, 0, elem.getType(), elem.getSemantic(), elem.getIndex()); } newDecl->sort(); // Now sort out proper buffer assignments and offsets size_t offset = 0; c = 0; unsigned short buffer = 0; VertexElementSemantic prevSemantic = VES_POSITION; for (i = elems.begin(); i != elems.end(); ++i, ++c) { const VertexElement& elem = *i; bool splitWithPrev = false; bool splitWithNext = false; switch (elem.getSemantic()) { case VES_POSITION: // For morph animation, we need positions on their own splitWithPrev = vertexAnimation; splitWithNext = vertexAnimation; break; case VES_NORMAL: // Normals can't sharing with blend weights/indices splitWithPrev = (prevSemantic == VES_BLEND_WEIGHTS || prevSemantic == VES_BLEND_INDICES); // All animated meshes have to split after normal splitWithNext = (skeletalAnimation || vertexAnimation); break; case VES_BLEND_WEIGHTS: // Blend weights/indices can be sharing with their own buffer only splitWithPrev = true; break; case VES_BLEND_INDICES: // Blend weights/indices can be sharing with their own buffer only splitWithNext = true; break; } if (splitWithPrev && offset) { ++buffer; offset = 0; } prevSemantic = elem.getSemantic(); newDecl->modifyElement(c, buffer, offset, elem.getType(), elem.getSemantic(), elem.getIndex()); if (splitWithNext) { ++buffer; offset = 0; } else { offset += elem.getSize(); } } return newDecl; }