Browse Source

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
Alex Szpakowski 8 years ago
parent
commit
2c28eef74a

+ 21 - 10
src/modules/graphics/opengl/Mesh.cpp

@@ -309,9 +309,26 @@ bool Mesh::isAttributeEnabled(const std::string &name) const
 	return it->second.enabled;
 	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)
 		for (const auto &it : mesh->attachedAttributes)
 		{
 		{
@@ -322,19 +339,13 @@ void Mesh::attachAttribute(const std::string &name, Mesh *mesh)
 		}
 		}
 	}
 	}
 
 
-	AttachedAttribute oldattrib = {};
 	AttachedAttribute newattrib = {};
 	AttachedAttribute newattrib = {};
-
-	auto it = attachedAttributes.find(name);
-	if (it != attachedAttributes.end())
-		oldattrib = it->second;
-
 	newattrib.mesh = mesh;
 	newattrib.mesh = mesh;
 	newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true;
 	newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true;
-	newattrib.index = mesh->getAttributeIndex(name);
+	newattrib.index = mesh->getAttributeIndex(attachname);
 
 
 	if (newattrib.index < 0)
 	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)
 	if (newattrib.mesh != this)
 		newattrib.mesh->retain();
 		newattrib.mesh->retain();

+ 1 - 1
src/modules/graphics/opengl/Mesh.h

@@ -138,7 +138,7 @@ public:
 	 * Attaches a vertex attribute from another Mesh to this one. The attribute
 	 * Attaches a vertex attribute from another Mesh to this one. The attribute
 	 * will be used when drawing this Mesh.
 	 * 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 *mapVertexData();
 	void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1);
 	void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1);

+ 8 - 2
src/modules/graphics/opengl/wrap_Mesh.cpp

@@ -337,8 +337,14 @@ int w_Mesh_attachAttribute(lua_State *L)
 {
 {
 	Mesh *t = luax_checkmesh(L, 1);
 	Mesh *t = luax_checkmesh(L, 1);
 	const char *name = luaL_checkstring(L, 2);
 	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;
 	return 0;
 }
 }