Yo @Deltakosh and @bghgary … How do i assign the initial morph target weights… In GLTF there is a and array for gltfMesh.weights… So if the guy is supposed to be smiling (WITHOUT ANIMATION) you can set blendShape - SmileLeft = 1 and SmileRight = 1…
When using Babylon Entities… I dont see anything to set the initial weights…
@bghgary … We had this problem in GLTF… You fixed it … How… So we can try implement in Babylon Entities as well ???
FYI… Here is how i export blend shaped now… Just dont see a WEIGHTS property
private void ConvertUnityBlendShapesToBabylon(UnityEngine.Mesh mesh, SkinnedMeshRenderer skin, BabylonScene babylonScene, BabylonMesh babylonMesh)
{
// Blend Shapes / Morph Targets
if (mesh.blendShapeCount > 0)
{
// Morph Target Manager
var babylonMorphTargetManager = new BabylonMorphTargetManager();
babylonMesh.morphTargetManagerId = babylonMorphTargetManager.id;
// Convert Morph Targets
var babylonMorphTargets = new List<BabylonMorphTarget>();
for (int blendShapeIndex = 0; blendShapeIndex < mesh.blendShapeCount; blendShapeIndex++)
{
// As described above, a blend shape can have multiple frames. Given that glTF only supports a single frame
// per blend shape, we'll always use the final frame (the one that would be for when 100% weight is applied).
string morphName = mesh.GetBlendShapeName(blendShapeIndex);
float morphWeight = skin.GetBlendShapeWeight(blendShapeIndex) / 100;
int morphFrame = mesh.GetBlendShapeFrameCount(blendShapeIndex) - 1;
var deltaVertices = new Vector3[mesh.vertexCount];
var deltaNormals = new Vector3[mesh.vertexCount];
var deltaTangents = new Vector3[mesh.vertexCount];
mesh.GetBlendShapeFrameVertices(blendShapeIndex, morphFrame, deltaVertices, deltaNormals, deltaTangents);
// Blendshape
var babylonMorphTarget = new BabylonMorphTarget();
babylonMorphTarget.name = morphName;
// Influence
babylonMorphTarget.influence = 0f;
// Positions
babylonMorphTarget.positions = deltaVertices.ToFloat();
// Normals
babylonMorphTarget.normals = deltaNormals.ToFloat();
// Tangents
babylonMorphTarget.tangents = deltaTangents.ToFloat();
// Animations
/* TODO: Morph Animations
var animations = new List<BabylonAnimation>();
ExportFloatGameController(morphWeight, "influence", animations);
if (animations.Count > 0)
{
babylonMorphTarget.animations = animations.ToArray();
}
*/
babylonMorphTargets.Add(babylonMorphTarget);
}
babylonMorphTargetManager.targets = babylonMorphTargets.Count > 0 ? babylonMorphTargets.ToArray() : null;
babylonScene.MorphTargetManagersList.Add(babylonMorphTargetManager);
}
}
Yo @Deltakosh … What is the class VertexData used for… Am i supposed to be using that class for something in the entities export?
/// <summary>
/// Store the data of the vertex used to extract the geometry.
/// It used by the morph target in order to have the same vertex order between the mesh and the target.
/// </summary>
public class VertexData
{
public int polygonId { get; set; }
public int vertexIndexGlobal { get; set; }
public int vertexIndexLocal { get; set; }
public VertexData(int _polygonId, int _vertexIndexGlobal, int _vertexIndexLocal)
{
polygonId = _polygonId;
vertexIndexGlobal = _vertexIndexGlobal;
vertexIndexLocal = _vertexIndexLocal;
}
}
Unity stores blend shapes (morph targets) using a delta of the original. glTF does the same. Babylon, however, stores the absolute values of the shapes/targets. Is that perhaps what you are seeing?
because i am trying to add morph targets to rgular babylon entities… so i am serializing these raw deltas WHICH IS WRONG… I should be calculating something with this delta right ???
Can you please show me that calculation ???
Where do you apply this delta to the original in GLTF Loader ???
Visually Nothing Different. But when i was tracing the value in babylon morph target manager targets… the first blend shape vertices.x value for Blink Left in GLTF = -0.1176459789276123
but with adding the delta to the mesh.vertices … the x = -0.2 something…
But they both look perfect… i have blend shape Smile_Left and Smile_Right set to 100
and this is BABYLON SCENE FILE (updating the delta positions in C# code):
public static void UpdateBlendShapeDeltas(UnityEngine.Mesh mesh, Vector3[] deltaVertices, Vector3[] deltaNormals, Vector3[] deltaTangents)
{
int index = 0;
// Verticies
if (mesh.vertices != null && mesh.vertices.Length == deltaVertices.Length)
{
foreach (Vector3 vv in mesh.vertices)
{
deltaVertices[index] += vv;
index++;
}
}
// Normals
index = 0;
if (mesh.normals != null && mesh.normals.Length == deltaNormals.Length)
{
foreach (Vector3 nn in mesh.normals)
{
deltaNormals[index] += nn;
index++;
}
}
// Tangents
index = 0;
if (mesh.tangents != null && mesh.tangents.Length == deltaTangents.Length)
{
foreach (Vector4 tt in mesh.tangents)
{
deltaTangents[index] += new Vector3(tt.x, tt.y, tt.z);
index++;
}
}
}
Me neither… I will double check GLTF Blend Shape Positions vs BABYLON Scene File Blend Shape Positions… But what ever the case, for some reason… its working in both like the screen shots above