- Home /

# How do I blend two BoneWeights?

Or fake it?

I'm creating a new vertex C, X% of the way between vertices A and B of a skinned mesh. C needs to stay between A and B such that they form a single visual edge (A-C-B) - or, as close as possible.

I can put the vertex in place but I'm not sure how to get it to stay there. I need to give C a BoneWeight which is a weighted average of A and B's weights. Often, this is pretty trivial - if A and B are on the same bone, then the new BoneWeight is just X% * weight A + (1-X%) * weight B. But what happens if A is affected by bones 0-3 and B is affected by bones 2-5? A vertex can only be weighted by four bones max. :confusedface:

Here's the uncommented code dump I have currently, which works great when the bones of two vertices already match exactly. If more bones than the quality settings allow are affecting a vertex, I get poor results. Is there any way around this and/or is my code doing silly things it shouldn't?

```
private class ArrayBoneWeight {
// makes it use arrays so i don't break my fingers typing
var weights:float[];
var bones:int[];
...
static function Combine(l:ArrayBoneWeight,r:ArrayBoneWeight,left:float,bones:int) : ArrayBoneWeight {
var right : float = 1-left;
var out : ArrayBoneWeight = new ArrayBoneWeight();
out.bones =[l.bones[0],l.bones[1],l.bones[2],l.bones[3],-1,-1,-1,-1];
out.weights=[l.weights[0]*left,l.weights[1]*left,l.weights[2]*left,l.weights[3]*left,-1,-1,-1,-1];
var lix : int;
var iix : int;
var tmp : float;
for ( lix = 0; lix < 4; lix++ ) {
for ( iix = 0; iix < 8; iix++ ) {
if ( out.bones[iix] == -1 ) break;
if ( out.bones[iix]==r.bones[lix] ) {
out.weights[iix]+=r.weights[lix] * right;
break;
}
}
if ( iix < 8 && out.bones[iix] == -1 ) {
out.bones[iix] = r.bones[lix];
out.weights[iix]=r.weights[lix]*right;
}
}
for ( lix = 1; lix < 8; lix++ ) {
while ( out.weights[lix] > out.weights[lix-1] ) {
tmp=out.weights[lix]; out.weights[lix]=out.weights[lix-1];out.weights[lix-1]=tmp;
iix=out.bones[lix];out.bones[lix]=out.bones[lix-1];out.bones[lix-1]=iix;
if ( lix > 1 ) lix--;
}
}
var bwgt : float = 0;
for ( lix = 0; lix < bones; lix++ ) { bwgt+= out.weights[lix]; }
bwgt = 1/bwgt;
for ( lix = 0; lix < 8; lix++ ) { out.weights[lix]=(lix>=bones)?0:out.weights[lix]*bwgt; }
return out;
}
}
// bones is the current bone quality setting - only that many bones can affect a vertex
static private function AverageBoneWeight( left : BoneWeight, right : BoneWeight, dist : float, bones : int ) : BoneWeight {
var bw : BoneWeight = new BoneWeight();
var negd : float = 1-dist;
var l : ArrayBoneWeight = new ArrayBoneWeight(left);
var r : ArrayBoneWeight = new ArrayBoneWeight(right);
l = ArrayBoneWeight.Combine(l,r,dist,bones);
return l.ToWeight();
}
```

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Modifying mesh vertices in an editor script 2 Answers

Get certain vertices? 1 Answer

Importing shapekeys from Blender 4 Answers

to Verlet or to Perlin ? 1 Answer

Skinned Cloth Editor Crashs 1 Answer