/// <summary> /// Convert a BlendShape to MeshBlendShape, used for storing to character card data /// </summary> internal MeshBlendShape ConvertToMeshBlendShape(string smrName, BlendShapeController.BlendShape blendShape) { if (blendShape == null) { return(null); } var meshBlendShape = new MeshBlendShape(smrName, blendShape, blendShape.vertexCount); return(meshBlendShape); }
private static BlendShapeData MergeBlendShapes([NotNull, ItemNotNull] IReadOnlyList <Mesh> meshes) { var vertices = new List <BlendShapeVertex>(); var shapes = new List <MeshBlendShape>(); var channels = new List <MeshBlendShapeChannel>(); var weights = new List <float>(); uint meshVertexIndexStart = 0; var totalFrameCount = 0; uint totalVertexCount = 0; foreach (var mesh in meshes) { var meshShape = mesh.Shape; if (meshShape != null) { var channelFrameCount = 0; foreach (var channel in meshShape.Channels) { var chan = new MeshBlendShapeChannel(); chan.Name = channel.Name; chan.FrameIndex = channel.FrameIndex + totalFrameCount; chan.FrameCount = channel.FrameCount; chan.NameHash = channel.NameHash; channelFrameCount += channel.FrameCount; channels.Add(chan); } totalFrameCount += channelFrameCount; weights.AddRange(meshShape.FullWeights); uint shapeVertexCount = 0; foreach (var s in meshShape.Shapes) { var shape = new MeshBlendShape(); shape.FirstVertex = s.FirstVertex + totalVertexCount; shape.HasNormals = s.HasNormals; shape.HasTangents = s.HasTangents; shape.VertexCount = s.VertexCount; shapeVertexCount += s.VertexCount; shapes.Add(shape); } totalVertexCount += shapeVertexCount; foreach (var v in meshShape.Vertices) { var vertex = new BlendShapeVertex(); vertex.Index = v.Index + meshVertexIndexStart; vertex.Vertex = v.Vertex; vertex.Normal = v.Normal; vertex.Tangent = v.Tangent; vertices.Add(vertex); } } meshVertexIndexStart += (uint)mesh.VertexCount; } return(new BlendShapeData(vertices.ToArray(), shapes.ToArray(), channels.ToArray(), weights.ToArray())); }
/// <summary> /// Loop through each mesh, and if the name/vertexcount matches, append the blendshape /// </summary> /// <param name="smrs">List of skinnedMeshRenderers to check for matching mesh name</param> /// <param name="meshBlendShape">The MeshBlendShape loaded from character card</param> internal void LoopMeshAndAddExistingBlendShape(List <SkinnedMeshRenderer> smrs, MeshBlendShape meshBlendShape, bool isClothingMesh = false) { var meshName = meshBlendShape.MeshName; var vertexCount = meshBlendShape.VertCount; var blendShape = meshBlendShape.BlendShape; foreach (var smr in smrs) { //If mesh matches, append the blend shape if (smr.name == meshName && smr.sharedMesh.vertexCount == vertexCount) { meshWithBlendShapes.Add(smr); //Make sure the blendshape does not already exists if (BlendShapeAlreadyExists(smr, meshBlendShape.BlendShape)) { continue; } //Add the blendshape to the mesh new BlendShapeController(smr, blendShape); // LogMeshBlendShapes(smr); } } }
internal static BlendShapeData ReadBlendShapeData([NotNull] this BinaryReader reader) { var vertexCount = reader.ReadInt32(); var vertices = new BlendShapeVertex[vertexCount]; for (var i = 0; i < vertexCount; ++i) { vertices[i] = ReadBlendShapeVertex(reader); } var shapeCount = reader.ReadInt32(); var shapes = new MeshBlendShape[shapeCount]; for (var i = 0; i < shapeCount; ++i) { shapes[i] = ReadMeshBlendShape(reader); } var channelCount = reader.ReadInt32(); var channels = new MeshBlendShapeChannel[channelCount]; for (var i = 0; i < channelCount; ++i) { channels[i] = ReadMeshBlendShapeChannel(reader); } var weightCount = reader.ReadInt32(); var weights = new float[weightCount]; for (var i = 0; i < weightCount; ++i) { weights[i] = reader.ReadSingle(); } return(new BlendShapeData(vertices, shapes, channels, weights)); BlendShapeVertex ReadBlendShapeVertex(BinaryReader r) { var vertex = new BlendShapeVertex(); vertex.Vertex = r.ReadVector3(); vertex.Normal = r.ReadVector3(); vertex.Tangent = r.ReadVector3(); vertex.Index = r.ReadUInt32(); return(vertex); } MeshBlendShape ReadMeshBlendShape(BinaryReader r) { var shape = new MeshBlendShape(); shape.FirstVertex = r.ReadUInt32(); shape.VertexCount = r.ReadUInt32(); shape.HasNormals = r.ReadBoolean(); shape.HasTangents = r.ReadBoolean(); r.AlignBy(4); return(shape); } MeshBlendShapeChannel ReadMeshBlendShapeChannel(BinaryReader r) { var channel = new MeshBlendShapeChannel(); channel.Name = r.ReadAlignedString(); channel.NameHash = r.ReadUInt32(); channel.FrameIndex = r.ReadInt32(); channel.FrameCount = r.ReadInt32(); return(channel); } }