Skinning data
The Simplygon API now provides the user to add skinning information per-vertex. The skinning data is kept intact when performing reduction. The API also provides the ability to reduce bones and generate new skinning data based on the reduction. For more on how to use bone reduction see the section about bone reduction settings or the bone reduction example.
Smooth skinning
Simplygon API provides support for smooth skinning. Two new fields have been added to the GeometryData class for skinning purposes. These two fields are the BoneIds and BoneWeights. The figure above shows how smooth skinning works.
Bones
To add skinning information in GeometryData use the AddBoneWeights. The method takes the tuple size which should be equal to the number of bones influencing a vertex. The API allows a vertex to be influenced by a maximum of four bones. Calling AddBoneWeights also creates the BoneIds field with the same tuple size. The bone ids field contains integer ids. The bone weights field can accept floating point values. Set the bone id and bone weight to -1 and 0 respectively if the tuple is not used. Bone setup is provided through the Simplygon scenegraph see SceneBone documentation.
Example - How to use skinning data
void AddBoneToGeometryData(spGeometryData geom)
{
// Add bone weights to geometry data (per vertex).
// Up to two bones can influence each vertex.
geom->AddBoneWeights(2);
spRealArray BoneWeights = geom->GetBoneWeights();
spRidArray BoneIds = geom->GetBoneIds();
// Add bone info to the bone weight and id fields.
for( int v_index=0; v_index<geom->GetVertexCount(); ++v_index )
{
// Set the bone weight to perform skinning.
BoneWeights->SetItem((v_index*2)+0, 0.5);
BoneWeights->SetItem((v_index*2)+1, 0.5);
// Set the bone ids influencing the vertex.
// Second argument is bone id.
BoneIds->SetItem((v_index*2)+0, 0);
BoneIds->SetItem((v_index*2)+1, 0);
}
}
void AddBoneToGeometryData(spGeometryData geom)
{
// Add bone weights to geometry data (per vertex).
// Up to two bones can influence each vertex.
geom.AddBoneWeights(2);
spRealArray BoneWeights = geom.GetBoneWeights();
spRidArray BoneIds = geom.GetBoneIds();
// Add bone info to the bone weight and id fields.
for (int v_index = 0; v_index < geom.GetVertexCount(); ++v_index)
{
// Set the bone weight to perform skinning.
BoneWeights.SetItem((v_index * 2) + 0, 0.5f);
BoneWeights.SetItem((v_index * 2) + 1, 0.5f);
// Set the bone ids influencing the vertex.
// Second argument is bone id.
BoneIds.SetItem((v_index * 2) + 0, 0);
BoneIds.SetItem((v_index * 2) + 1, 0);
}
}
def AddBoneToGeometryData(geom):
# Add bone weights to geometry data (per vertex).
# Up to two bones can influence each vertex.
geom.AddBoneWeights(2)
BoneWeights = geom.GetBoneWeights()
BoneIds = geom.GetBoneIds()
# Add bone info to the bone weight and id fields.
for v_index in range(geom.GetVertexCount()):
# Setup the bone indices to influence this vertex.
# In this case bone 0 and 1
v_bone_indices = [0 , 1]
BoneIds.SetTuple( v_index, v_bone_indices )
# Setup the bone weight to perform skinning.
# In this case 50% on the first bone and 50% on the second bone
v_bone_weights = [0.5 , 0.5]
BoneWeights.SetTuple( v_index, v_bone_weights )