Vertex Weight calculation

Started by
1 comment, last by Andrew Lucas 14 years, 5 months ago
I've been messing with this issue earlier actually, but to be honest I was tired of it and decided to give up. Now, I'm almost done with all of my work, and I had realised that I'd like to wrap this issue up too. In my game engine, I have decalling for world polygons and 3d models too. The models in my game have simple bone transformations calculated, with only one bone being able to affect one vertex. Now, when decals are applied to a model, they would need vertex weight calculations to be done each time they are applied over a triangle whose vertices are shared between multiple bones, but right now I simply don't let decals be applied onto such triangles. This doesn't look good, at all, especially on lower-polygon models, so I thought I'd bring this issue up again. Last time, I was given a solution wich didn't really work for me, and I decided to give up. I'd like to illustrate my problem in a simple diagram. http://img69.imageshack.us/img69/9529/triangle.jpg As you can see, the triangle that belongs to the basic model is defined by three 3d coordinates, the black A, B and C coordinates. When this triangle is touched by a decal's mins/maxs, it gets clipped and forms a polygon with three new coordinates, the red A, B and C. Well, the red A would be alright, but I'd need to calculate bone weights for the red B, C and D coordinates. This is where I'm in trouble, as I don't have the mathematical background to make this kind of calculation. I'd like it if someone could help me out with some kind of formula, as I can't get anywhere on my own. Thanks.
Advertisement
I tried using the method advised by Black Panther in the previous topic, with little to no success on the issue to be honest. I guess either there's something wrong with this method, or the way I'm transforming the positions into bone-space. This is how my code looks like:

The Area function looks like this:
float Area( vec3_t A, vec3_t B, vec3_t C ){	return CrossProduct(B - A, C - A).Length();}

	float area = Area(v1, v2, v3);	v1 = verts[tri->verts[0].vertindex];	v2 = verts[tri->verts[1].vertindex];	v3 = verts[tri->verts[2].vertindex];	indexes[0] = tri->verts[0].boneindex;	indexes[1] = tri->verts[1].boneindex;	indexes[2] = tri->verts[2].boneindex;	for(int i = 0; i < nv; i++)	{		float weight1 = Area(dverts1, v2, v3)/area;		float weight2 = Area(dverts1, v3, v1)/area;		float weight3 = Area(dverts1, v1, v2)/area;		float totalweight = weight1+weight2+weight3;		if(totalweight > 1.0)		{			float diff = 1.0/totalweight;			weight1 *= diff;			weight2 *= diff;			weight3 *= diff;		}		weights[0] = weight1;		weights[1] = weight2;		weights[2] = weight3;	}	vec3_t temp1, temp2, temp3;	vec3_t finalposition;	for(int i = 0; i < nv; i++)	{		VectorClear(finalposition);		for(int j = 0; j < 3; j++)		{			VectorClear(temp1);			VectorClear(temp2);			VectorClear(temp3);			temp1[0] = dverts1[0]-(*m_pbonetransform)[indexes[j]][0][3];			temp1[1] = dverts1[1]-(*m_pbonetransform)[indexes[j]][1][3];			temp1[2] = dverts1[2]-(*m_pbonetransform)[indexes[j]][2][3];			VectorIRotate( temp1, (*m_pbonetransform)[indexes[j]], temp2 );			VectorMA(finalposition, weights[j], temp2, finalposition);		}		float texc_x = (DotProduct(dverts1, right) - texc_orig_x)/xsize;		float texc_y = (DotProduct(dverts1, up) - texc_orig_y)/ysize;		decalpoly.verts.texcoord[0] = ((texc_x + 1)/2)*-1;		decalpoly.verts.texcoord[1] = ((texc_y + 1)/2)*-1;		int j = 0;		for(; j < decal->verts.size(); j++)		{			if(decal->verts[j].position == finalposition)			{				decalpoly.verts.vertindex = j;				break;			}		}		if(j == decal->verts.size())		{			decalvertinfo_t vinfo;			memcpy(vinfo.boneindexes, indexes, sizeof(indexes));			memcpy(vinfo.boneweights, weights, sizeof(float)*3);			VectorCopy(finalposition, vinfo.position);			decalpoly.verts.vertindex = decal->verts.size();			decal->verts.push_back(vinfo);		}	}


And this is how the coordinate is transformed during rendering:

		for(int i = 0; i < pnext->verts.size(); i++)		{			vec3_t temp;			VectorClear(temp);			VectorClear(m_vVertexTransform);			for(int j = 0; j < 3; j++)			{				if(pnext->verts.boneweights[j] == 0)					continue;				VectorTransform( pnext->verts.position, (*m_pbonetransform)[pnext->verts.boneindexes[j]], temp );				VectorMA(m_vVertexTransform, pnext->verts.boneweights[j], temp, m_vVertexTransform);			}		}


[Edited by - Andrew Lucas on November 11, 2009 10:14:39 AM]
Doesn't anyone have a suggestion at least? I'm either doing something horribly wrong when I transform the vertex back, or the weights are completely wrong. Any advice is apprechiated.

Thanks.

This topic is closed to new replies.

Advertisement