DQ skinning for Unity
Dual Quaternion skinning implementation with bulging compensation
Classes | Public Member Functions | Public Attributes | Properties | List of all members
DualQuaternionSkinner Class Reference

Replaces Unity's default linear skinning with DQ skinning More...

+ Inheritance diagram for DualQuaternionSkinner:

Public Member Functions

void SetViewFrustrumCulling (bool viewFrustrumculling)
 Enable or disable view frustrum culling.
When moving the bones manually to test the script, bounding box does not update (it is pre-calculated based on available animations), which may lead to improper culling. More...
 
bool GetViewFrustrumCulling ()
 Returns current state of view frustrum culling. More...
 
float[] GetBlendShapeWeights ()
 Returns an array of currently applied blend shape weights.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100. More...
 
void SetBlendShapeWeights (float[] weights)
 Applies blend shape weights from the given array.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100. More...
 
void SetBlendShapeWeight (int index, float weight)
 Set weight for the blend shape with given index.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100. More...
 
float GetBlendShapeWeight (int index)
 Returns currently applied weight for the blend shape with given index.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100. More...
 
void UpdatePerVertexCompensationCoef ()
 If the value of boneOrientationVector was changed while DualQuaternionSkinner is active (started == true), UpdatePerVertexCompensationCoef() must be called in order for the change to take effect. More...
 

Public Attributes

Vector3 boneOrientationVector = Vector3.up
 Bone orientation is required for bulge-compensation.
Do not set directly, use custom editor instead. More...
 
float bulgeCompensation = 0
 Adjusts the amount of bulge-compensation. More...
 
ComputeShader shaderComputeBoneDQ
 
ComputeShader shaderDQBlend
 
ComputeShader shaderApplyMorph
 

Properties

bool started = false [get]
 Indicates whether DualQuaternionSkinner is currently active. More...
 
Mesh mesh [get]
 UnityEngine.Mesh that is currently being rendered. More...
 

Detailed Description

Replaces Unity's default linear skinning with DQ skinning

Add this component to a GameObject that has SkinnedMeshRenderer attached.
Do not remove SkinnedMeshRenderer component!
Make sure that all materials of the animated object are using shader "MadCake/Material/Standard hacked for DQ skinning"

Definition at line 11 of file DualQuaternionSkinner.cs.

Member Function Documentation

◆ GetBlendShapeWeight()

float DualQuaternionSkinner.GetBlendShapeWeight ( int  index)

Returns currently applied weight for the blend shape with given index.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100.

Parameters
indexIndex of the blend shape
Returns
Currently applied weight

Definition at line 269 of file DualQuaternionSkinner.cs.

270  {
271  if (this.started == false)
272  {
273  return this.GetComponent<SkinnedMeshRenderer>().GetBlendShapeWeight(index);
274  }
275 
276  if (index < 0 || index >= this.morphWeights.Length)
277  {
278  throw new System.IndexOutOfRangeException("Blend shape index out of range");
279  }
280 
281  return this.morphWeights[index];
282  }

◆ GetBlendShapeWeights()

float [] DualQuaternionSkinner.GetBlendShapeWeights ( )

Returns an array of currently applied blend shape weights.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100.

Returns
Array of currently applied blend shape weights

Definition at line 201 of file DualQuaternionSkinner.cs.

202  {
203  float[] weights = new float[this.morphWeights.Length];
204  for (int i = 0; i < weights.Length; i++)
205  {
206  weights[i] = this.morphWeights[i];
207  }
208 
209  return weights;
210  }

◆ GetViewFrustrumCulling()

bool DualQuaternionSkinner.GetViewFrustrumCulling ( )

Returns current state of view frustrum culling.

Returns
Current state of view frustrum culling (true = enabled, false = disabled)

Definition at line 182 of file DualQuaternionSkinner.cs.

183  {
184  return this.viewFrustrumCulling;
185  }

◆ SetBlendShapeWeight()

void DualQuaternionSkinner.SetBlendShapeWeight ( int  index,
float  weight 
)

Set weight for the blend shape with given index.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100.

Parameters
indexIndex of the blend shape
weightWeight to be applied

Definition at line 244 of file DualQuaternionSkinner.cs.

245  {
246  if (this.started == false)
247  {
248  this.GetComponent<SkinnedMeshRenderer>().SetBlendShapeWeight(index, weight);
249  return;
250  }
251 
252  if (index < 0 || index >= this.morphWeights.Length)
253  {
254  throw new System.IndexOutOfRangeException("Blend shape index out of range");
255  }
256 
257  this.morphWeights[index] = weight;
258 
259  this.ApplyMorphs();
260  }

◆ SetBlendShapeWeights()

void DualQuaternionSkinner.SetBlendShapeWeights ( float[]  weights)

Applies blend shape weights from the given array.
Default range is 0-100.
It is possible to apply negative weights or exceeding 100.

Parameters
weightsAn array of weights to be applied

Definition at line 218 of file DualQuaternionSkinner.cs.

219  {
220  if (weights.Length != this.morphWeights.Length)
221  {
222  throw new System.ArgumentException(
223  "An array of weights must contain the number of elements " +
224  $"equal to the number of available blendshapes. Currently " +
225  $"{this.morphWeights.Length} blendshapes ara available but {weights.Length} weights were passed."
226  );
227  }
228 
229  for (int i = 0; i < weights.Length; i++)
230  {
231  this.morphWeights[i] = weights[i];
232  }
233 
234  this.ApplyMorphs();
235  }

◆ SetViewFrustrumCulling()

void DualQuaternionSkinner.SetViewFrustrumCulling ( bool  viewFrustrumculling)

Enable or disable view frustrum culling.
When moving the bones manually to test the script, bounding box does not update (it is pre-calculated based on available animations), which may lead to improper culling.

Definition at line 167 of file DualQuaternionSkinner.cs.

168  {
169  if (this.viewFrustrumCulling == viewFrustrumculling)
170  return;
171 
172  this.viewFrustrumCulling = viewFrustrumculling;
173 
174  if (this.started == true)
175  UpdateViewFrustrumCulling();
176  }

◆ UpdatePerVertexCompensationCoef()

void DualQuaternionSkinner.UpdatePerVertexCompensationCoef ( )

If the value of boneOrientationVector was changed while DualQuaternionSkinner is active (started == true), UpdatePerVertexCompensationCoef() must be called in order for the change to take effect.

Definition at line 306 of file DualQuaternionSkinner.cs.

307  {
308  if (this.started == false)
309  {
310  return;
311  }
312 
313  var vertInfos = new VertexInfo[this.mf.sharedMesh.vertexCount];
314  this.bufVertInfo.GetData(vertInfos);
315 
316  for (int i = 0; i < vertInfos.Length; i++)
317  {
318  Matrix4x4 bindPose = this.bindPoses[vertInfos[i].boneIndex0].inverse;
319  Quaternion boneBindRotation = bindPose.ExtractRotation();
320  Vector3 boneDirection = boneBindRotation * this.boneOrientationVector; // ToDo figure out bone orientation
321  Vector3 bonePosition = bindPose.ExtractPosition();
322  Vector3 toBone = bonePosition - (Vector3)vertInfos[i].position;
323 
324  vertInfos[i].compensation_coef = Vector3.Cross(toBone, boneDirection).magnitude;
325  }
326 
327  this.bufVertInfo.SetData(vertInfos);
328  this.ApplyMorphs();
329  }

Member Data Documentation

◆ boneOrientationVector

Vector3 DualQuaternionSkinner.boneOrientationVector = Vector3.up

Bone orientation is required for bulge-compensation.
Do not set directly, use custom editor instead.

Definition at line 17 of file DualQuaternionSkinner.cs.

◆ bulgeCompensation

float DualQuaternionSkinner.bulgeCompensation = 0

Adjusts the amount of bulge-compensation.

Definition at line 66 of file DualQuaternionSkinner.cs.

Property Documentation

◆ mesh

Mesh DualQuaternionSkinner.mesh
get

UnityEngine.Mesh that is currently being rendered.

See also
Mesh.GetBlendShapeName(int shapeIndex)
Mesh.GetBlendShapeIndex(string blendShapeName)
Mesh.blendShapeCount

Definition at line 290 of file DualQuaternionSkinner.cs.

291  {
292  get
293  {
294  if (this.started == false)
295  {
296  return this.smr.sharedMesh;
297  }
298 
299  return this.mf.sharedMesh;
300  }
301  }

◆ started

bool DualQuaternionSkinner.started = false
get

Indicates whether DualQuaternionSkinner is currently active.

Definition at line 75 of file DualQuaternionSkinner.cs.

75 { get; private set; } = false;
DualQuaternionSkinner.started
bool started
Indicates whether DualQuaternionSkinner is currently active.
Definition: DualQuaternionSkinner.cs:75
DualQuaternionSkinner.boneOrientationVector
Vector3 boneOrientationVector
Bone orientation is required for bulge-compensation. Do not set directly, use custom editor instead.
Definition: DualQuaternionSkinner.cs:17