From 2c28eef74a5f71aa34ee994af07d54bc274f459e Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Fri, 25 Nov 2016 22:51:31 -0400 Subject: [PATCH] Added 2 new variants of Mesh:attachAttribute (resolves issue #1233). Thanks xenthral! - Added Mesh:attachAttribute(name, mesh, nameInMesh) which retargets the attribute name in the specified Mesh (3rd argument) to a new name for this mesh (1st argument). - Added Mesh:attachAttribute(name) which detaches any attached attributes from other meshes for that attribute name. --HG-- branch : minor --- src/modules/graphics/opengl/Mesh.cpp | 31 +++++++++++++++-------- src/modules/graphics/opengl/Mesh.h | 2 +- src/modules/graphics/opengl/wrap_Mesh.cpp | 10 ++++++-- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 8d7e7e87b..7d7c011aa 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -309,9 +309,26 @@ bool Mesh::isAttributeEnabled(const std::string &name) const return it->second.enabled; } -void Mesh::attachAttribute(const std::string &name, Mesh *mesh) +void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname) { - if (mesh != this) + AttachedAttribute oldattrib = {}; + + auto it = attachedAttributes.find(name); + if (it != attachedAttributes.end()) + oldattrib = it->second; + + if (mesh == nullptr) + { + if (it != attachedAttributes.end() && oldattrib.mesh != this) + { + oldattrib.mesh->release(); + attachedAttributes.erase(it); + if (getAttributeIndex(name) != -1) + attachAttribute(name, this, name); + return; + } + } + else if (mesh != this) { for (const auto &it : mesh->attachedAttributes) { @@ -322,19 +339,13 @@ void Mesh::attachAttribute(const std::string &name, Mesh *mesh) } } - AttachedAttribute oldattrib = {}; AttachedAttribute newattrib = {}; - - auto it = attachedAttributes.find(name); - if (it != attachedAttributes.end()) - oldattrib = it->second; - newattrib.mesh = mesh; newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true; - newattrib.index = mesh->getAttributeIndex(name); + newattrib.index = mesh->getAttributeIndex(attachname); if (newattrib.index < 0) - throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", name.c_str()); + throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", attachname.c_str()); if (newattrib.mesh != this) newattrib.mesh->retain(); diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 19ba61097..c34032d3b 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -138,7 +138,7 @@ public: * Attaches a vertex attribute from another Mesh to this one. The attribute * will be used when drawing this Mesh. **/ - void attachAttribute(const std::string &name, Mesh *mesh); + void attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname); void *mapVertexData(); void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 3f730554a..f0bde6fa0 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -337,8 +337,14 @@ int w_Mesh_attachAttribute(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); const char *name = luaL_checkstring(L, 2); - Mesh *mesh = luax_checkmesh(L, 3); - luax_catchexcept(L, [&](){ t->attachAttribute(name, mesh); }); + const char *attachname = name; + Mesh *mesh = nullptr; + if (lua_isnoneornil(L, 3)) + { + mesh = luax_checkmesh(L, 3); + attachname = luaL_optstring(L, 4, attachname); + } + luax_catchexcept(L, [&](){ t->attachAttribute(name, mesh, attachname); }); return 0; }