Advertisement
Suzukaze

Untitled

Jan 14th, 2025
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.70 KB | None | 0 0
  1.         private void AddSkinnedMesh(Assimp.Node node, GameObject parent, Material[] mats, CombineInstance[] combine)
  2.         {
  3.             SkinnedMeshRenderer meshRenderer = parent.AddComponent<SkinnedMeshRenderer>();
  4.             List<List<Assimp.Bone>> meshBones = new List<List<Assimp.Bone>>();
  5.             Dictionary<int, List<BoneWeight1>> VertexBonesWeights = new Dictionary<int, List<BoneWeight1>>();
  6.             List<Transform[]> bonesArray = new List<Transform[]>();
  7.             List<Matrix4x4[]> bindPoses = new List<Matrix4x4[]>();
  8.             List<Assimp.MeshAnimationAttachment> blendMeshes = new List<Assimp.MeshAnimationAttachment>();
  9.             //Debug.Log(node.Name + " / " + parent.name);
  10.  
  11.             int previousVertexCount = 0;
  12.             for (int iMesh = 0; iMesh < node.MeshIndices.Count; iMesh++)
  13.             {
  14.                 Assimp.Mesh currentMesh = scene.Meshes[node.MeshIndices[iMesh]];
  15.                 meshBones.Add(currentMesh.Bones);
  16.                 bonesArray.Add(new Transform[currentMesh.BoneCount]);
  17.                 bindPoses.Add(new Matrix4x4[currentMesh.BoneCount]);
  18.  
  19.                 for (int iBone = 0; iBone < bonesArray[iMesh].Length; iBone++)
  20.                 {
  21.                     Assimp.Bone currentBones = meshBones[iMesh][iBone];
  22.                     if (!bones.ContainsKey(currentBones.Name))
  23.                     {
  24.                         Debug.Log("missing bone " + currentBones.Name);
  25.                         continue;
  26.                     }
  27.                     bonesArray[iMesh][iBone] = bones[currentBones.Name];
  28.                     bindPoses[iMesh][iBone] = bonesArray[iMesh][iBone].worldToLocalMatrix;
  29.  
  30.                     for (int iVertex = 0; iVertex < currentBones.VertexWeightCount; iVertex++)
  31.                     {
  32.                         int vertexIndex = currentBones.VertexWeights[iVertex].VertexID + previousVertexCount;
  33.                         float weight = currentBones.VertexWeights[iVertex].Weight;
  34.                         BoneWeight1 boneWeight = new BoneWeight1() { boneIndex = iBone, weight = weight };
  35.                         if (!VertexBonesWeights.ContainsKey(vertexIndex)) VertexBonesWeights.Add(vertexIndex, new List<BoneWeight1>());
  36.                         VertexBonesWeights[vertexIndex].Add(boneWeight);
  37.                     }
  38.                 }
  39.                 previousVertexCount += currentMesh.VertexCount;
  40.                 if (currentMesh.HasMeshAnimationAttachments)
  41.                 {
  42.                     for (int i = 0; i < currentMesh.MeshAnimationAttachmentCount; i++)
  43.                     {
  44.                         blendMeshes.Add(currentMesh.MeshAnimationAttachments[i]);
  45.                     }
  46.                 }
  47.             }
  48.  
  49.             List<Assimp.Bone> meshBonesFlat = new List<Assimp.Bone>();
  50.             meshBones.ForEach(x => meshBonesFlat.AddRange(x));
  51.             List<Transform> bonesArrayFlat = new List<Transform>();
  52.             bonesArray.ForEach(x => bonesArrayFlat.AddRange(x));
  53.             List<Matrix4x4> bindPosesFlat = new List<Matrix4x4>();
  54.             bindPoses.ForEach(x => bindPosesFlat.AddRange(x));
  55.             List<BoneWeight> bonesWeightsFlat = new List<BoneWeight>();
  56.             byte[] bonesPerVertes = new byte[VertexBonesWeights.Count];
  57.             List<BoneWeight1> bw = new List<BoneWeight1>();
  58.             for (int i = 0; i < VertexBonesWeights.Count; i++)
  59.             {
  60.                 bonesPerVertes[i] = (byte)VertexBonesWeights[i].Count;
  61.                 VertexBonesWeights[i].Sort((x, y) =>
  62.                 {
  63.                     if (x == null)
  64.                     {
  65.                         if (y == null) return 0;
  66.                         else return -1;
  67.                     }
  68.                     else
  69.                     {
  70.                         if (y == null) return 1;
  71.                         else return -x.weight.CompareTo(y.weight);
  72.                     }
  73.                 });
  74.                 bw.AddRange(VertexBonesWeights[i]);
  75.             }
  76.             Transform root = null;
  77.             for (int i = 0; i < bonesArrayFlat.Count; i++)
  78.             {
  79.                 if (bonesArrayFlat.Contains(bonesArrayFlat[i].parent)) continue;
  80.                 root = bonesArrayFlat[i];
  81.                 break;
  82.             }
  83.  
  84.             meshRenderer.bones = bonesArrayFlat.ToArray();
  85.             meshRenderer.sharedMesh = new Mesh();
  86.             meshRenderer.sharedMesh.bindposes = bindPosesFlat.ToArray();
  87.             meshRenderer.sharedMesh.CombineMeshes(combine, false);
  88.             meshRenderer.sharedMesh.SetBoneWeights(new NativeArray<byte>(bonesPerVertes, Allocator.Temp), new NativeArray<BoneWeight1>(bw.ToArray(), Allocator.Temp));
  89.             meshRenderer.sharedMesh.name = meshes[node.MeshIndices[0]].name;
  90.             meshRenderer.sharedMaterials = mats;
  91.             meshRenderer.rootBone = root;
  92.             if (meshRenderer.sharedMesh.bounds.size.magnitude > meshSize.magnitude)
  93.             {
  94.                 meshCenter = meshRenderer.bounds.center;
  95.                 meshSize = meshRenderer.bounds.size;
  96.                 bodyMesh = meshRenderer;
  97.             }
  98.  
  99.             foreach (Assimp.MeshAnimationAttachment blendShape in blendMeshes)
  100.             {
  101.                 string name = blendShape.Name;
  102.                 float frameWeight = blendShape.Weight;
  103.                 Vector3[] deltaVerts = new Vector3[meshRenderer.sharedMesh.vertexCount];
  104.                 if (blendShape.HasVertices)
  105.                 {
  106.                     Assimp.Vector3D thisVector = new Assimp.Vector3D();
  107.                     Vector3 unityVector = new Vector3();
  108.                     for (int iVert = 0; iVert < blendShape.VertexCount; iVert++)
  109.                     {
  110.                         thisVector = blendShape.Vertices[iVert];
  111.                         unityVector = new Vector3(thisVector.X, thisVector.Y, thisVector.Z);
  112.                         deltaVerts[iVert] = unityVector - meshRenderer.sharedMesh.vertices[iVert];
  113.                     }
  114.                 }
  115.                 Vector3[] deltaNormals = new Vector3[meshRenderer.sharedMesh.normals.Length];
  116.                 if (blendShape.HasNormals)
  117.                 {
  118.                     Assimp.Vector3D thisVector = new Assimp.Vector3D();
  119.                     Vector3 unityVector = new Vector3();
  120.                     for (int iNormals = 0; iNormals < blendShape.Normals.Count; iNormals++)
  121.                     {
  122.                         thisVector = blendShape.Normals[iNormals];
  123.                         unityVector = new Vector3(thisVector.X, thisVector.Y, thisVector.Z);
  124.                         deltaNormals[iNormals] = meshRenderer.sharedMesh.normals[iNormals] - unityVector;
  125.                     }
  126.                 }
  127.                 meshRenderer.sharedMesh.AddBlendShapeFrame(name, frameWeight, deltaVerts, deltaNormals, null);
  128.             }
  129.         }
  130.  
  131.         private void AddSimpleMesh(Assimp.Node node, GameObject parent, Material[] mats, CombineInstance[] combine)
  132.         {
  133.             MeshFilter meshFilter = parent.AddComponent<MeshFilter>();
  134.             MeshRenderer meshRenderer = parent.AddComponent<MeshRenderer>();
  135.  
  136.             meshFilter.mesh = new Mesh();
  137.             meshFilter.mesh.CombineMeshes(combine, false);
  138.             meshFilter.name = meshes[node.MeshIndices[0]].name;
  139.             meshFilter.mesh.name = meshFilter.name;
  140.             meshRenderer.sharedMaterials = mats;
  141.             MeshCollider collider = parent.AddComponent<MeshCollider>();
  142.         }
  143.         Matrix4x4 invers = Matrix4x4.identity;
  144.  
  145.         private IEnumerator ImportHierarchy(Assimp.Node node, Transform parent, GameObject go, Matrix4x4 cumulMatrix, Quaternion preRotation)
  146.         {
  147.             if (parent != null && parent != go.transform)
  148.                 go.transform.parent = parent;
  149.  
  150.             GlobalState.Instance.messageBox.ShowMessage("Importing Hierarchy : " + importCount);
  151.  
  152.             // Do not use Assimp Decompose function, it does not work properly
  153.             // use unity decomposition instead
  154.             Matrix4x4 nodeMatrix = new Matrix4x4(
  155.                 new Vector4(node.Transform.A1, node.Transform.B1, node.Transform.C1, node.Transform.D1),
  156.                 new Vector4(node.Transform.A2, node.Transform.B2, node.Transform.C2, node.Transform.D2),
  157.                 new Vector4(node.Transform.A3, node.Transform.B3, node.Transform.C3, node.Transform.D3),
  158.                 new Vector4(node.Transform.A4, node.Transform.B4, node.Transform.C4, node.Transform.D4)
  159.                 );
  160.  
  161.             Maths.DecomposeMatrix(nodeMatrix, out Vector3 np, out Quaternion nr, out Vector3 ns);
  162.             //Debug.Log(node.Name + " " + np + " " + nr + " " + ns);
  163.  
  164.             int metadataCount = node.Metadata.Count;
  165.  
  166.  
  167.             if ((node.Name.Contains("ctrl") || node.Name.Contains("grp")) && node.Name.Contains("ScalingPivotInverse"))
  168.             {
  169.                 invers = /*invers **/ nodeMatrix;
  170.                 //Debug.Log(node.Name);
  171.             }
  172.  
  173.             cumulMatrix = cumulMatrix * nodeMatrix;
  174.             //if (node.Metadata.TryGetValue("ScalingMax", out Assimp.Metadata.Entry val)) Debug.Log(val.DataAs<Assimp.Vector3D>().Value.X);
  175.  
  176.             if (metadataCount == 0)
  177.             {
  178.                 if (blocking)
  179.                     ImportHierarchy(node.Children[0], parent, go, cumulMatrix, preRotation).MoveNext();
  180.                 else
  181.                     yield return StartCoroutine(ImportHierarchy(node.Children[0], parent, go, cumulMatrix, preRotation));
  182.             }
  183.             else
  184.             {
  185.                 string nodeInfo = node.Name + '\n';
  186.                 foreach (KeyValuePair<string, Assimp.Metadata.Entry> pair in node.Metadata)
  187.                 {
  188.                     nodeInfo += pair.Key + " " + pair.Value.ToString() + " " + pair.Value.GetType() + " " + pair.Value.Data + '\n';
  189.                 }
  190.                 //Debug.Log(nodeInfo);
  191.                 Maths.DecomposeMatrix(cumulMatrix /** invers.inverse*/, out Vector3 cumulPosition, out Quaternion cumulRotation, out Vector3 cumulScale);
  192.                 if (isHuman && node.Name.Contains("grp"))
  193.                 //&& node.Metadata.TryGetValue(" IsNull", out Assimp.Metadata.Entry isNull) && !(bool)isNull.DataAs<bool>())
  194.                 {
  195.                     cumulPosition *= 0.2f;
  196.                 }
  197.                 if (node.Metadata.TryGetValue("IsNull", out Assimp.Metadata.Entry isNull2) && (bool)isNull2.DataAs<bool>())
  198.                 {
  199.                     invers = Matrix4x4.identity;
  200.                     //Debug.Log("isNullBone " + node.Name);
  201.                 }
  202.  
  203.                 AssignMeshes(node, go, invers);
  204.                 if (node.Parent != null)
  205.                 {
  206.                     go.transform.localPosition = cumulPosition; // new Vector3(cumulPosition.x * inversp.x, cumulPosition.y * inversp.y, cumulPosition.z * inversp.z);
  207.                     go.transform.localRotation = cumulRotation;
  208.                     go.transform.localScale = cumulScale;
  209.                     go.name = isHuman ? node.Name : Utils.CreateUniqueName(node.Name);
  210.                     if (isHuman)
  211.                     {
  212.                         if (bones.ContainsKey(node.Name))
  213.                         {
  214.                             bones[node.Name] = go.transform;
  215.                         }
  216.                         if (node.Name.Contains("Root")) rootBone = go.transform;
  217.                         if (rootBone == null && node.Name.Contains("Hips")) rootBone = go.transform;
  218.                     }
  219.                 }
  220.                 if (scene.HasAnimations)
  221.                 {
  222.                     ImportAnimation(node, go, cumulRotation);
  223.                 }
  224.                 nodeMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one);
  225.                 //if (invers != Matrix4x4.identity) nodeMatrix = invers;
  226.                 importCount++;
  227.                 foreach (Assimp.Node assimpChild in node.Children)
  228.                 {
  229.                     GameObject child = new GameObject();
  230.                     child.gameObject.tag = "PhysicObject";
  231.                     if (blocking)
  232.                         ImportHierarchy(assimpChild, go.transform, child, nodeMatrix, Quaternion.identity).MoveNext();
  233.                     else
  234.                         yield return StartCoroutine(ImportHierarchy(assimpChild, go.transform, child, nodeMatrix, Quaternion.identity));
  235.                 }
  236.                 //}
  237.             }
  238.         }
  239.  
  240.         private IEnumerator ImportHierarchy(Assimp.Node node, Transform parent, GameObject go)
  241.         {
  242.             if (parent != null && parent != go.transform)
  243.                 go.transform.parent = parent;
  244.  
  245.             GlobalState.Instance.messageBox.ShowMessage("Importing Hierarchy : " + importCount);
  246.            
  247.             // Do not use Assimp Decompose function, it does not work properly
  248.             // use unity decomposition instead
  249.             Matrix4x4 mat = new Matrix4x4(
  250.                 new Vector4(node.Transform.A1, node.Transform.B1, node.Transform.C1, node.Transform.D1),
  251.                 new Vector4(node.Transform.A2, node.Transform.B2, node.Transform.C2, node.Transform.D2),
  252.                 new Vector4(node.Transform.A3, node.Transform.B3, node.Transform.C3, node.Transform.D3),
  253.                 new Vector4(node.Transform.A4, node.Transform.B4, node.Transform.C4, node.Transform.D4)
  254.                 );
  255.             Vector3 position, scale;
  256.             Quaternion rotation;
  257.             Maths.DecomposeMatrix(mat, out position, out rotation, out scale);
  258.  
  259.             node.Transform.Decompose(out Assimp.Vector3D scale1, out Assimp.Quaternion rot, out Assimp.Vector3D trans);
  260.  
  261.             AssignMeshes(node, go, Matrix4x4.identity);
  262.  
  263.             if (node.Parent != null)
  264.             {
  265.                 go.transform.localPosition = position;
  266.                 go.transform.localRotation = rotation;
  267.                 go.transform.localScale = scale;
  268.                 go.name = isHuman ? node.Name : Utils.CreateUniqueName(node.Name);
  269.                 if (isHuman)
  270.                 {
  271.                     if (bones.ContainsKey(node.Name))
  272.                     {
  273.                         bones[node.Name] = go.transform;
  274.                     }
  275.                     if (node.Name.Contains("Hips")) rootBone = go.transform;
  276.                 }
  277.             }
  278.  
  279.  
  280.             if (scene.HasAnimations)
  281.             {
  282.                 ImportAnimation(node, go, Quaternion.identity);
  283.             }
  284.  
  285.             importCount++;
  286.             foreach (Assimp.Node assimpChild in node.Children)
  287.             {
  288.                 GameObject child = new GameObject();
  289.                 if (blocking)
  290.                     ImportHierarchy(assimpChild, go.transform, child).MoveNext();
  291.                 else
  292.                     yield return StartCoroutine(ImportHierarchy(assimpChild, go.transform, child));
  293.             }
  294.         }
  295.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement