Advertisement
Guest User

Untitled

a guest
Apr 28th, 2015
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.85 KB | None | 0 0
  1.  
  2.         void SetBones(Matrix4[] mats)
  3.         {
  4.             int bones = 50;
  5.             float[] set = new float[bones * 16];
  6.             for (int i = 0; i < mats.Length; i++)
  7.             {
  8.                 for (int x = 0; x < 4; x++)
  9.                 {
  10.                     for (int y = 0; y < 4; y++)
  11.                     {
  12.                         set[i * 16 + x * 4 + y] = mats[i][x, y];
  13.                     }
  14.                 }
  15.             }
  16.             for (int i = mats.Length; i < bones; i++)
  17.             {
  18.                 for (int x = 0; x < 4; x++)
  19.                 {
  20.                     for (int y = 0; y < 4; y++)
  21.                     {
  22.                         set[i * 16 + x * 4 + y] = Matrix4.Identity[x, y];
  23.                     }
  24.                 }
  25.             }
  26.             GL.UniformMatrix4(6, bones, false, set);
  27.         }
  28.  
  29.         public Matrix4 convert(Matrix4x4 mat)
  30.         {
  31.             return new Matrix4(mat.A1, mat.A2, mat.A3, mat.A4,
  32.                 mat.B1, mat.B2, mat.B3, mat.B4,
  33.                 mat.C1, mat.C2, mat.C3, mat.C4,
  34.                 mat.D1, mat.D2, mat.D3, mat.D4);
  35.         }
  36.  
  37.         int findPos(double time, NodeAnimationChannel nodeAnim)
  38.         {
  39.             for (int i = 0; i < nodeAnim.PositionKeyCount - 1; i++)
  40.             {
  41.                 if (time < nodeAnim.PositionKeys[i + 1].Time)
  42.                 {
  43.                     return i;
  44.                 }
  45.             }
  46.             throw new Exception("findPos: Can't find pos");
  47.         }
  48.  
  49.         Vector3D lerpPos(double aTime, NodeAnimationChannel nodeAnim)
  50.         {
  51.             if (nodeAnim.PositionKeyCount == 0)
  52.             {
  53.                 return new Vector3D(0, 0, 0);
  54.             }
  55.             if (nodeAnim.PositionKeyCount == 1)
  56.             {
  57.                 return nodeAnim.PositionKeys[0].Value;
  58.             }
  59.             int index = findPos(aTime, nodeAnim);
  60.             int nextIndex = index + 1;
  61.             if (nextIndex >= nodeAnim.PositionKeyCount)
  62.             {
  63.                 return new Vector3D(0, 0, 0);
  64.             }
  65.             double deltaT = nodeAnim.PositionKeys[nextIndex].Time - nodeAnim.PositionKeys[index].Time;
  66.             double factor = (aTime - nodeAnim.PositionKeys[index].Time) / deltaT;
  67.             if (factor < 0 || factor > 1)
  68.             {
  69.                 return new Vector3D(0, 0, 0);
  70.             }
  71.             Vector3D start = nodeAnim.PositionKeys[index].Value;
  72.             Vector3D end = nodeAnim.PositionKeys[nextIndex].Value;
  73.             Vector3D deltaV = end - start;
  74.             return start + (float)factor * deltaV;
  75.         }
  76.  
  77.         int findRotate(double time, NodeAnimationChannel nodeAnim)
  78.         {
  79.             for (int i = 0; i < nodeAnim.RotationKeyCount - 1; i++)
  80.             {
  81.                 if (time < nodeAnim.RotationKeys[i + 1].Time)
  82.                 {
  83.                     return i;
  84.                 }
  85.             }
  86.             throw new Exception("findRotate: Can't find rotate");
  87.         }
  88.  
  89.         Assimp.Quaternion lerpRotate(double aTime, NodeAnimationChannel nodeAnim)
  90.         {
  91.             if (nodeAnim.RotationKeyCount == 0)
  92.             {
  93.                 return new Assimp.Quaternion();
  94.             }
  95.             if (nodeAnim.RotationKeyCount == 1)
  96.             {
  97.                 return nodeAnim.RotationKeys[0].Value;
  98.             }
  99.             int index = findRotate(aTime, nodeAnim);
  100.             int nextIndex = index + 1;
  101.             if (nextIndex >= nodeAnim.ScalingKeyCount)
  102.             {
  103.                 return new Assimp.Quaternion();
  104.             }
  105.             double deltaT = nodeAnim.RotationKeys[nextIndex].Time - nodeAnim.RotationKeys[index].Time;
  106.             double factor = (aTime - nodeAnim.RotationKeys[index].Time) / deltaT;
  107.             if (factor < 0 || factor > 1)
  108.             {
  109.                 return new Assimp.Quaternion();
  110.             }
  111.             Assimp.Quaternion start = nodeAnim.RotationKeys[index].Value;
  112.             Assimp.Quaternion end = nodeAnim.RotationKeys[nextIndex].Value;
  113.             Assimp.Quaternion res = Assimp.Quaternion.Slerp(start, end, (float)factor);
  114.             res.Normalize();
  115.             return res;
  116.         }
  117.  
  118.         int findScale(double time, NodeAnimationChannel nodeAnim)
  119.         {
  120.             for (int i = 0; i < nodeAnim.ScalingKeyCount - 1; i++)
  121.             {
  122.                 if (time < nodeAnim.ScalingKeys[i + 1].Time)
  123.                 {
  124.                     return i;
  125.                 }
  126.             }
  127.             throw new Exception("findScale: Can't find scale");
  128.         }
  129.  
  130.         Vector3D lerpScale(double aTime, NodeAnimationChannel nodeAnim)
  131.         {
  132.             if (nodeAnim.ScalingKeyCount == 0)
  133.             {
  134.                 return new Vector3D(1, 1, 1);
  135.             }
  136.             if (nodeAnim.ScalingKeyCount == 1)
  137.             {
  138.                 return nodeAnim.ScalingKeys[0].Value;
  139.             }
  140.             int index = findScale(aTime, nodeAnim);
  141.             int nextIndex = index + 1;
  142.             if (nextIndex >= nodeAnim.ScalingKeyCount)
  143.             {
  144.                 return new Vector3D(1, 1, 1);
  145.             }
  146.             double deltaT = nodeAnim.ScalingKeys[nextIndex].Time - nodeAnim.ScalingKeys[index].Time;
  147.             double factor = (aTime - nodeAnim.ScalingKeys[index].Time) / deltaT;
  148.             if (factor < 0 || factor > 1)
  149.             {
  150.                 return new Vector3D(1, 1, 1);
  151.             }
  152.             Vector3D start = nodeAnim.ScalingKeys[index].Value;
  153.             Vector3D end = nodeAnim.ScalingKeys[nextIndex].Value;
  154.             Vector3D deltaV = end - start;
  155.             Vector3D scale = start + (float)factor * deltaV;
  156.             return scale;
  157.         }
  158.  
  159.         Matrix4 globalInverse = Matrix4.Identity;
  160.  
  161.         public void UpdateTransforms(double aTime, Node pNode, Matrix4 transf)
  162.         {
  163.             try
  164.             {
  165.                 string nodename = pNode.Name;
  166.                 if (OriginalModel.AnimationCount == 0)
  167.                 {
  168.                     return;
  169.                 }
  170.                 Animation pAnim = OriginalModel.Animations[0];
  171.                 Matrix4 nodeTransf = convert(pNode.Transform);
  172.                 NodeAnimationChannel pNodeAnim = FindNodeAnim(pAnim, nodename);
  173.                 if (pNodeAnim != null)
  174.                 {
  175.                     Vector3D scaling = lerpScale(aTime, pNodeAnim);
  176.                     Matrix4 scale = Matrix4.CreateScale(scaling.X, scaling.Y, scaling.Z);
  177.                     Assimp.Quaternion rot = lerpRotate(aTime, pNodeAnim);
  178.                     Matrix4 rotation = convert(new Matrix4x4(rot.GetMatrix()));
  179.                     Vector3D pos = lerpPos(aTime, pNodeAnim);
  180.                     Matrix4 translation = Matrix4.CreateTranslation(pos.X, pos.Y, pos.Z);
  181.                     nodeTransf = translation * rotation * scale;
  182.                 }
  183.                 Matrix4 global = transf * nodeTransf;
  184.                 foreach (ModelMesh mesh in Meshes)
  185.                 {
  186.                     int pos;
  187.                     if (mesh.BoneLookup.TryGetValue(nodename, out pos))
  188.                     {
  189.                         mesh.Bones[pos].Transform = globalInverse * global * convert(mesh.Bones[pos].Internal.OffsetMatrix);
  190.                     }
  191.                 }
  192.                 for (int i = 0; i < pNode.ChildCount; i++)
  193.                 {
  194.                     UpdateTransforms(aTime, pNode.Children[i], global);
  195.                 }
  196.             }
  197.             catch (Exception ex)
  198.             {
  199.                 SysConsole.Output(OutputType.ERROR, ex.ToString());
  200.             }
  201.         }
  202.  
  203.         NodeAnimationChannel FindNodeAnim(Animation pAnim, string nodeName)
  204.         {
  205.             for (int i = 0; i < pAnim.NodeAnimationChannelCount; i++)
  206.             {
  207.                 NodeAnimationChannel nac = pAnim.NodeAnimationChannels[i];
  208.                 if (nac.NodeName == nodeName)
  209.                 {
  210.                     return nac;
  211.                 }
  212.             }
  213.             return null;
  214.         }
  215.  
  216.         /// <summary>
  217.         /// Draws the model.
  218.         /// </summary>
  219.         public void Draw(double aTime)
  220.         {
  221.             for (int i = 0; i < Meshes.Count; i++)
  222.             {
  223.                 if (Meshes[i].Bones.Count > 0)
  224.                 {
  225.                     globalInverse = convert(OriginalModel.RootNode.Transform).Inverted();
  226.                     UpdateTransforms(aTime, OriginalModel.RootNode, Matrix4.Identity);
  227.                     Matrix4[] mats = new Matrix4[Meshes[i].Bones.Count];
  228.                     for (int x = 0; x < Meshes[i].Bones.Count; x++)
  229.                     {
  230.                         mats[x] = Meshes[i].Bones[x].Transform;
  231.                     }
  232.                     SetBones(mats);
  233.                 }
  234.                 Meshes[i].Draw();
  235.                 if (Meshes[i].Bones.Count > 0)
  236.                 {
  237.                     VBO.BonesIdentity();
  238.                 }
  239.             }
  240.         }
  241.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement