Browse Source

Add AnimationImporters & tainicom.Aether.Animation

* AnimationsProcessor.cs - Import animations from a Model.
* GpuAnimatedModelProcessor - Import an animated Model.
* CpuAnimatedModelProcessor - Import an animated Model to be animated by
the CPU. Based on DynamicModelProcessor, the imported asset is of type
Microsoft.Xna.Framework.Graphics.Model where the VertexBuffer is
replaced by a CpuAnimatedVertexBuffer. CpuAnimatedVertexBuffer inherits
from DynamicVertexBuffer.

Add tainicom.Aether.Animation

Play animated 3D models and support for CPU animation.
CPU animation is optimized using unsafe code, writing directly to mapped
VertexBuffer memory using reflection (DirectX) and unmanaged/C++ code
(WP8.0).
Nikos Kastellanos 8 years ago
parent
commit
24202d8958
85 changed files with 4145 additions and 0 deletions
  1. 13 0
      Aether.Extras.PORTABLE.sln
  2. 40 0
      Aether.Extras.W10.sln
  3. 22 0
      Aether.Extras.W8_1.sln
  4. 13 0
      Aether.Extras.WINDOWS.MG.sln
  5. 13 0
      Aether.Extras.WINDOWS.XNA.sln
  6. 20 0
      Aether.Extras.WP7_1.sln
  7. 38 0
      Aether.Extras.WP8.sln
  8. 58 0
      Animation/Aether.Animation.PORTABLE.csproj
  9. 164 0
      Animation/Aether.Animation.W10.csproj
  10. 16 0
      Animation/Aether.Animation.W10.project.json
  11. 81 0
      Animation/Aether.Animation.W8_1.csproj
  12. 78 0
      Animation/Aether.Animation.WINDOWS.MG.csproj
  13. 84 0
      Animation/Aether.Animation.WINDOWS.XNA.csproj
  14. 91 0
      Animation/Aether.Animation.WP7_1.csproj
  15. 153 0
      Animation/Aether.Animation.WP8.csproj
  16. 163 0
      Animation/Animation/Animations.cs
  17. 32 0
      Animation/Animation/Clip.cs
  18. 150 0
      Animation/Animation/CpuAnimatedVertexBuffer.Unsafe.cs
  19. 108 0
      Animation/Animation/CpuAnimatedVertexBuffer.cs
  20. 38 0
      Animation/Animation/Extensions.cs
  21. 54 0
      Animation/Animation/Keyframe.cs
  22. 74 0
      Animation/Animation/NativeExtensions.cs
  23. 132 0
      Animation/ContentReaders/AnimationsReader.cs
  24. 83 0
      Animation/ContentReaders/ClipReader.cs
  25. 112 0
      Animation/ContentReaders/CpuAnimatedVertexBufferReader.cs
  26. 66 0
      Animation/Graphics/VertexTypes/VertexIndicesWeightsPositionNormal.cs
  27. 33 0
      Animation/Properties/Aether.Animation.rd.xml
  28. 24 0
      Animation/Properties/AssemblyInfo.PORTABLE.cs
  29. 26 0
      Animation/Properties/AssemblyInfo.W10.cs
  30. 38 0
      Animation/Properties/AssemblyInfo.WP8.cs
  31. 41 0
      Animation/Properties/AssemblyInfo.cs
  32. 57 0
      Animation/README.md
  33. 4 0
      Animation/packages.config
  34. 38 0
      Content.Pipeline/AnimationImporters/Animation/AnimationsContent.cs
  35. 32 0
      Content.Pipeline/AnimationImporters/Animation/ClipContent.cs
  36. 30 0
      Content.Pipeline/AnimationImporters/Animation/CpuAnimatedVertexBufferContent.cs
  37. 35 0
      Content.Pipeline/AnimationImporters/Animation/KeyframeContent.cs
  38. 77 0
      Content.Pipeline/AnimationImporters/AnimationImporters.PORTABLE.csproj
  39. 80 0
      Content.Pipeline/AnimationImporters/AnimationImporters.WINDOWS.MG.csproj
  40. 79 0
      Content.Pipeline/AnimationImporters/AnimationImporters.WINDOWS.XNA.csproj
  41. 444 0
      Content.Pipeline/AnimationImporters/Processors/AnimationsProcessor.cs
  42. 134 0
      Content.Pipeline/AnimationImporters/Processors/CpuAnimatedModelProcessor.cs
  43. 87 0
      Content.Pipeline/AnimationImporters/Processors/GpuAnimatedModelProcessor.cs
  44. 33 0
      Content.Pipeline/AnimationImporters/Properties/AssemblyInfo.MG.cs
  45. 30 0
      Content.Pipeline/AnimationImporters/Properties/AssemblyInfo.cs
  46. 94 0
      Content.Pipeline/AnimationImporters/Serialization/AnimationsWriter.cs
  47. 78 0
      Content.Pipeline/AnimationImporters/Serialization/ClipWriter.cs
  48. 48 0
      Content.Pipeline/AnimationImporters/Serialization/CpuAnimatedVertexBufferWriter.cs
  49. 5 0
      Content.Pipeline/AnimationImporters/packages.config
  50. 199 0
      Native.Animation/Aether.Native.Animation.WP8.vcxproj
  51. 114 0
      Native.Animation/Animation/CpuAnimatedVertexBufferHelper.cpp
  52. 52 0
      Native.Animation/Animation/CpuAnimatedVertexBufferHelper.h
  53. 38 0
      Native.Animation/Data/Int4Data.h
  54. 40 0
      Native.Animation/Data/Matrix.h
  55. 37 0
      Native.Animation/Data/Vector2Data.h
  56. 37 0
      Native.Animation/Data/Vector3Data.h
  57. 37 0
      Native.Animation/Data/Vector4Data.h
  58. 45 0
      Native.Animation/Graphics/VertexTypes/VertexIndicesWeightsPositionNormal.h
  59. 41 0
      Native.Animation/VertexPositionNormalTextureData.h
  60. 6 0
      Native.Animation/pch.cpp
  61. 13 0
      Native.Animation/pch.h
  62. 8 0
      README.md
  63. BIN
      bin/Release/Portable/Aether.Animation.dll
  64. BIN
      bin/Release/Portable/Aether.Content.Pipeline.AnimationImporters.dll
  65. BIN
      bin/Release/W10/Aether.Animation.dll
  66. BIN
      bin/Release/W10/Aether.Animation.pri
  67. 33 0
      bin/Release/W10/Aether.Animation/Properties/Aether.Animation.rd.xml
  68. BIN
      bin/Release/W8_1/Aether.Animation.dll
  69. BIN
      bin/Release/W8_1/Aether.Animation.pri
  70. BIN
      bin/Release/WP7_1/Aether.Animation.dll
  71. BIN
      bin/Release/WP8/ARM/Aether.Animation.dll
  72. BIN
      bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.dll
  73. BIN
      bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.exp
  74. BIN
      bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.lib
  75. BIN
      bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.winmd
  76. BIN
      bin/Release/WP8/x86/Aether.Animation.dll
  77. BIN
      bin/Release/WP8/x86/tainicom.Aether.Native.Animation.dll
  78. BIN
      bin/Release/WP8/x86/tainicom.Aether.Native.Animation.exp
  79. BIN
      bin/Release/WP8/x86/tainicom.Aether.Native.Animation.lib
  80. BIN
      bin/Release/WP8/x86/tainicom.Aether.Native.Animation.winmd
  81. BIN
      bin/Release/Windows.XNA/Aether.Animation.dll
  82. BIN
      bin/Release/Windows.XNA/Aether.Content.Pipeline.AnimationImporters.dll
  83. BIN
      bin/Release/Windows/Aether.Animation.dll
  84. BIN
      bin/Release/Windows/Aether.Content.Pipeline.AnimationImporters.dll
  85. 2 0
      packages/repositories.config

+ 13 - 0
Aether.Extras.PORTABLE.sln

@@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphicsImporters.PORTABLE"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Graphics.PORTABLE", "Graphics\Aether.Graphics.PORTABLE.csproj", "{3E3BB349-662A-4628-B033-154CB8CD2F2A}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.PORTABLE", "Animation\Aether.Animation.PORTABLE.csproj", "{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnimationImporters.PORTABLE", "Content.Pipeline\AnimationImporters\AnimationImporters.PORTABLE.csproj", "{962D579A-91F7-4FAB-940A-423E04B8465E}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -29,6 +33,14 @@ Global
 		{3E3BB349-662A-4628-B033-154CB8CD2F2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{3E3BB349-662A-4628-B033-154CB8CD2F2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3E3BB349-662A-4628-B033-154CB8CD2F2A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}.Release|Any CPU.Build.0 = Release|Any CPU
+		{962D579A-91F7-4FAB-940A-423E04B8465E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{962D579A-91F7-4FAB-940A-423E04B8465E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{962D579A-91F7-4FAB-940A-423E04B8465E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{962D579A-91F7-4FAB-940A-423E04B8465E}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -36,5 +48,6 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{C3218A39-5491-44BF-B820-754832E318DB} = {717F89BC-8423-4E7C-A834-460CFD62B1E3}
 		{0A079394-D331-433A-94DF-AA25B6522279} = {717F89BC-8423-4E7C-A834-460CFD62B1E3}
+		{962D579A-91F7-4FAB-940A-423E04B8465E} = {717F89BC-8423-4E7C-A834-460CFD62B1E3}
 	EndGlobalSection
 EndGlobal

+ 40 - 0
Aether.Extras.W10.sln

@@ -0,0 +1,40 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.W10", "Animation\Aether.Animation.W10.csproj", "{A312F64C-A5D4-4B28-A250-3A75CD5C4952}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|ARM = Debug|ARM
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|ARM = Release|ARM
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|ARM.ActiveCfg = Debug|ARM
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|ARM.Build.0 = Debug|ARM
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|x64.ActiveCfg = Debug|x64
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|x64.Build.0 = Debug|x64
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|x86.ActiveCfg = Debug|x86
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Debug|x86.Build.0 = Debug|x86
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|ARM.ActiveCfg = Release|ARM
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|ARM.Build.0 = Release|ARM
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|x64.ActiveCfg = Release|x64
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|x64.Build.0 = Release|x64
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|x86.ActiveCfg = Release|x86
+		{A312F64C-A5D4-4B28-A250-3A75CD5C4952}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 22 - 0
Aether.Extras.W8_1.sln

@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.W8_1", "Animation\Aether.Animation.W8_1.csproj", "{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 13 - 0
Aether.Extras.WINDOWS.MG.sln

@@ -13,6 +13,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphicsImporters.WINDOWS.M
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Graphics.WINDOWS.MG", "Graphics\Aether.Graphics.WINDOWS.MG.csproj", "{0A4ED2DF-9CDD-4C98-83AA-1898A394AC27}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnimationImporters.WINDOWS.MG", "Content.Pipeline\AnimationImporters\AnimationImporters.WINDOWS.MG.csproj", "{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.WINDOWS.MG", "Animation\Aether.Animation.WINDOWS.MG.csproj", "{F08D6D4C-60FB-4543-8D81-594080EB8051}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -35,6 +39,14 @@ Global
 		{0A4ED2DF-9CDD-4C98-83AA-1898A394AC27}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0A4ED2DF-9CDD-4C98-83AA-1898A394AC27}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{0A4ED2DF-9CDD-4C98-83AA-1898A394AC27}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F08D6D4C-60FB-4543-8D81-594080EB8051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F08D6D4C-60FB-4543-8D81-594080EB8051}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F08D6D4C-60FB-4543-8D81-594080EB8051}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F08D6D4C-60FB-4543-8D81-594080EB8051}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -43,5 +55,6 @@ Global
 		{26C387C6-7313-47D4-A05F-14639AB02D70} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{48E4029A-115C-4DC2-AF3A-0AB94F36BFC0} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 		{400DC7B2-739D-4156-916D-2F2E1920310D} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
+		{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3} = {A921886B-C6F7-4FF8-8668-EC20004C464A}
 	EndGlobalSection
 EndGlobal

+ 13 - 0
Aether.Extras.WINDOWS.XNA.sln

@@ -7,6 +7,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Graphics.WINDOWS.XNA
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aether.Content.Pipeline", "Aether.Content.Pipeline", "{F6B6E505-6037-49E4-9060-8B29A7B99BC1}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnimationImporters.WINDOWS.XNA", "Content.Pipeline\AnimationImporters\AnimationImporters.WINDOWS.XNA.csproj", "{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.WINDOWS.XNA", "Animation\Aether.Animation.WINDOWS.XNA.csproj", "{1BD2DBC0-D366-42F7-9369-F566CCD01C03}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -21,11 +25,20 @@ Global
 		{838D803F-F140-4763-A378-56DC27EDD5F3}.Debug|x86.Build.0 = Debug|x86
 		{838D803F-F140-4763-A378-56DC27EDD5F3}.Release|x86.ActiveCfg = Release|x86
 		{838D803F-F140-4763-A378-56DC27EDD5F3}.Release|x86.Build.0 = Release|x86
+		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}.Debug|x86.ActiveCfg = Debug|x86
+		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}.Debug|x86.Build.0 = Debug|x86
+		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}.Release|x86.ActiveCfg = Release|x86
+		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}.Release|x86.Build.0 = Release|x86
+		{1BD2DBC0-D366-42F7-9369-F566CCD01C03}.Debug|x86.ActiveCfg = Debug|x86
+		{1BD2DBC0-D366-42F7-9369-F566CCD01C03}.Debug|x86.Build.0 = Debug|x86
+		{1BD2DBC0-D366-42F7-9369-F566CCD01C03}.Release|x86.ActiveCfg = Release|x86
+		{1BD2DBC0-D366-42F7-9369-F566CCD01C03}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{565ACF47-7E36-435E-8727-2AFB39E61134} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
+		{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E} = {F6B6E505-6037-49E4-9060-8B29A7B99BC1}
 	EndGlobalSection
 EndGlobal

+ 20 - 0
Aether.Extras.WP7_1.sln

@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.WP7_1", "Animation\Aether.Animation.WP7_1.csproj", "{08932BB0-C3E4-489B-9A45-1649730A9CDB}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Windows Phone = Debug|Windows Phone
+		Release|Windows Phone = Release|Windows Phone
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{08932BB0-C3E4-489B-9A45-1649730A9CDB}.Debug|Windows Phone.ActiveCfg = Debug|Windows Phone
+		{08932BB0-C3E4-489B-9A45-1649730A9CDB}.Debug|Windows Phone.Build.0 = Debug|Windows Phone
+		{08932BB0-C3E4-489B-9A45-1649730A9CDB}.Release|Windows Phone.ActiveCfg = Release|Windows Phone
+		{08932BB0-C3E4-489B-9A45-1649730A9CDB}.Release|Windows Phone.Build.0 = Release|Windows Phone
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 38 - 0
Aether.Extras.WP8.sln

@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aether.Animation.WP8", "Animation\Aether.Animation.WP8.csproj", "{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Aether.Native.Animation", "Native.Animation\Aether.Native.Animation.WP8.vcxproj", "{22C72DC0-022D-4D1B-B738-C764F67421EA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|x86 = Debug|x86
+		Release|ARM = Release|ARM
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Debug|ARM.ActiveCfg = Debug|ARM
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Debug|ARM.Build.0 = Debug|ARM
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Debug|x86.ActiveCfg = Debug|x86
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Debug|x86.Build.0 = Debug|x86
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Release|ARM.ActiveCfg = Release|ARM
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Release|ARM.Build.0 = Release|ARM
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Release|x86.ActiveCfg = Release|x86
+		{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}.Release|x86.Build.0 = Release|x86
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Debug|ARM.ActiveCfg = Debug|ARM
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Debug|ARM.Build.0 = Debug|ARM
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Debug|x86.ActiveCfg = Debug|Win32
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Debug|x86.Build.0 = Debug|Win32
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Release|ARM.ActiveCfg = Release|ARM
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Release|ARM.Build.0 = Release|ARM
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Release|x86.ActiveCfg = Release|Win32
+		{22C72DC0-022D-4D1B-B738-C764F67421EA}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 58 - 0
Animation/Aether.Animation.PORTABLE.csproj

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{11DC5896-8B7A-43ED-978C-45D0ECD4DD42}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <TargetFrameworkProfile>Profile328</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Portable\</OutputPath>
+    <DefineConstants>DEBUG;PORTABLE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Portable\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <DefineConstants>PORTABLE</DefineConstants>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.PORTABLE.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+</Project>

+ 164 - 0
Animation/Aether.Animation.W10.csproj

@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{A312F64C-A5D4-4B28-A250-3A75CD5C4952}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
+    <TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
+    <TargetPlatformMinVersion>10.0.10586.0</TargetPlatformMinVersion>
+    <MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\W10\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;W10 MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\W10\</OutputPath>
+    <DefineConstants>TRACE;W10 MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
+    <PlatformTarget>ARM</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\bin\Debug\W10\ARM\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;W10 MAPPEDMEM</DefineConstants>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>full</DebugType>
+    <PlatformTarget>ARM</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
+    <PlatformTarget>ARM</PlatformTarget>
+    <OutputPath>..\bin\Release\W10\ARM\</OutputPath>
+    <DefineConstants>TRACE;W10 MAPPEDMEM</DefineConstants>
+    <Optimize>true</Optimize>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>none</DebugType>
+    <PlatformTarget>ARM</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\bin\Debug\W10\x64\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;W10 MAPPEDMEM</DefineConstants>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>..\bin\Release\W10\x64\</OutputPath>
+    <DefineConstants>TRACE;W10 MAPPEDMEM</DefineConstants>
+    <Optimize>true</Optimize>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>none</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\bin\Debug\W10\x86\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;W10 MAPPEDMEM</DefineConstants>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <PlatformTarget>x86</PlatformTarget>
+    <OutputPath>..\bin\Release\W10\x86\</OutputPath>
+    <DefineConstants>TRACE;W10 MAPPEDMEM</DefineConstants>
+    <Optimize>true</Optimize>
+    <NoWarn>;2008</NoWarn>
+    <DebugType>none</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <ErrorReport>prompt</ErrorReport>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <GenerateLibraryLayout>true</GenerateLibraryLayout>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.Unsafe.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.W10.cs" />
+    <Content Include="Properties\Aether.Animation.rd.xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Aether.Animation.W10.project.json" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX">
+      <HintPath>$(MSBuildExtensionsPath)\..\MonoGame\v3.0\Assemblies\WindowsUniversal\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11">
+      <HintPath>$(MSBuildExtensionsPath)\..\MonoGame\v3.0\Assemblies\WindowsUniversal\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
+    <VisualStudioVersion>14.0</VisualStudioVersion>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 16 - 0
Animation/Aether.Animation.W10.project.json

@@ -0,0 +1,16 @@
+{
+  "dependencies": {
+    "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
+  },
+  "frameworks": {
+    "uap10.0": {}
+  },
+  "runtimes": {
+    "win10-arm": {},
+    "win10-arm-aot": {},
+    "win10-x86": {},
+    "win10-x86-aot": {},
+    "win10-x64": {},
+    "win10-x64-aot": {}
+  }
+}

+ 81 - 0
Animation/Aether.Animation.W8_1.csproj

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{AEE9C708-BDBD-4E8B-B85F-2DB9FA717436}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <TargetPlatformVersion>8.1</TargetPlatformVersion>
+    <MinimumVisualStudioVersion>12</MinimumVisualStudioVersion>
+    <TargetFrameworkVersion />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\W8_1\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;W8_1 MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\W8_1\</OutputPath>
+    <DefineConstants>TRACE;W8_1 MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.Unsafe.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>$(MSBuildExtensionsPath)\..\MonoGame\v3.0\Assemblies\Windows8\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>$(MSBuildExtensionsPath)\..\MonoGame\v3.0\Assemblies\Windows8\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
+    <VisualStudioVersion>12.0</VisualStudioVersion>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 78 - 0
Animation/Aether.Animation.WINDOWS.MG.csproj

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{F08D6D4C-60FB-4543-8D81-594080EB8051}</ProjectGuid>
+    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Windows\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Windows\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG MAPPEDMEM</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\Windows\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\Windows\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="mscorlib" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.Unsafe.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 84 - 0
Animation/Aether.Animation.WINDOWS.XNA.csproj

@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{1BD2DBC0-D366-42F7-9369-F566CCD01C03}</ProjectGuid>
+    <ProjectTypeGuids>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows</XnaPlatform>
+    <XnaProfile>Reach</XnaProfile>
+    <XnaCrossPlatformGroupID>55ac98f1-c123-4838-ac90-fb4285b12686</XnaCrossPlatformGroupID>
+    <XnaOutputType>Library</XnaOutputType>
+    <!--
+    <XnaRefreshLevel>1</XnaRefreshLevel>
+    -->
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>false</XnaCompressContent>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\Windows.XNA\</OutputPath>
+    <DefineConstants>WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaCompressContent>true</XnaCompressContent>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.Unsafe.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
+  <!--
+      To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 91 - 0
Animation/Aether.Animation.WP7_1.csproj

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{08932BB0-C3E4-489B-9A45-1649730A9CDB}</ProjectGuid>
+    <ProjectTypeGuids>{6D335F3A-9D43-41b4-9D22-F6F17C4BE596};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">Windows Phone</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <XnaPlatform>Windows Phone</XnaPlatform>
+    <XnaProfile>Reach</XnaProfile>
+    <XnaCrossPlatformGroupID>55ac98f1-c123-4838-ac90-fb4285b12686</XnaCrossPlatformGroupID>
+    <XnaOutputType>Library</XnaOutputType>
+    <XapFilename Condition="$(XnaOutputType)=='Game'">$(AssemblyName).xap</XapFilename>
+    <SilverlightManifestTemplate Condition="$(XnaOutputType)=='Game'">Properties\AppManifest.xml</SilverlightManifestTemplate>
+    <XnaWindowsPhoneManifestTemplate Condition="$(XnaOutputType)=='Game'">Properties\WMAppManifest.xml</XnaWindowsPhoneManifestTemplate>
+    <TileImage Condition="$(XnaOutputType)=='Game'">Background.png</TileImage>
+    <TileTitle Condition="$(XnaOutputType)=='Game'">TileTitle</TileTitle>
+    <XnaRefreshLevel>1</XnaRefreshLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Windows Phone' ">
+    <OutputPath>..\bin\Debug\WP7_1\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <DefineConstants>TRACE;DEBUG;WP7_1</DefineConstants>
+    <XnaCompressContent>false</XnaCompressContent>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Windows Phone' ">
+    <OutputPath>..\bin\Release\WP7_1\</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <NoStdLib>true</NoStdLib>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <DefineConstants>TRACE;WP7</DefineConstants>
+    <XnaCompressContent>false</XnaCompressContent>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Phone, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e, processorArchitecture=MSIL" />
+    <Reference Include="Microsoft.Xna.Framework">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="Microsoft.Xna.Framework.Graphics">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="mscorlib">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Core">
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.targets" />
+  <!--
+      To modify your build process, add your task inside one of the targets below and uncomment it. 
+      Other similar extension points exist, see Microsoft.Common.targets.
+      <Target Name="BeforeBuild">
+      </Target>
+      <Target Name="AfterBuild">
+      </Target>
+    -->
+</Project>

+ 153 - 0
Animation/Aether.Animation.WP8.csproj

@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.20506</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{8029B300-3608-4C01-BEF5-3F7BC3F9E58E}</ProjectGuid>
+    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Animation</RootNamespace>
+    <AssemblyName>Aether.Animation</AssemblyName>
+    <TargetFrameworkIdentifier>WindowsPhone</TargetFrameworkIdentifier>
+    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\WP8\x86\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;PHONE;WP8 MAPPEDMEM USE_NATIVE_ANIMATION</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\WP8\x86\</OutputPath>
+    <DefineConstants>TRACE;PHONE;WP8 MAPPEDMEM USE_NATIVE_ANIMATION</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\bin\Debug\WP8\ARM\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WP8 MAPPEDMEM USE_NATIVE_ANIMATION</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|ARM' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\WP8\ARM\</OutputPath>
+    <DefineConstants>TRACE;WP8 MAPPEDMEM USE_NATIVE_ANIMATION</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowedReferenceRelatedFileExtensions>
+      <!-- Prevent default XML and PDB files copied to output in RELEASE. 
+           Only *.allowedextension files will be included, which doesn't exist in my case.
+       -->
+      .allowedextension
+    </AllowedReferenceRelatedFileExtensions>
+    <DocumentationFile>
+    </DocumentationFile>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Animation\Animations.cs" />
+    <Compile Include="Animation\Clip.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBuffer.Unsafe.cs" />
+    <Compile Include="Animation\Extensions.cs" />
+    <Compile Include="Animation\Keyframe.cs" />
+    <Compile Include="Animation\NativeExtensions.cs" />
+    <Compile Include="ContentReaders\AnimationsReader.cs" />
+    <Compile Include="ContentReaders\ClipReader.cs" />
+    <Compile Include="ContentReaders\CpuAnimatedVertexBufferReader.cs" />
+    <Compile Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework" Condition=" '$(Platform)' == 'ARM' ">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="MonoGame.Framework, Version=3.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX" Condition=" '$(Platform)' == 'x86' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\x86\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX" Condition=" '$(Platform)' == 'ARM' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\ARM\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX" Condition=" '$(Platform)' == 'AnyCPU' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\x86\SharpDX.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11" Condition=" '$(Platform)' == 'x86' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\x86\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11" Condition=" '$(Platform)' == 'ARM' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\ARM\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="SharpDX.Direct3D11" Condition=" '$(Platform)' == 'AnyCPU' ">
+      <HintPath>C:\Program Files (x86)\MonoGame\v3.0\Assemblies\WindowsPhone\x86\SharpDX.Direct3D11.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Native.Animation\Aether.Native.Animation.WP8.vcxproj">
+      <Project>{22c72dc0-022d-4d1b-b738-c764f67421ea}</Project>
+      <Name>tainicom.Aether.Native.Animation</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
+  <ProjectExtensions />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <Target Name="MonoGame_RemoveXnaAssemblies" AfterTargets="ImplicitlyExpandTargetFramework">
+    <Message Text="MonoGame - Removing XNA Assembly references!" Importance="normal" />
+    <ItemGroup>
+      <ReferencePath Remove="@(ReferencePath)" Condition="'%(Filename)%(Extension)'=='Microsoft.Xna.Framework.dll'" />
+      <ReferencePath Remove="@(ReferencePath)" Condition="'%(Filename)%(Extension)'=='Microsoft.Xna.Framework.GamerServices.dll'" />
+      <ReferencePath Remove="@(ReferencePath)" Condition="'%(Filename)%(Extension)'=='Microsoft.Xna.Framework.GamerServicesExtensions.dll'" />
+      <ReferencePath Remove="@(ReferencePath)" Condition="'%(Filename)%(Extension)'=='Microsoft.Xna.Framework.Input.Touch.dll'" />
+      <ReferencePath Remove="@(ReferencePath)" Condition="'%(Filename)%(Extension)'=='Microsoft.Xna.Framework.MediaLibraryExtensions.dll'" />
+    </ItemGroup>
+  </Target>
+</Project>

+ 163 - 0
Animation/Animation/Animations.cs

@@ -0,0 +1,163 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+
+namespace tainicom.Aether.Animation
+{    
+    public class Animations
+    {
+        internal List<Matrix> _bindPose;
+        internal List<Matrix> _invBindPose; // TODO: convert those from List<T> to simple T[] arrays.
+        internal List<int> _skeletonHierarchy;
+
+        private Matrix[] _boneTransforms;
+        private Matrix[] _worldTransforms;
+        private Matrix[] _animationTransforms;
+
+        private int _currentKeyframe;
+
+
+        public Dictionary<string, Clip> Clips { get; private set; }
+        public Clip CurrentClip { get; private set; }
+        public TimeSpan CurrentTime { get; private set; }
+
+        /// <summary>
+        /// The current bone transform matrices, relative to their parent bones.
+        /// </summary>
+        public Matrix[] BoneTransforms { get { return _boneTransforms; } }
+
+        /// <summary>
+        /// The current bone transform matrices, in absolute format.
+        /// </summary>
+        public Matrix[] WorldTransforms { get { return _worldTransforms; } }
+
+        /// <summary>
+        /// The current bone transform matrices, relative to the animation bind pose.
+        /// </summary>
+        public Matrix[] AnimationTransforms { get { return _animationTransforms; } }
+
+
+        internal Animations(List<Matrix> bindPose, List<Matrix> invBindPose, List<int> skeletonHierarchy, Dictionary<string, Clip> clips)
+        {
+            _bindPose = bindPose;
+            _invBindPose = invBindPose;
+            _skeletonHierarchy = skeletonHierarchy;
+            Clips = clips;
+            
+            // initialize
+            _boneTransforms = new Matrix[_bindPose.Count];
+            _worldTransforms = new Matrix[_bindPose.Count];
+            _animationTransforms = new Matrix[_bindPose.Count];
+        }
+
+        public void SetClip(string clipName)
+        {
+            var clip = Clips["Base Stack"];
+            SetClip(clip);
+        }
+
+        public void SetClip(Clip clip)
+        {
+            if (clip == null)
+                throw new ArgumentNullException("clip");
+
+            CurrentClip = clip;
+            CurrentTime = TimeSpan.Zero;
+            _currentKeyframe = 0;
+
+            // Initialize bone transforms to the bind pose.
+            _bindPose.CopyTo(_boneTransforms, 0);
+        }
+        
+        public void Update(TimeSpan time, bool relativeToCurrentTime, Matrix rootTransform)
+        {
+            UpdateBoneTransforms(time, relativeToCurrentTime);
+            UpdateWorldTransforms(rootTransform);
+            UpdateAnimationTransforms();
+        }
+
+        public void UpdateBoneTransforms(TimeSpan time, bool relativeToCurrentTime)
+        {
+            // Update the animation position.
+            if (relativeToCurrentTime)
+            {
+                time += CurrentTime;
+
+                // If we reached the end, loop back to the start.
+                while (time >= CurrentClip.Duration)
+                    time -= CurrentClip.Duration;
+            }
+
+            if (time < TimeSpan.Zero)
+                throw new ArgumentOutOfRangeException("time out of range");
+            if (time > CurrentClip.Duration)
+                //throw new ArgumentOutOfRangeException("time out of range");
+                time = CurrentClip.Duration;
+
+            // If the position moved backwards, reset the keyframe index.
+            if (time < CurrentTime)
+            {
+                _currentKeyframe = 0;
+                _bindPose.CopyTo(_boneTransforms, 0);
+            }
+
+            CurrentTime = time;
+
+            // Read keyframe matrices.
+            IList<Keyframe> keyframes = CurrentClip.Keyframes;
+
+            while (_currentKeyframe < keyframes.Count)
+            {
+                Keyframe keyframe = keyframes[_currentKeyframe];
+
+                // Stop when we've read up to the current time position.
+                if (keyframe.Time > CurrentTime)
+                    break;
+
+                // Use this keyframe.
+                _boneTransforms[keyframe.Bone] = keyframe.Transform;
+
+                _currentKeyframe++;
+            }
+        }
+
+        public void UpdateWorldTransforms(Matrix rootTransform)
+        {
+            // Root bone.
+            Matrix.Multiply(ref _boneTransforms[0], ref rootTransform, out _worldTransforms[0]);
+
+            // Child bones.
+            for (int bone = 1; bone < _worldTransforms.Length; bone++)
+            {
+                int parentBone = _skeletonHierarchy[bone];
+
+                Matrix.Multiply(ref _boneTransforms[bone], ref _worldTransforms[parentBone], out _worldTransforms[bone]);
+            }
+        }
+
+        public void UpdateAnimationTransforms()
+        {
+            for (int bone = 0; bone < _animationTransforms.Length; bone++)
+            {
+                Matrix _tmpInvBindPose = _invBindPose[bone]; //can not pass it as 'ref'
+                Matrix.Multiply(ref _tmpInvBindPose, ref _worldTransforms[bone], out _animationTransforms[bone]);
+            }
+        }
+    }
+}

+ 32 - 0
Animation/Animation/Clip.cs

@@ -0,0 +1,32 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+
+namespace tainicom.Aether.Animation
+{
+    public class Clip
+    {
+        public TimeSpan Duration { get; internal set; }
+        public Keyframe[] Keyframes { get; private set; }
+
+        internal Clip(TimeSpan duration, Keyframe[] keyframes)
+        {
+            Duration = duration;
+            Keyframes = keyframes;
+        }
+    }
+}

+ 150 - 0
Animation/Animation/CpuAnimatedVertexBuffer.Unsafe.cs

@@ -0,0 +1,150 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Graphics;
+#if MAPPEDMEM
+using System;
+using System.Reflection;
+using SharpDX.Direct3D11;
+#endif
+
+
+namespace tainicom.Aether.Animation
+{
+    public class CpuAnimatedVertexBuffer: DynamicVertexBuffer
+    {
+        #if USE_NATIVE_ANIMATION
+        Native.Animation.CpuAnimatedVertexBufferHelper _cpuVertexBufferHelper;
+        #else
+        private VertexIndicesWeightsPositionNormal[] _cpuVertices;
+        #endif
+
+        private VertexPositionNormalTexture[] _gpuVertices;
+        
+        #if MAPPEDMEM
+        SharpDX.Direct3D11.Buffer _buffer;
+        #endif
+
+        public CpuAnimatedVertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage) :
+            base(graphicsDevice, vertexDeclaration, vertexCount, bufferUsage)
+        {            
+            #if MAPPEDMEM
+            #if W8_1
+            FieldInfo _bufferInfo = typeof(VertexBuffer).GetTypeInfo().GetDeclaredField("_buffer");
+            #else
+            FieldInfo _bufferInfo = typeof(VertexBuffer).GetField("_buffer", BindingFlags.Instance | BindingFlags.NonPublic);
+            #endif
+            _buffer = _bufferInfo.GetValue(this) as SharpDX.Direct3D11.Buffer;
+            #endif
+
+            return;
+        }
+
+        internal void SetGpuVertices(VertexPositionNormalTexture[] vertices)
+        {
+            _gpuVertices = vertices;
+        }
+
+        internal void SetCpuVertices(VertexIndicesWeightsPositionNormal[] vertices)
+        {
+            #if USE_NATIVE_ANIMATION
+            var nativeCpuVertices = new Native.Animation.VertexTypes.VertexIndicesWeightsPositionNormal[vertices.Length];
+            for (int i = 0; i < vertices.Length; i++)
+                nativeCpuVertices[i] = vertices[i].ToNativeCpuVertex();
+            _cpuVertexBufferHelper = new Native.Animation.CpuAnimatedVertexBufferHelper();
+            _cpuVertexBufferHelper.SetCpuVertices(nativeCpuVertices);
+            #else            
+            _cpuVertices = vertices;
+            #endif
+        }
+
+        internal unsafe void UpdateVertices(Matrix[] boneTransforms, int startIndex, int elementCount)
+        {
+            #if MAPPEDMEM
+            var context = _buffer.Device.ImmediateContext;
+            var dataBox = context.MapSubresource(_buffer, 0, MapMode.WriteNoOverwrite, MapFlags.None);
+            var pgpuVertices = (VertexPositionNormalTexture*)dataBox.DataPointer.ToPointer();
+            InnerUpdateVertices(pgpuVertices, boneTransforms, startIndex, elementCount);
+            context.UnmapSubresource(_buffer, 0);
+            #else
+            fixed (VertexPositionNormalTexture* pgpuVertices = _gpuVertices)
+                InnerUpdateVertices(pgpuVertices, boneTransforms, startIndex, elementCount);
+            int vertexStride = VertexPositionNormalTexture.VertexDeclaration.VertexStride;
+            int offsetInBytes = startIndex * vertexStride;
+            SetData(offsetInBytes, _gpuVertices, startIndex, elementCount, vertexStride, SetDataOptions.NoOverwrite);
+#endif
+        }
+
+        private unsafe void InnerUpdateVertices(VertexPositionNormalTexture* pgpuVertices, Matrix[] boneTransforms, int startIndex, int elementCount)
+        {
+            fixed (Matrix* pBoneTransforms = boneTransforms)
+            {   
+                #if USE_NATIVE_ANIMATION
+                _cpuVertexBufferHelper.UpdateVertices((long)pBoneTransforms, (long)pgpuVertices, startIndex, elementCount);
+#else
+                fixed (VertexIndicesWeightsPositionNormal* pcpuVertices = _cpuVertices)
+                {
+                    Matrix transformSum = Matrix.Identity;
+                    var pVertex = pcpuVertices + startIndex;
+                    var pGpuVertex = pgpuVertices + startIndex;
+
+                    // skin all of the vertices
+                    for (int i = 0; i < elementCount; i++, pVertex++, pGpuVertex++)
+                    {
+                        int b0 = pVertex->BlendIndex0;
+                        int b1 = pVertex->BlendIndex1;
+                        int b2 = pVertex->BlendIndex2;
+                        int b3 = pVertex->BlendIndex3;
+
+                        float w1 = pVertex->BlendWeights.X;
+                        float w2 = pVertex->BlendWeights.Y;
+                        float w3 = pVertex->BlendWeights.Z;
+                        float w4 = pVertex->BlendWeights.W;
+
+                        Matrix* m1 = pBoneTransforms + b0;
+                        Matrix* m2 = pBoneTransforms + b1;
+                        Matrix* m3 = pBoneTransforms + b2;
+                        Matrix* m4 = pBoneTransforms + b3;
+                        transformSum.M11 = (m1->M11 * w1) + (m2->M11 * w2) + (m3->M11 * w3) + (m4->M11 * w4);
+                        transformSum.M12 = (m1->M12 * w1) + (m2->M12 * w2) + (m3->M12 * w3) + (m4->M12 * w4);
+                        transformSum.M13 = (m1->M13 * w1) + (m2->M13 * w2) + (m3->M13 * w3) + (m4->M13 * w4);
+                        transformSum.M21 = (m1->M21 * w1) + (m2->M21 * w2) + (m3->M21 * w3) + (m4->M21 * w4);
+                        transformSum.M22 = (m1->M22 * w1) + (m2->M22 * w2) + (m3->M22 * w3) + (m4->M22 * w4);
+                        transformSum.M23 = (m1->M23 * w1) + (m2->M23 * w2) + (m3->M23 * w3) + (m4->M23 * w4);
+                        transformSum.M31 = (m1->M31 * w1) + (m2->M31 * w2) + (m3->M31 * w3) + (m4->M31 * w4);
+                        transformSum.M32 = (m1->M32 * w1) + (m2->M32 * w2) + (m3->M32 * w3) + (m4->M32 * w4);
+                        transformSum.M33 = (m1->M33 * w1) + (m2->M33 * w2) + (m3->M33 * w3) + (m4->M33 * w4);
+                        transformSum.M41 = (m1->M41 * w1) + (m2->M41 * w2) + (m3->M41 * w3) + (m4->M41 * w4);
+                        transformSum.M42 = (m1->M42 * w1) + (m2->M42 * w2) + (m3->M42 * w3) + (m4->M42 * w4);
+                        transformSum.M43 = (m1->M43 * w1) + (m2->M43 * w2) + (m3->M43 * w3) + (m4->M43 * w4);
+
+
+                        pGpuVertex->Position.X = pVertex->Position.X * transformSum.M11 + pVertex->Position.Y * transformSum.M21 + pVertex->Position.Z * transformSum.M31 + transformSum.M41;
+                        pGpuVertex->Position.Y = pVertex->Position.X * transformSum.M12 + pVertex->Position.Y * transformSum.M22 + pVertex->Position.Z * transformSum.M32 + transformSum.M42;
+                        pGpuVertex->Position.Z = pVertex->Position.X * transformSum.M13 + pVertex->Position.Y * transformSum.M23 + pVertex->Position.Z * transformSum.M33 + transformSum.M43;
+
+                        pGpuVertex->Normal.X = pVertex->Normal.X * transformSum.M11 + pVertex->Normal.Y * transformSum.M21 + pVertex->Normal.Z * transformSum.M31;
+                        pGpuVertex->Normal.Y = pVertex->Normal.X * transformSum.M12 + pVertex->Normal.Y * transformSum.M22 + pVertex->Normal.Z * transformSum.M32;
+                        pGpuVertex->Normal.Z = pVertex->Normal.X * transformSum.M13 + pVertex->Normal.Y * transformSum.M23 + pVertex->Normal.Z * transformSum.M33;
+                    }
+                }                
+                #endif
+            }
+        }
+    }
+}

+ 108 - 0
Animation/Animation/CpuAnimatedVertexBuffer.cs

@@ -0,0 +1,108 @@
+#region License
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Graphics;
+
+namespace tainicom.Aether.Animation
+{
+    public class CpuAnimatedVertexBuffer: DynamicVertexBuffer
+    {
+        private VertexIndicesWeightsPositionNormal[] cpuVertices;
+        private VertexPositionNormalTexture[] gpuVertices;
+        
+        public CpuAnimatedVertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage) :
+            base(graphicsDevice, vertexDeclaration, vertexCount, bufferUsage)
+        {
+            return;
+        }
+
+        internal void SetGpuVertices(VertexPositionNormalTexture[] vertices)
+        {
+            this.gpuVertices = vertices;
+        }
+
+        internal void SetCpuVertices(VertexIndicesWeightsPositionNormal[] vertices)
+        {
+            this.cpuVertices = vertices;
+        }
+
+        internal void UpdateVertices(Matrix[] boneTransforms, int startIndex, int elementCount)
+        {
+            Matrix transformSum = Matrix.Identity;
+
+            // skin all of the vertices
+            for (int i = startIndex; i < (startIndex + elementCount); i++)
+            {
+                int b0 = cpuVertices[i].BlendIndex0;
+                int b1 = cpuVertices[i].BlendIndex1;
+                int b2 = cpuVertices[i].BlendIndex2;
+                int b3 = cpuVertices[i].BlendIndex3;
+
+                float w1 = cpuVertices[i].BlendWeights.X;
+                float w2 = cpuVertices[i].BlendWeights.Y;
+                float w3 = cpuVertices[i].BlendWeights.Z;
+                float w4 = cpuVertices[i].BlendWeights.W;
+
+            #if (WP7_1)
+                // Moblunatic claims ~40% faster.
+                // http://forums.create.msdn.com/forums/p/55123/335148.aspx
+                // This is true on WP7 with SIMD enabled. 
+                // On WP8/Monogame it is *TWO* times slower than the original code.                
+                
+                Matrix mm1, mm2, mm3, mm4;
+                Matrix.Multiply(ref boneTransforms[b0], w1, out mm1);
+                Matrix.Multiply(ref boneTransforms[b1], w2, out mm2);
+                Matrix.Multiply(ref boneTransforms[b2], w3, out mm3);
+                Matrix.Multiply(ref boneTransforms[b3], w4, out mm4);
+
+                Matrix.Add(ref mm1, ref mm2, out transformSum);
+                Matrix.Add(ref transformSum, ref mm3, out transformSum);
+                Matrix.Add(ref transformSum, ref mm4, out transformSum);
+                transformSum.M14 = 0.0f;
+                transformSum.M24 = 0.0f;
+                transformSum.M34 = 0.0f;
+                transformSum.M44 = 1.0f;
+            #else
+                Matrix m1 = boneTransforms[b0];
+                Matrix m2 = boneTransforms[b1];
+                Matrix m3 = boneTransforms[b2];
+                Matrix m4 = boneTransforms[b3];
+                transformSum.M11 = (m1.M11 * w1) + (m2.M11 * w2) + (m3.M11 * w3) + (m4.M11 * w4);
+                transformSum.M12 = (m1.M12 * w1) + (m2.M12 * w2) + (m3.M12 * w3) + (m4.M12 * w4);
+                transformSum.M13 = (m1.M13 * w1) + (m2.M13 * w2) + (m3.M13 * w3) + (m4.M13 * w4);
+                transformSum.M21 = (m1.M21 * w1) + (m2.M21 * w2) + (m3.M21 * w3) + (m4.M21 * w4);
+                transformSum.M22 = (m1.M22 * w1) + (m2.M22 * w2) + (m3.M22 * w3) + (m4.M22 * w4);
+                transformSum.M23 = (m1.M23 * w1) + (m2.M23 * w2) + (m3.M23 * w3) + (m4.M23 * w4);
+                transformSum.M31 = (m1.M31 * w1) + (m2.M31 * w2) + (m3.M31 * w3) + (m4.M31 * w4);
+                transformSum.M32 = (m1.M32 * w1) + (m2.M32 * w2) + (m3.M32 * w3) + (m4.M32 * w4);
+                transformSum.M33 = (m1.M33 * w1) + (m2.M33 * w2) + (m3.M33 * w3) + (m4.M33 * w4);
+                transformSum.M41 = (m1.M41 * w1) + (m2.M41 * w2) + (m3.M41 * w3) + (m4.M41 * w4);
+                transformSum.M42 = (m1.M42 * w1) + (m2.M42 * w2) + (m3.M42 * w3) + (m4.M42 * w4);
+                transformSum.M43 = (m1.M43 * w1) + (m2.M43 * w2) + (m3.M43 * w3) + (m4.M43 * w4);
+            #endif
+
+                // Support the 4 Bone Influences - Position then Normal
+                Vector3.Transform(ref cpuVertices[i].Position, ref transformSum, out gpuVertices[i].Position);
+                Vector3.TransformNormal(ref cpuVertices[i].Normal, ref transformSum, out gpuVertices[i].Normal);
+            }
+
+            // put the vertices into our vertex buffer
+            SetData(gpuVertices, 0, VertexCount, SetDataOptions.NoOverwrite);
+        }
+    }
+}

+ 38 - 0
Animation/Animation/Extensions.cs

@@ -0,0 +1,38 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Graphics;
+
+namespace tainicom.Aether.Animation
+{
+    public static class Extensions
+    {
+        public static Animations GetAnimations(this Model model)
+        {
+            var animations = model.Tag as Animations;
+            return animations;
+        }
+
+        public static void UpdateVertices(this ModelMeshPart meshPart, Matrix[] boneTransforms)
+        {
+            var animatedVertexBuffer = meshPart.VertexBuffer as CpuAnimatedVertexBuffer;
+            animatedVertexBuffer.UpdateVertices(boneTransforms, meshPart.VertexOffset, meshPart.NumVertices);
+        }
+        
+    }
+}

+ 54 - 0
Animation/Animation/Keyframe.cs

@@ -0,0 +1,54 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+
+namespace tainicom.Aether.Animation
+{
+    public struct Keyframe
+    {
+        internal int _bone;
+        internal TimeSpan _time;
+        internal Matrix _transform;
+        
+        public int Bone 
+        { 
+            get {return _bone;}
+            internal set { _bone = value; }
+        }
+
+        public TimeSpan Time
+        {
+            get { return _time; }
+            internal set { _time = value; }
+        }
+
+        public Matrix Transform
+        {
+            get { return _transform; }
+            internal set { _transform = value; }
+        }
+        
+        public Keyframe(int bone, TimeSpan time, Matrix transform)
+        {
+            this._bone = bone;
+            this._time = time;
+            this._transform = transform;
+        }	
+    }
+}

+ 74 - 0
Animation/Animation/NativeExtensions.cs

@@ -0,0 +1,74 @@
+#region License
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework;
+using tainicom.Aether.Graphics;
+
+namespace tainicom.Aether.Animation
+{
+    internal static class NativeExtensions
+    {        
+        #if USE_NATIVE_ANIMATION
+
+        internal static Native.Animation.VertexTypes.VertexIndicesWeightsPositionNormal ToNativeCpuVertex(this VertexIndicesWeightsPositionNormal source)
+        {
+            Native.Animation.VertexTypes.VertexIndicesWeightsPositionNormal result;
+            //result.BlendIndices = source.BlendIndices.ToInt4Data();
+            result.BlendIndices = new Native.Animation.Data.Int4Data()
+            {
+                X = source.BlendIndex0,
+                Y = source.BlendIndex1,
+                Z = source.BlendIndex2,
+                W = source.BlendIndex3,
+            };
+            result.BlendWeights = source.BlendWeights.ToNativeVector4Data();
+            result.Position = source.Position.ToNativeVector3Data();
+            result.Normal = source.Normal.ToNativeVector3Data();
+
+            return result;
+        }
+        
+        internal static Native.Animation.Data.Vector4Data ToNativeVector4Data(this Vector4 source)
+        {
+            Native.Animation.Data.Vector4Data result;
+            result.X = source.X;
+            result.Y = source.Y;
+            result.Z = source.Z;
+            result.W = source.W;
+            return result;
+        }
+
+        internal static Native.Animation.Data.Vector3Data ToNativeVector3Data(this Vector3 source)
+        {
+            Native.Animation.Data.Vector3Data result;
+            result.X = source.X;
+            result.Y = source.Y;
+            result.Z = source.Z;
+            return result;
+        }
+
+        internal static Native.Animation.Data.Vector2Data ToNativeVector2Data(this Vector2 source)
+        {
+            Native.Animation.Data.Vector2Data result;
+            result.X = source.X;
+            result.Y = source.Y;
+            return result;
+        }
+
+        #endif
+    }
+}
+

+ 132 - 0
Animation/ContentReaders/AnimationsReader.cs

@@ -0,0 +1,132 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+
+namespace tainicom.Aether.Animation.Content
+{
+    public class AnimationsReader : ContentTypeReader<Animations>
+    {
+        protected override Animations Read(ContentReader input, Animations existingInstance)
+        {
+            Animations animations = existingInstance;
+
+            if (existingInstance == null)
+            {
+                Dictionary<string, Clip> clips = ReadAnimationClips(input, null);
+                List<Matrix> bindPose = ReadBindPose(input, null);
+                List<Matrix> invBindPose = ReadInvBindPose(input, null);
+                List<int> skeletonHierarchy = ReadSkeletonHierarchy(input, null);
+                animations = new Animations(bindPose, invBindPose, skeletonHierarchy, clips);
+            }
+            else
+            {
+                ReadAnimationClips(input, animations.Clips);
+                ReadBindPose(input, animations._bindPose);
+                ReadInvBindPose(input, animations._invBindPose);
+                ReadSkeletonHierarchy(input, animations._skeletonHierarchy);
+            }
+
+            return animations;
+        }
+
+        private Dictionary<string, Clip> ReadAnimationClips(ContentReader input, Dictionary<string, Clip> existingInstance)
+        {
+            Dictionary<string, Clip> animationClips = existingInstance;
+
+            int count = input.ReadInt32();
+            if (animationClips == null)
+                animationClips = new Dictionary<string, Clip>(count);
+
+            for (int i = 0; i < count; i++)
+            {
+                string key = input.ReadString();
+                Clip val = input.ReadObject<Clip>();
+                if (existingInstance == null)
+                    animationClips.Add(key, val);
+                else
+                    animationClips[key] = val;
+            }
+
+            return animationClips;
+        }
+
+        private List<Matrix> ReadBindPose(ContentReader input, List<Matrix> existingInstance)
+        {
+            List<Matrix> bindPose = existingInstance;
+
+            int count = input.ReadInt32();
+            if (bindPose == null)
+                bindPose = new List<Matrix>(count);
+
+            for (int i = 0; i < count; i++)
+            {
+                Matrix val = input.ReadMatrix();
+                if (existingInstance == null)
+                    bindPose.Add(val);
+                else
+                    bindPose[i] = val;
+            }
+
+            return bindPose;
+        }
+
+        private List<Matrix> ReadInvBindPose(ContentReader input, List<Matrix> existingInstance)
+        {
+            List<Matrix> invBindPose = existingInstance;
+
+            int count = input.ReadInt32();
+            if (invBindPose == null)
+                invBindPose = new List<Matrix>(count);
+
+            for (int i = 0; i < count; i++)
+            {
+                Matrix val = input.ReadMatrix();
+                if (existingInstance == null)
+                    invBindPose.Add(val);
+                else
+                    invBindPose[i] = val;
+            }
+
+            return invBindPose;
+        }
+
+        private List<int> ReadSkeletonHierarchy(ContentReader input, List<int> existingInstance)
+        {
+            List<int> skeletonHierarchy = existingInstance;
+
+            int count = input.ReadInt32();
+            if (skeletonHierarchy == null)
+                skeletonHierarchy = new List<int>(count);
+
+            for (int i = 0; i < count; i++)
+            {
+                Int32 val = input.ReadInt32();
+                if (existingInstance == null)
+                    skeletonHierarchy.Add(val);
+                else
+                    skeletonHierarchy[i] = val;
+            }
+
+            return skeletonHierarchy;
+        }
+        
+    }
+    
+}

+ 83 - 0
Animation/ContentReaders/ClipReader.cs

@@ -0,0 +1,83 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework.Content;
+
+namespace tainicom.Aether.Animation.Content
+{
+    public class ClipReader : ContentTypeReader<Clip>
+    {
+        protected override Clip Read(ContentReader input, Clip existingInstance)
+        {
+            Clip animationClip = existingInstance;
+
+            if (existingInstance == null)
+            {
+                TimeSpan duration = ReadDuration(input);
+                Keyframe[] keyframes = ReadKeyframes(input, null);
+                animationClip = new Clip(duration, keyframes);
+            }
+            else
+            {
+                animationClip.Duration = ReadDuration(input);
+                ReadKeyframes(input, animationClip.Keyframes);
+            }
+
+            return animationClip;                       
+        }
+        
+        private TimeSpan ReadDuration(ContentReader input)
+        {
+            return new TimeSpan(input.ReadInt64());
+        }
+
+        private Keyframe[] ReadKeyframes(ContentReader input, Keyframe[] existingInstance)
+        {
+            Keyframe[] keyframes = existingInstance;
+
+            int count = input.ReadInt32();
+            if (keyframes == null)
+                keyframes = new Keyframe[count];
+            
+            for (int i = 0; i < count; i++)
+            {
+                keyframes[i]._bone = input.ReadInt32();
+                keyframes[i]._time = new TimeSpan(input.ReadInt64());
+                keyframes[i]._transform.M11 = input.ReadSingle();
+                keyframes[i]._transform.M12 = input.ReadSingle();
+                keyframes[i]._transform.M13 = input.ReadSingle();
+                keyframes[i]._transform.M14 = 0;
+                keyframes[i]._transform.M21 = input.ReadSingle();
+                keyframes[i]._transform.M22 = input.ReadSingle();
+                keyframes[i]._transform.M23 = input.ReadSingle();
+                keyframes[i]._transform.M24 = 0;
+                keyframes[i]._transform.M31 = input.ReadSingle();
+                keyframes[i]._transform.M32 = input.ReadSingle();
+                keyframes[i]._transform.M33 = input.ReadSingle();
+                keyframes[i]._transform.M34 = 0;
+                keyframes[i]._transform.M41 = input.ReadSingle();
+                keyframes[i]._transform.M42 = input.ReadSingle();
+                keyframes[i]._transform.M43 = input.ReadSingle();
+                keyframes[i]._transform.M44 = 1;
+            }
+
+            return keyframes;
+        }
+        
+    }
+    
+}

+ 112 - 0
Animation/ContentReaders/CpuAnimatedVertexBufferReader.cs

@@ -0,0 +1,112 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Graphics.PackedVector;
+using tainicom.Aether.Graphics;
+
+namespace tainicom.Aether.Animation.Content
+{
+    public class CpuAnimatedVertexBufferReader : ContentTypeReader<CpuAnimatedVertexBuffer>
+    {
+        protected override CpuAnimatedVertexBuffer Read(ContentReader input, CpuAnimatedVertexBuffer buffer)
+        {
+            IGraphicsDeviceService graphicsDeviceService = (IGraphicsDeviceService)input.ContentManager.ServiceProvider.GetService(typeof(IGraphicsDeviceService));
+            var device = graphicsDeviceService.GraphicsDevice;
+
+            // read standard VertexBuffer
+            var declaration = input.ReadRawObject<VertexDeclaration>();
+            var vertexCount = (int)input.ReadUInt32();
+            // int dataSize = vertexCount * declaration.VertexStride;
+            //byte[] data = new byte[dataSize];
+            //input.Read(data, 0, dataSize);
+
+            //read data                      
+            var channels = declaration.GetVertexElements();
+            var cpuVertices = new VertexIndicesWeightsPositionNormal[vertexCount];
+            var gpuVertices = new VertexPositionNormalTexture[vertexCount];
+
+            for (int i = 0; i < vertexCount; i++)
+            {
+                foreach (var channel in channels)
+                {
+                    switch (channel.VertexElementUsage)
+                    {
+                        case VertexElementUsage.Position:
+                            System.Diagnostics.Debug.Assert(channel.VertexElementFormat == VertexElementFormat.Vector3);
+                            var pos = input.ReadVector3();
+                            cpuVertices[i].Position = pos;
+                            gpuVertices[i].Position = pos;
+                            break;
+
+                        case VertexElementUsage.Normal:
+                            System.Diagnostics.Debug.Assert(channel.VertexElementFormat == VertexElementFormat.Vector3);
+                            var nor = input.ReadVector3();
+                            cpuVertices[i].Normal = nor;
+                            gpuVertices[i].Normal = nor;
+                            break;
+
+                        case VertexElementUsage.TextureCoordinate:
+                            System.Diagnostics.Debug.Assert(channel.VertexElementFormat == VertexElementFormat.Vector2);
+                            var tex = input.ReadVector2();
+                            gpuVertices[i].TextureCoordinate = tex;
+                            break;
+
+                        case VertexElementUsage.BlendWeight:
+                            System.Diagnostics.Debug.Assert(channel.VertexElementFormat == VertexElementFormat.Vector4);
+                            var wei = input.ReadVector4();
+                            cpuVertices[i].BlendWeights = wei;
+                            break;
+
+                        case VertexElementUsage.BlendIndices:
+                            System.Diagnostics.Debug.Assert(channel.VertexElementFormat == VertexElementFormat.Byte4);
+                            var i0 = input.ReadByte();
+                            var i1 = input.ReadByte();
+                            var i2 = input.ReadByte();
+                            var i3 = input.ReadByte();
+                            cpuVertices[i].BlendIndex0 = i0;
+                            cpuVertices[i].BlendIndex1 = i1;
+                            cpuVertices[i].BlendIndex2 = i2;
+                            cpuVertices[i].BlendIndex3 = i3;
+                            break;
+
+                        default:
+                            throw new Exception();
+                    }
+                }
+            }
+            
+
+            // read extras
+            bool IsWriteOnly = input.ReadBoolean();
+
+            if (buffer == null)
+            {
+                BufferUsage usage = (IsWriteOnly) ? BufferUsage.WriteOnly : BufferUsage.None;
+                buffer = new CpuAnimatedVertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, vertexCount, usage);
+            }
+
+            buffer.SetData(gpuVertices, 0, vertexCount);
+            buffer.SetGpuVertices(gpuVertices);
+            buffer.SetCpuVertices(cpuVertices);
+
+            return buffer;
+        }
+    }
+}

+ 66 - 0
Animation/Graphics/VertexTypes/VertexIndicesWeightsPositionNormal.cs

@@ -0,0 +1,66 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.Runtime.InteropServices;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Graphics
+{
+    [StructLayout(LayoutKind.Explicit)]
+    public struct VertexIndicesWeightsPositionNormal : IVertexType
+    {        
+        [FieldOffset( 0)] public byte BlendIndex0;
+        [FieldOffset( 1)] public byte BlendIndex1;        
+        [FieldOffset( 2)] public byte BlendIndex2;                
+        [FieldOffset( 3)] public byte BlendIndex3;
+        [FieldOffset( 4)] public Vector4 BlendWeights;
+        [FieldOffset(20)] public Vector3 Position;
+        [FieldOffset(32)] public Vector3 Normal;
+
+        
+        #region IVertexType Members
+        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration(
+                new VertexElement[] 
+                {                  
+                    new VertexElement( 0, VertexElementFormat.Byte4, VertexElementUsage.BlendIndices, 0),
+                    new VertexElement( 4, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0),
+                    new VertexElement(20, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
+                    new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
+                });
+
+        VertexDeclaration IVertexType.VertexDeclaration { get { return VertexDeclaration; } }
+        #endregion
+        
+
+        public VertexIndicesWeightsPositionNormal(Vector3 position, Vector3 normal, Vector4 blendWeights, byte blendIndex0, byte blendIndex1, byte blendIndex2, byte blendIndex3)
+        {
+            this.BlendIndex0 = blendIndex0;
+            this.BlendIndex1 = blendIndex1;
+            this.BlendIndex2 = blendIndex2;
+            this.BlendIndex3 = blendIndex3;
+            this.BlendWeights = blendWeights;
+            this.Position = position;
+            this.Normal = normal;
+        }
+
+        public override string ToString()
+        {
+            return string.Format("{{Position:{0} Normal:{1} BlendWeights:{2} BlendIndices:{3},{4},{5},{6} }}",
+                new object[] { Position, Normal, BlendWeights, BlendIndex0, BlendIndex1, BlendIndex2, BlendIndex3 });
+        }
+    }
+}

+ 33 - 0
Animation/Properties/Aether.Animation.rd.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    This file contains Runtime Directives, specifications about types your application accesses
+    through reflection and other dynamic code patterns. Runtime Directives are used to control the
+    .NET Native optimizer and ensure that it does not remove code accessed by your library. If your
+    library does not do any reflection, then you generally do not need to edit this file. However,
+    if your library reflects over types, especially types passed to it or derived from its types,
+    then you should write Runtime Directives.
+
+    The most common use of reflection in libraries is to discover information about types passed
+    to the library. Runtime Directives have three ways to express requirements on types passed to
+    your library.
+
+    1.  Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
+        Use these directives to reflect over types passed as a parameter.
+
+    2.  SubTypes
+        Use a SubTypes directive to reflect over types derived from another type.
+
+    3.  AttributeImplies
+        Use an AttributeImplies directive to indicate that your library needs to reflect over
+        types or methods decorated with an attribute.
+
+    For more information on writing Runtime Directives for libraries, please visit
+    http://go.microsoft.com/fwlink/?LinkID=391919
+-->
+<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
+  <Library Name="Aether.Animation">
+
+  	<!-- add directives for your library here -->
+
+  </Library>
+</Directives>

+ 24 - 0
Animation/Properties/AssemblyInfo.PORTABLE.cs

@@ -0,0 +1,24 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle ("Aether.Animation")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("Aether.Animation")]
+[assembly: AssemblyCopyright ("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 26 - 0
Animation/Properties/AssemblyInfo.W10.cs

@@ -0,0 +1,26 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Animation")]
+[assembly: AssemblyProduct("Aether.Animation")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]

+ 38 - 0
Animation/Properties/AssemblyInfo.WP8.cs

@@ -0,0 +1,38 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Resources;
+
+[assembly: AssemblyTitle("Aether.Animation")]
+[assembly: AssemblyProduct("Aether.Animation")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type. Only Windows
+// assemblies support COM.
+[assembly: ComVisible(false)]
+
+// On Windows, the following GUID is for the ID of the typelib if this
+// project is exposed to COM. On other platforms, it unique identifies the
+// title storage container when deploying this assembly to the device.
+[assembly: Guid("089a2665-02e6-4cf3-8571-30c768fe35f9")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: NeutralResourcesLanguageAttribute("en-US")]

+ 41 - 0
Animation/Properties/AssemblyInfo.cs

@@ -0,0 +1,41 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Animation")]
+[assembly: AssemblyProduct("Aether.Animation")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type. Only Windows
+// assemblies support COM.
+[assembly: ComVisible(false)]
+
+// On Windows, the following GUID is for the ID of the typelib if this
+// project is exposed to COM. On other platforms, it unique identifies the
+// title storage container when deploying this assembly to the device.
+[assembly: Guid("089a2665-02e6-4cf3-8571-30c768fe35f9")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+#if WP7_1
+// Enable NEON/SIMD
+[assembly: CodeGeneration(CodeGenerationFlags.EnableFPIntrinsicsUsingSIMD)]
+#endif

+ 57 - 0
Animation/README.md

@@ -0,0 +1,57 @@
+
+# tainicom.Aether.Animation.*
+
+Play animated 3D models and support for CPU animation.
+CPU animation is optimized using unsafe code, writing directly to mapped VertexBuffer memory using reflection (DirectX) and unmanaged/C++ code (WP8.0). 
+
+## Importers
+
+* 'Animation' - Import animations from a Model.
+* 'GPU AnimatedModel' - Import an animated Model.
+* 'CPU AnimatedModel' - Import an animated Model to be animated by the CPU. Based on DynamicModelProcessor, the imported asset is of type Microsoft.Xna.Framework.Graphics.Model where the VertexBuffer is replaced by a CpuAnimatedVertexBuffer. CpuAnimatedVertexBuffer inherits from DynamicVertexBuffer.
+
+## Example
+
+-Import 3D model with GPU AnimatedModel or GPU AnimatedModel Processor. Use SkinnedEffect for GPU and BasicEffect for CPU based animation.
+
+-Load as any 3D Model:
+
+	_model = Content.Load<Model>("animatedModel");
+
+-Load the Animations from model:
+
+	_animations = _model.GetAnimations();
+	var clip = _animations.Clips["ClipName"];
+        _animations.SetClip(clip);
+
+-Update animation on every frame:
+
+        _animations.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
+
+-Draw GPU animation:
+
+	foreach (ModelMesh mesh in _model.Meshes)
+	{
+		foreach (var meshPart in mesh.MeshParts)
+		{
+			meshPart.effect.SetBoneTransforms(_animations.AnimationTransforms);
+			// set effect parameters, lights, etc          
+		}
+		mesh.Draw();
+	}
+
+-Draw CPU animation:
+
+	foreach (ModelMesh mesh in _model.Meshes)
+	{
+		foreach (var meshPart in mesh.MeshParts)
+		{
+		       meshPart.UpdateVertices(animationPlayer.AnimationTransforms);
+		       // set effect parameters, lights, etc
+		}
+		mesh.Draw();
+	}
+
+
+
+

+ 4 - 0
Animation/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MonoGame.Framework.Portable" version="3.2.99.1-Beta" targetFramework="portable-net45+win+wp80+MonoAndroid10+xamarinios10+MonoTouch10" />
+</packages>

+ 38 - 0
Content.Pipeline/AnimationImporters/Animation/AnimationsContent.cs

@@ -0,0 +1,38 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+
+namespace tainicom.Aether.Content.Pipeline.Animation
+{
+    public class AnimationsContent
+    {
+        public List<Matrix> BindPose { get; private set; }
+        public List<Matrix> InvBindPose { get; private set; }
+        public List<int> SkeletonHierarchy { get; private set; }
+        public Dictionary<string, ClipContent> Clips { get; private set; }
+
+
+        internal AnimationsContent(List<Matrix> bindPose, List<Matrix> invBindPose, List<int> skeletonHierarchy, Dictionary<string, ClipContent> clips)
+        {
+            BindPose = bindPose;
+            InvBindPose = invBindPose;
+            SkeletonHierarchy = skeletonHierarchy;
+            Clips = clips;
+        }
+    }
+}

+ 32 - 0
Content.Pipeline/AnimationImporters/Animation/ClipContent.cs

@@ -0,0 +1,32 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+
+namespace tainicom.Aether.Content.Pipeline.Animation
+{
+    public class ClipContent
+    {
+        public TimeSpan Duration { get; internal set; }
+        public KeyframeContent[] Keyframes { get; private set; }
+
+        internal ClipContent(TimeSpan duration, KeyframeContent[] keyframes)
+        {
+            Duration = duration;
+            Keyframes = keyframes;
+        }
+    }
+}

+ 30 - 0
Content.Pipeline/AnimationImporters/Animation/CpuAnimatedVertexBufferContent.cs

@@ -0,0 +1,30 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using Microsoft.Xna.Framework.Content.Pipeline.Processors;
+using tainicom.Aether.Content.Pipeline.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Animation
+{
+    public class CpuAnimatedVertexBufferContent : DynamicVertexBufferContent
+    {
+        public CpuAnimatedVertexBufferContent(VertexBufferContent source) : base(source)
+        {
+        }
+
+
+    }
+}

+ 35 - 0
Content.Pipeline/AnimationImporters/Animation/KeyframeContent.cs

@@ -0,0 +1,35 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework;
+
+namespace tainicom.Aether.Content.Pipeline.Animation
+{
+    public struct KeyframeContent
+    {
+        public int Bone;
+        public TimeSpan Time;
+        public Matrix Transform;
+
+        public KeyframeContent(int bone, TimeSpan time, Matrix transform)
+        {
+            this.Bone = bone;
+            this.Time = time;
+            this.Transform = transform;
+        }	
+    }
+}

+ 77 - 0
Content.Pipeline/AnimationImporters/AnimationImporters.PORTABLE.csproj

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{962D579A-91F7-4FAB-940A-423E04B8465E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Content.Pipeline</RootNamespace>
+    <AssemblyName>Aether.Content.Pipeline.AnimationImporters</AssemblyName>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\Debug\Portable\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;PORTABLE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\Release\Portable\</OutputPath>
+    <DefineConstants>TRACE;PORTABLE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework, Version=3.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl50+win+wpa81+wp80+MonoAndroid10+MonoTouch10\MonoGame.Framework.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="MonoGame.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Content.Pipeline.Portable.3.2.99.1-Beta\lib\portable-net40+sl50+win+wpa81+wp80+MonoAndroid10+MonoTouch10\MonoGame.Framework.Content.Pipeline.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\AnimationsContent.cs" />
+    <Compile Include="Animation\ClipContent.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBufferContent.cs" />
+    <Compile Include="Animation\KeyframeContent.cs" />
+    <Compile Include="Processors\AnimationsProcessor.cs" />
+    <Compile Include="Processors\CpuAnimatedModelProcessor.cs" />
+    <Compile Include="Processors\GpuAnimatedModelProcessor.cs" />
+    <Compile Include="Serialization\AnimationsWriter.cs" />
+    <Compile Include="Serialization\ClipWriter.cs" />
+    <Compile Include="Serialization\CpuAnimatedVertexBufferWriter.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\GraphicsImporters\GraphicsImporters.PORTABLE.csproj">
+      <Project>{0a079394-d331-433a-94df-aa25b6522279}</Project>
+      <Name>GraphicsImporters.PORTABLE</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 80 - 0
Content.Pipeline/AnimationImporters/AnimationImporters.WINDOWS.MG.csproj

@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <ProjectGuid>{D9A47306-DEE0-4410-BC2C-BA8FFCE682A3}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Content.Pipeline</RootNamespace>
+    <AssemblyName>Aether.Content.Pipeline.AnimationImporters</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\Debug\Windows\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\Release\Windows\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="MonoGame.Framework, Version=3.1.2.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Portable.3.2.99.1-Beta\lib\portable-net40+sl40+win+wp80\MonoGame.Framework.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="MonoGame.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\MonoGame.Framework.Content.Pipeline.Portable.3.2.99.1-Beta\lib\portable-net45+win+wpa81+Xamarin.iOS10+MonoAndroid10+MonoTouch10\MonoGame.Framework.Content.Pipeline.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Microsoft.CSharp" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\AnimationsContent.cs" />
+    <Compile Include="Animation\ClipContent.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBufferContent.cs" />
+    <Compile Include="Animation\KeyframeContent.cs" />
+    <Compile Include="Processors\AnimationsProcessor.cs" />
+    <Compile Include="Processors\CpuAnimatedModelProcessor.cs" />
+    <Compile Include="Processors\GpuAnimatedModelProcessor.cs" />
+    <Compile Include="Serialization\AnimationsWriter.cs" />
+    <Compile Include="Serialization\ClipWriter.cs" />
+    <Compile Include="Serialization\CpuAnimatedVertexBufferWriter.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.MG.cs" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\GraphicsImporters\GraphicsImporters.WINDOWS.MG.csproj">
+      <Project>{400dc7b2-739d-4156-916d-2f2e1920310d}</Project>
+      <Name>GraphicsImporters.WINDOWS.MG</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 79 - 0
Content.Pipeline/AnimationImporters/AnimationImporters.WINDOWS.XNA.csproj

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <ProjectGuid>{E22F02E7-6799-4C14-B9B3-B461D6E9AB6E}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>tainicom.Aether.Content.Pipeline</RootNamespace>
+    <AssemblyName>Aether.Content.Pipeline.AnimationImporters</AssemblyName>
+    <XnaFrameworkVersion>v4.0</XnaFrameworkVersion>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\Debug\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaPlatform>Windows</XnaPlatform>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>none</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\Release\Windows.XNA\</OutputPath>
+    <DefineConstants>TRACE;WINDOWS XNA</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>x86</PlatformTarget>
+    <XnaPlatform>Windows</XnaPlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Content.Pipeline, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
+    <Reference Include="System">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Animation\AnimationsContent.cs" />
+    <Compile Include="Animation\ClipContent.cs" />
+    <Compile Include="Animation\CpuAnimatedVertexBufferContent.cs" />
+    <Compile Include="Animation\KeyframeContent.cs" />
+    <Compile Include="Processors\AnimationsProcessor.cs" />
+    <Compile Include="Processors\CpuAnimatedModelProcessor.cs" />
+    <Compile Include="Processors\GpuAnimatedModelProcessor.cs" />
+    <Compile Include="Serialization\AnimationsWriter.cs" />
+    <Compile Include="Serialization\ClipWriter.cs" />
+    <Compile Include="Serialization\CpuAnimatedVertexBufferWriter.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\GraphicsImporters\GraphicsImporters.WINDOWS.XNA.csproj">
+      <Project>{565ACF47-7E36-435E-8727-2AFB39E61134}</Project>
+      <Name>GraphicsImporters.WINDOWS.XNA</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\Microsoft.Xna.GameStudio.ContentPipelineExtensions.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+     Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 444 - 0
Content.Pipeline/AnimationImporters/Processors/AnimationsProcessor.cs

@@ -0,0 +1,444 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Content.Pipeline.Animation;
+
+namespace tainicom.Aether.Content.Pipeline.Processors
+{
+    [ContentProcessor(DisplayName = "Animation - Aether")]
+    class AnimationsProcessor : ContentProcessor<NodeContent, AnimationsContent>
+    {
+        private int _maxBones = SkinnedEffect.MaxBones;
+        private int _generateKeyframesFrequency = 0;
+        private bool _fixRealBoneRoot = false;
+
+#if !PORTABLE
+        [DisplayName("MaxBones")]
+#endif
+        [DefaultValue(SkinnedEffect.MaxBones)]
+        public virtual int MaxBones
+        {
+            get { return _maxBones; }
+            set { _maxBones = value; }
+        }
+
+#if !PORTABLE
+        [DisplayName("Generate Keyframes Frequency")]
+#endif
+        [DefaultValue(0)] // (0=no, 30=30fps, 60=60fps)
+        public virtual int GenerateKeyframesFrequency
+        {
+            get { return _generateKeyframesFrequency; }
+            set { _generateKeyframesFrequency = value; }
+        }
+
+#if !PORTABLE
+        [DisplayName("Fix BoneRoot from MG importer")]
+#endif
+        [DefaultValue(false)]
+        public virtual bool FixRealBoneRoot
+        {
+            get { return _fixRealBoneRoot; }
+            set { _fixRealBoneRoot = value; }
+        }
+
+        public override AnimationsContent Process(NodeContent input, ContentProcessorContext context)
+        {
+            if(_fixRealBoneRoot)
+                MGFixRealBoneRoot(input, context);
+
+            ValidateMesh(input, context, null);
+
+            // Find the skeleton.
+            BoneContent skeleton = MeshHelper.FindSkeleton(input);
+
+            if (skeleton == null)
+                throw new InvalidContentException("Input skeleton not found.");
+
+            // We don't want to have to worry about different parts of the model being
+            // in different local coordinate systems, so let's just bake everything.
+            FlattenTransforms(input, skeleton);
+
+            // Read the bind pose and skeleton hierarchy data.
+            IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton);
+
+            if (bones.Count > MaxBones)
+            {
+                throw new InvalidContentException(string.Format("Skeleton has {0} bones, but the maximum supported is {1}.", bones.Count, MaxBones));
+            }
+
+            List<Matrix> bindPose = new List<Matrix>();
+            List<Matrix> invBindPose = new List<Matrix>();
+            List<int> skeletonHierarchy = new List<int>();
+
+            foreach (BoneContent bone in bones)
+            {
+                bindPose.Add(bone.Transform);
+                invBindPose.Add(Matrix.Invert(bone.AbsoluteTransform));
+                skeletonHierarchy.Add(bones.IndexOf(bone.Parent as BoneContent));
+            }
+
+            // Convert animation data to our runtime format.
+            Dictionary<string, ClipContent> clips;
+            clips = ProcessAnimations(input, context, skeleton.Animations, bones, GenerateKeyframesFrequency);
+
+            return new AnimationsContent(bindPose, invBindPose, skeletonHierarchy, clips);
+        }
+        
+        /// <summary>
+        /// MonoGame converts some NodeContent into BoneContent.
+        /// Here we revert that to get the original Skeleton and  
+        /// add the real boneroot to the root node.
+        /// </summary>
+        private void MGFixRealBoneRoot(NodeContent input, ContentProcessorContext context)
+        {
+            for (int i = input.Children.Count - 1; i >= 0; i--)
+            {
+                var node = input.Children[i];
+                if (node is BoneContent &&
+                    node.AbsoluteTransform == Matrix.Identity &&
+                    node.Children.Count ==1 &&
+                    node.Children[0] is BoneContent &&
+                    node.Children[0].AbsoluteTransform == Matrix.Identity
+                    )
+                {
+                    //dettach real boneRoot
+                    var realBoneRoot = node.Children[0];
+                    node.Children.RemoveAt(0);
+                    //copy animation from node to boneRoot
+                    foreach (var animation in node.Animations)
+                        realBoneRoot.Animations.Add(animation.Key, animation.Value);
+                    // convert fake BoneContent back to NodeContent
+                    input.Children[i] = new NodeContent()
+                    {
+                        Name = node.Name,
+                        Identity = node.Identity,
+                        Transform = node.Transform,                        
+                    };
+                    foreach (var animation in node.Animations)
+                        input.Children[i].Animations.Add(animation.Key, animation.Value);
+                    foreach (var opaqueData in node.OpaqueData)
+                        input.Children[i].OpaqueData.Add(opaqueData.Key, opaqueData.Value);
+                    //attach real boneRoot to the root node
+                    input.Children.Add(realBoneRoot);
+
+                    break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Makes sure this mesh contains the kind of data we know how to animate.
+        /// </summary>
+        void ValidateMesh(NodeContent node, ContentProcessorContext context, string parentBoneName)
+        {
+            MeshContent mesh = node as MeshContent;
+            if (mesh != null)
+            {
+                // Validate the mesh.
+                if (parentBoneName != null)
+                {
+                    context.Logger.LogWarning(null, null,
+                        "Mesh {0} is a child of bone {1}. AnimatedModelProcessor " +
+                        "does not correctly handle meshes that are children of bones.",
+                        mesh.Name, parentBoneName);
+                }
+
+                if (!MeshHasSkinning(mesh))
+                {
+                    context.Logger.LogWarning(null, null,
+                        "Mesh {0} has no skinning information, so it has been deleted.",
+                        mesh.Name);
+
+                    mesh.Parent.Children.Remove(mesh);
+                    return;
+                }
+            }
+            else if (node is BoneContent)
+            {
+                // If this is a bone, remember that we are now looking inside it.
+                parentBoneName = node.Name;
+            }
+
+            // Recurse (iterating over a copy of the child collection,
+            // because validating children may delete some of them).
+            foreach (NodeContent child in new List<NodeContent>(node.Children))
+                ValidateMesh(child, context, parentBoneName);
+        }
+        
+        /// <summary>
+        /// Checks whether a mesh contains skininng information.
+        /// </summary>
+        bool MeshHasSkinning(MeshContent mesh)
+        {
+            foreach (GeometryContent geometry in mesh.Geometry)
+            {
+                if (!geometry.Vertices.Channels.Contains(VertexChannelNames.Weights()) &&
+                    !geometry.Vertices.Channels.Contains("BlendWeight0"))
+                    return false;
+            }
+
+            return true;
+        }
+        
+        /// <summary>
+        /// Bakes unwanted transforms into the model geometry,
+        /// so everything ends up in the same coordinate system.
+        /// </summary>
+        void FlattenTransforms(NodeContent node, BoneContent skeleton)
+        {
+            foreach (NodeContent child in node.Children)
+            {
+                // Don't process the skeleton, because that is special.
+                if (child == skeleton)
+                    continue;
+
+                // Bake the local transform into the actual geometry.
+                MeshHelper.TransformScene(child, child.Transform);
+
+                // Having baked it, we can now set the local
+                // coordinate system back to identity.
+                child.Transform = Matrix.Identity;
+
+                // Recurse.
+                FlattenTransforms(child, skeleton);
+            }
+        }
+        
+        /// <summary>
+        /// Converts an intermediate format content pipeline AnimationContentDictionary
+        /// object to our runtime AnimationClip format.
+        /// </summary>
+        Dictionary<string, ClipContent> ProcessAnimations(NodeContent input, ContentProcessorContext context, AnimationContentDictionary animations, IList<BoneContent> bones, int generateKeyframesFrequency)
+        {
+            // Build up a table mapping bone names to indices.
+            Dictionary<string, int> boneMap = new Dictionary<string, int>();
+
+            for (int i = 0; i < bones.Count; i++)
+            {
+                string boneName = bones[i].Name;
+
+                if (!string.IsNullOrEmpty(boneName))
+                    boneMap.Add(boneName, i);
+            }
+
+            // Convert each animation in turn.
+            Dictionary<string, ClipContent> animationClips;
+            animationClips = new Dictionary<string, ClipContent>();
+
+            foreach (KeyValuePair<string, AnimationContent> animation in animations)
+            {
+                ClipContent clip = ProcessAnimation(input, context, animation.Value, boneMap, generateKeyframesFrequency);
+
+                animationClips.Add(animation.Key, clip);
+            }
+
+            if (animationClips.Count == 0)
+            {
+                //throw new InvalidContentException("Input file does not contain any animations.");
+                context.Logger.LogWarning(null, null, "Input file does not contain any animations.");
+            }
+
+            return animationClips;
+        }
+        
+        /// <summary>
+        /// Converts an intermediate format content pipeline AnimationContent
+        /// object to our runtime AnimationClip format.
+        /// </summary>
+        ClipContent ProcessAnimation(NodeContent input, ContentProcessorContext context, AnimationContent animation, Dictionary<string, int> boneMap, int generateKeyframesFrequency)
+        {
+            List<KeyframeContent> keyframes = new List<KeyframeContent>();
+
+            // For each input animation channel.
+            foreach (KeyValuePair<string, AnimationChannel> channel in
+                animation.Channels)
+            {
+                // Look up what bone this channel is controlling.
+                int boneIndex;
+
+                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
+                {
+                    //throw new InvalidContentException(string.Format("Found animation for bone '{0}', which is not part of the skeleton.", channel.Key));
+                    context.Logger.LogWarning(null, null, "Found animation for bone '{0}', which is not part of the skeleton.", channel.Key);
+
+                    continue;
+                }
+
+                foreach (AnimationKeyframe keyframe in channel.Value)
+                    keyframes.Add(new KeyframeContent(boneIndex, keyframe.Time, keyframe.Transform));
+            }
+
+            // Sort the merged keyframes by time.
+            keyframes.Sort(CompareKeyframeTimes);
+
+            //System.Diagnostics.Debugger.Launch();
+            if (generateKeyframesFrequency > 0)
+                keyframes = InterpolateKeyframes(animation.Duration, keyframes, generateKeyframesFrequency);
+
+            if (keyframes.Count == 0)
+                throw new InvalidContentException("Animation has no keyframes.");
+
+            if (animation.Duration <= TimeSpan.Zero)
+                throw new InvalidContentException("Animation has a zero duration.");
+
+            return new ClipContent(animation.Duration, keyframes.ToArray());
+        }
+
+        int CompareKeyframeTimes(KeyframeContent a, KeyframeContent b)
+        {
+            int cmpTime = a.Time.CompareTo(b.Time);
+            if (cmpTime == 0)
+                return a.Bone.CompareTo(b.Bone);
+
+            return cmpTime;
+        }
+
+        private List<KeyframeContent> InterpolateKeyframes(TimeSpan duration, List<KeyframeContent> keyframes, int generateKeyframesFrequency)
+        {
+            if (generateKeyframesFrequency <= 0)
+                return keyframes;
+
+            int keyframeCount = keyframes.Count;
+
+            // find bones
+            HashSet<int> bonesSet = new HashSet<int>();
+            int maxBone = 0;
+            for (int i = 0; i < keyframeCount; i++)
+            {
+                int bone = keyframes[i].Bone;
+                maxBone = Math.Max(maxBone, bone);
+                bonesSet.Add(bone);
+            }
+            int boneCount = bonesSet.Count;
+
+            // split bones 
+            List<KeyframeContent>[] boneFrames = new List<KeyframeContent>[maxBone + 1];
+            for (int i = 0; i < keyframeCount; i++)
+            {
+                int bone = keyframes[i].Bone;
+                if (boneFrames[bone] == null) boneFrames[bone] = new List<KeyframeContent>();
+                boneFrames[bone].Add(keyframes[i]);
+            }
+
+            //            
+            System.Diagnostics.Debug.WriteLine("Duration: " + duration);
+            System.Diagnostics.Debug.WriteLine("keyframeCount: " + keyframeCount);
+
+            for (int b = 0; b < boneFrames.Length; b++)
+            {
+                TimeSpan keySpan = TimeSpan.FromTicks((long)((1f / generateKeyframesFrequency) * TimeSpan.TicksPerSecond));
+                boneFrames[b] = InterpolateFramesBone(b, boneFrames[b], keySpan);
+            }
+
+            int frames = keyframeCount / boneCount;
+
+            TimeSpan checkDuration = TimeSpan.FromSeconds((frames - 1) / generateKeyframesFrequency);
+            if (duration == checkDuration) return keyframes;
+
+            List<KeyframeContent> newKeyframes = new List<KeyframeContent>();
+            for (int b = 0; b < boneFrames.Length; b++)
+            {
+                for (int k = 0; k < boneFrames[b].Count; ++k)
+                {
+                    newKeyframes.Add(boneFrames[b][k]);
+                }
+            }
+            newKeyframes.Sort(CompareKeyframeTimes);
+
+            return newKeyframes;
+        }
+
+        private static List<KeyframeContent> InterpolateFramesBone(int bone, List<KeyframeContent> frames, TimeSpan keySpan)
+        {
+            System.Diagnostics.Debug.WriteLine("");
+            System.Diagnostics.Debug.WriteLine("Bone: " + bone);
+            if (frames == null)
+            {
+                System.Diagnostics.Debug.WriteLine("Frames: " + "null");
+                return frames;
+            }
+            System.Diagnostics.Debug.WriteLine("Frames: " + frames.Count);
+            System.Diagnostics.Debug.WriteLine("MinTime: " + frames[0].Time);
+            System.Diagnostics.Debug.WriteLine("MaxTime: " + frames[frames.Count - 1].Time);
+
+            for (int i = 0; i < frames.Count - 1; ++i)
+            {
+                InterpolateFrames(bone, frames, keySpan, i);
+            }
+
+            return frames;
+        }
+
+        private static void InterpolateFrames(int bone, List<KeyframeContent> frames, TimeSpan keySpan, int i)
+        {
+            int a = i;
+            int b = i + 1;
+            var diff = frames[b].Time - frames[a].Time;
+            if (diff > keySpan)
+            {
+                TimeSpan newTime = frames[a].Time + keySpan;
+                float amount = (float)(keySpan.TotalSeconds / diff.TotalSeconds);
+
+                Vector3 pScale; Quaternion pRotation; Vector3 pTranslation;
+                frames[a].Transform.Decompose(out pScale, out pRotation, out pTranslation);
+
+                Vector3 iScale; Quaternion iRotation; Vector3 iTranslation;
+                frames[b].Transform.Decompose(out iScale, out iRotation, out iTranslation);
+
+                Vector3 Scale; Quaternion Rotation; Vector3 Translation;
+                //lerp
+                Vector3.Lerp(ref pScale, ref iScale, amount, out Scale);
+                Quaternion.Lerp(ref pRotation, ref iRotation, amount, out Rotation);
+                Vector3.Lerp(ref pTranslation, ref iTranslation, amount, out Translation);
+
+                Matrix rotation;
+                Matrix.CreateFromQuaternion(ref Rotation, out rotation);
+
+                Matrix newMatrix = new Matrix
+                {
+                    M11 = Scale.X * rotation.M11,
+                    M12 = Scale.X * rotation.M12,
+                    M13 = Scale.X * rotation.M13,
+                    M14 = 0,
+                    M21 = Scale.Y * rotation.M21,
+                    M22 = Scale.Y * rotation.M22,
+                    M23 = Scale.Y * rotation.M23,
+                    M24 = 0,
+                    M31 = Scale.Z * rotation.M31,
+                    M32 = Scale.Z * rotation.M32,
+                    M33 = Scale.Z * rotation.M33,
+                    M34 = 0,
+                    M41 = Translation.X,
+                    M42 = Translation.Y,
+                    M43 = Translation.Z,
+                    M44 = 1
+                };
+
+                frames.Insert(b, new KeyframeContent(bone, newTime, newMatrix));
+            }
+            return;
+        }
+        
+    }
+}

+ 134 - 0
Content.Pipeline/AnimationImporters/Processors/CpuAnimatedModelProcessor.cs

@@ -0,0 +1,134 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Content.Pipeline.Processors;
+using Microsoft.Xna.Framework.Graphics;
+using tainicom.Aether.Content.Pipeline.Animation;
+using tainicom.Aether.Content.Pipeline.Serialization;
+using tainicom.Aether.Content.Pipeline.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Processors
+{
+    [ContentProcessor(DisplayName = "CPU AnimatedModel - Aether")]
+    class CpuAnimatedModelProcessor : DynamicModelProcessor, IContentProcessor
+    {
+        private int _maxBones = SkinnedEffect.MaxBones;
+        private int _generateKeyframesFrequency = 0;
+        private bool _fixRealBoneRoot = false;
+
+        // used to avoid creating clones/duplicates of the same VertexBufferContent
+        Dictionary<VertexBufferContent, CpuAnimatedVertexBufferContent> _vertexBufferCache = new Dictionary<VertexBufferContent,CpuAnimatedVertexBufferContent>();
+
+        
+        [DefaultValue(DynamicModelContent.BufferType.DynamicWriteOnly)]
+        public new DynamicModelContent.BufferType VertexBufferType
+        {
+            get { return  base.VertexBufferType; }
+            set { base.VertexBufferType = value; }
+        }
+        
+        [DefaultValue(DynamicModelContent.BufferType.Default)]
+        public new DynamicModelContent.BufferType IndexBufferType
+        {
+            get { return base.IndexBufferType; }
+            set { base.IndexBufferType = value; }
+        }
+        
+#if !PORTABLE
+        [DisplayName("MaxBones")]
+#endif
+        [DefaultValue(SkinnedEffect.MaxBones)]
+        public virtual int MaxBones
+        {
+            get { return _maxBones; }
+            set { _maxBones = value; }
+        }
+        
+#if !PORTABLE
+        [DisplayName("Generate Keyframes Frequency")]
+#endif
+        [DefaultValue(0)] // (0=no, 30=30fps, 60=60fps)
+        public virtual int GenerateKeyframesFrequency
+        {
+            get { return _generateKeyframesFrequency; }
+            set { _generateKeyframesFrequency = value; }
+        }
+
+#if !PORTABLE
+        [DisplayName("Fix BoneRoot from MG importer")]
+#endif
+        [DefaultValue(false)]
+        public virtual bool FixRealBoneRoot
+        {
+            get { return _fixRealBoneRoot; }
+            set { _fixRealBoneRoot = value; }
+        }
+        
+        public CpuAnimatedModelProcessor()
+        {
+            VertexBufferType = DynamicModelContent.BufferType.DynamicWriteOnly;
+            IndexBufferType  = DynamicModelContent.BufferType.Default;
+        }
+
+        object IContentProcessor.Process(object input, ContentProcessorContext context)
+        {
+            var model = Process((NodeContent)input, context);
+            var outputModel = new DynamicModelContent(model);
+            
+            foreach(var mesh in outputModel.Meshes)
+            {
+                foreach(var part in mesh.MeshParts)
+                {
+                    ProcessVertexBuffer(outputModel, context, part);
+                    ProcessIndexBuffer(outputModel, context, part);
+                }
+            }
+
+            // import animation
+            var animationProcessor = new AnimationsProcessor();
+            animationProcessor.MaxBones = this.MaxBones;
+            animationProcessor.GenerateKeyframesFrequency = this.GenerateKeyframesFrequency;
+            animationProcessor.FixRealBoneRoot = this._fixRealBoneRoot;
+            var animation = animationProcessor.Process((NodeContent)input, context);
+            outputModel.Tag = animation;
+
+            //ProcessNode((NodeContent)input);
+
+            return outputModel;
+        }
+
+        protected override void ProcessVertexBuffer(DynamicModelContent dynamicModel, ContentProcessorContext context, DynamicModelMeshPartContent part)
+        {
+            if (VertexBufferType != DynamicModelContent.BufferType.Default)
+            {
+                // Replace the default VertexBufferContent with CpuAnimatedVertexBufferContent.
+                CpuAnimatedVertexBufferContent vb;
+                if (!_vertexBufferCache.TryGetValue(part.VertexBuffer, out vb))
+                {
+                    vb = new CpuAnimatedVertexBufferContent(part.VertexBuffer);
+                    vb.IsWriteOnly = (VertexBufferType == DynamicModelContent.BufferType.DynamicWriteOnly);
+                    _vertexBufferCache[part.VertexBuffer] = vb;
+                }
+                part.VertexBuffer = vb;
+            }
+        }
+        
+    }
+}

+ 87 - 0
Content.Pipeline/AnimationImporters/Processors/GpuAnimatedModelProcessor.cs

@@ -0,0 +1,87 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System.ComponentModel;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
+using Microsoft.Xna.Framework.Content.Pipeline.Processors;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Processors
+{
+    [ContentProcessor(DisplayName = "GPU AnimatedModel - Aether")]
+    public class GpuAnimatedModelProcessor : ModelProcessor
+    {
+        private int _maxBones = SkinnedEffect.MaxBones;
+        private int _generateKeyframesFrequency = 0;
+        private bool _fixRealBoneRoot = false;
+
+#if !PORTABLE
+        [DisplayName("MaxBones")]
+#endif
+        [DefaultValue(SkinnedEffect.MaxBones)]
+        public virtual int MaxBones 
+        {
+            get { return _maxBones; }
+            set { _maxBones = value; }
+        }
+
+#if !PORTABLE
+        [DisplayName("Generate Keyframes Frequency")]
+#endif
+        [DefaultValue(0)] // (0=no, 30=30fps, 60=60fps)
+        public virtual int GenerateKeyframesFrequency
+        {
+            get { return _generateKeyframesFrequency; }
+            set { _generateKeyframesFrequency = value; }
+        }
+
+#if !PORTABLE
+        [DisplayName("Fix BoneRoot from MG importer")]
+#endif
+        [DefaultValue(false)]
+        public virtual bool FixRealBoneRoot
+        {
+            get { return _fixRealBoneRoot; }
+            set { _fixRealBoneRoot = value; }
+        }
+
+        [DefaultValue(MaterialProcessorDefaultEffect.SkinnedEffect)]
+        public override MaterialProcessorDefaultEffect DefaultEffect
+        {
+            get { return base.DefaultEffect; }
+            set { base.DefaultEffect = value; }
+        }
+        
+        public GpuAnimatedModelProcessor()
+        {
+            DefaultEffect = MaterialProcessorDefaultEffect.SkinnedEffect;
+        }
+
+        public override ModelContent Process(NodeContent input, ContentProcessorContext context)
+        {
+            var animationProcessor = new AnimationsProcessor();
+            animationProcessor.MaxBones = this.MaxBones;   
+            animationProcessor.GenerateKeyframesFrequency = this.GenerateKeyframesFrequency;
+            animationProcessor.FixRealBoneRoot = this._fixRealBoneRoot;
+            var animation = animationProcessor.Process(input, context);
+            
+            ModelContent model = base.Process(input, context);
+            model.Tag = animation;
+            return model;
+        }
+    }
+}

+ 33 - 0
Content.Pipeline/AnimationImporters/Properties/AssemblyInfo.MG.cs

@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Content.Pipeline.Animation")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Aether.Content.Pipeline.Animation")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("a837f910-cb4a-408c-805a-64f9a1d31eca")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 30 - 0
Content.Pipeline/AnimationImporters/Properties/AssemblyInfo.cs

@@ -0,0 +1,30 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Aether.Content.Pipeline.Animation")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Aether.Content.Pipeline.Animation")]
+[assembly: AssemblyCopyright("Copyright ©  Kastellanos Nikolaos 2011-2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ff837057-ca41-4c1d-9162-561a32cd3923")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 94 - 0
Content.Pipeline/AnimationImporters/Serialization/AnimationsWriter.cs

@@ -0,0 +1,94 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
+using tainicom.Aether.Content.Pipeline.Animation;
+
+namespace tainicom.Aether.Content.Pipeline.Serialization
+{   
+    [ContentTypeWriter]
+    class AnimationsDataWriter : ContentTypeWriter<AnimationsContent>
+    {
+        protected override void Write(ContentWriter output, AnimationsContent value)
+        {
+            WriteClips(output, value.Clips);
+            WriteBindPose(output, value.BindPose);
+            WriteInvBindPose(output, value.InvBindPose);
+            WriteSkeletonHierarchy(output, value.SkeletonHierarchy);
+        }
+
+        private void WriteClips(ContentWriter output, Dictionary<string, ClipContent> clips)
+        {
+            Int32 count = clips.Count;
+            output.Write((Int32)count);
+
+            foreach (var clip in clips)
+            {
+                output.Write(clip.Key);
+                output.WriteObject<ClipContent>(clip.Value);
+            }            
+
+            return;
+        }
+
+        private void WriteBindPose(ContentWriter output, List<Microsoft.Xna.Framework.Matrix> bindPoses)
+        {
+            Int32 count = bindPoses.Count;
+            output.Write((Int32)count);
+
+            for (int i = 0; i < count; i++)
+                output.Write(bindPoses[i]);
+
+            return;
+        }
+
+        private void WriteInvBindPose(ContentWriter output, List<Microsoft.Xna.Framework.Matrix> invBindPoses)
+        {
+            Int32 count = invBindPoses.Count;
+            output.Write((Int32)count);
+
+            for (int i = 0; i < count; i++)
+                output.Write(invBindPoses[i]);
+
+            return;
+        }
+
+        private void WriteSkeletonHierarchy(ContentWriter output, List<int> skeletonHierarchy)
+        {
+            Int32 count = skeletonHierarchy.Count;
+            output.Write((Int32)count);
+
+            for (int i = 0; i < count; i++)
+                output.Write((Int32)skeletonHierarchy[i]);
+
+            return;
+        }
+    
+        public override string GetRuntimeType(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Animation.Animations, Aether.Animation";
+        }
+
+        public override string GetRuntimeReader(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Animation.Content.AnimationsReader, Aether.Animation";
+        }
+    }
+        
+}

+ 78 - 0
Content.Pipeline/AnimationImporters/Serialization/ClipWriter.cs

@@ -0,0 +1,78 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
+using tainicom.Aether.Content.Pipeline.Animation;
+
+
+namespace tainicom.Aether.Content.Pipeline.Serialization
+{
+    [ContentTypeWriter]
+    class ClipWriter : ContentTypeWriter<ClipContent>
+    {
+        protected override void Write(ContentWriter output, ClipContent value)
+        {
+            WriteDuration(output, value.Duration);
+            WriteKeyframes(output, value.Keyframes);
+        }
+
+        private void WriteDuration(ContentWriter output, TimeSpan duration)
+        {
+            output.Write(duration.Ticks);
+        }
+
+        private void WriteKeyframes(ContentWriter output, IList<KeyframeContent> keyframes)
+        {
+            Int32 count = keyframes.Count;
+            output.Write((Int32)count);
+
+            for (int i = 0; i < count; i++)
+            {
+                KeyframeContent keyframe = keyframes[i];
+                output.Write(keyframe.Bone);
+                output.Write(keyframe.Time.Ticks);
+                output.Write(keyframe.Transform.M11);
+                output.Write(keyframe.Transform.M12);
+                output.Write(keyframe.Transform.M13);
+                output.Write(keyframe.Transform.M21);
+                output.Write(keyframe.Transform.M22);
+                output.Write(keyframe.Transform.M23);
+                output.Write(keyframe.Transform.M31);
+                output.Write(keyframe.Transform.M32);
+                output.Write(keyframe.Transform.M33);
+                output.Write(keyframe.Transform.M41);
+                output.Write(keyframe.Transform.M42);
+                output.Write(keyframe.Transform.M43);
+            }
+
+            return;
+        }
+
+        public override string GetRuntimeType(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Animation.Clip, Aether.Animation";
+        }
+
+        public override string GetRuntimeReader(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Animation.Content.ClipReader, Aether.Animation";
+        }
+    }
+    
+}

+ 48 - 0
Content.Pipeline/AnimationImporters/Serialization/CpuAnimatedVertexBufferWriter.cs

@@ -0,0 +1,48 @@
+#region License
+//   Copyright 2011-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+#endregion
+
+using System;
+using Microsoft.Xna.Framework.Content.Pipeline;
+using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
+using tainicom.Aether.Content.Pipeline.Animation;
+using tainicom.Aether.Content.Pipeline.Graphics;
+
+namespace tainicom.Aether.Content.Pipeline.Serialization
+{
+    [ContentTypeWriter]
+    public class CpuAnimatedVertexBufferWriter : ContentTypeWriter<CpuAnimatedVertexBufferContent>
+    {
+        protected override void Write(ContentWriter output, CpuAnimatedVertexBufferContent buffer)
+        {
+            WriteVertexBuffer(output, buffer);
+            
+            output.Write(buffer.IsWriteOnly);
+        }
+                
+        private void WriteVertexBuffer(ContentWriter output, DynamicVertexBufferContent buffer)
+        {
+            var vertexCount = buffer.VertexData.Length / buffer.VertexDeclaration.VertexStride;
+            output.WriteRawObject(buffer.VertexDeclaration);
+            output.Write((UInt32)vertexCount);
+            output.Write(buffer.VertexData);
+        }
+        
+        public override string GetRuntimeReader(TargetPlatform targetPlatform)
+        {
+            return "tainicom.Aether.Animation.Content.CpuAnimatedVertexBufferReader, Aether.Animation";
+        }
+    }
+}

+ 5 - 0
Content.Pipeline/AnimationImporters/packages.config

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MonoGame.Framework.Content.Pipeline.Portable" version="3.2.99.1-Beta" targetFramework="net45" />
+  <package id="MonoGame.Framework.Portable" version="3.2.99.1-Beta" targetFramework="net45" />
+</packages>

+ 199 - 0
Native.Animation/Aether.Native.Animation.WP8.vcxproj

@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{22c72dc0-022d-4d1b-b738-c764f67421ea}</ProjectGuid>
+    <RootNamespace>tainicom.Aether.Native.Animation</RootNamespace>
+    <DefaultLanguage>en-US</DefaultLanguage>
+    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+    <WinMDAssembly>true</WinMDAssembly>
+    <ProjectName>tainicom.Aether.Native.Animation</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110_wp80</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <GenerateManifest>false</GenerateManifest>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <IntDir>$(ProjectDir)\obj\$(Configuration)\WP8\$(PlatformShortName)\</IntDir>
+    <OutDir>$(SolutionDir)\bin\$(Configuration)\WP8\$(PlatformShortName)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <IntDir>$(ProjectDir)\obj\$(Configuration)\WP8\$(PlatformShortName)\</IntDir>
+    <OutDir>$(SolutionDir)\bin\$(Configuration)\WP8\$(PlatformShortName)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IntDir>$(ProjectDir)\obj\$(Configuration)\WP8\$(PlatformShortName)\</IntDir>
+    <OutDir>$(SolutionDir)\bin\$(Configuration)\WP8\$(PlatformShortName)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IntDir>$(ProjectDir)\obj\$(Configuration)\WP8\$(PlatformShortName)\</IntDir>
+    <OutDir>$(SolutionDir)\bin\$(Configuration)\WP8\$(PlatformShortName)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>true</CompileAsWinRT>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateWindowsMetadata>true</GenerateWindowsMetadata>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>true</CompileAsWinRT>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateWindowsMetadata>true</GenerateWindowsMetadata>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>true</CompileAsWinRT>
+      <Optimization>Disabled</Optimization>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <WholeProgramOptimization>true</WholeProgramOptimization>
+      <AdditionalOptions> /Qpar-report:2 %(AdditionalOptions)</AdditionalOptions>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateWindowsMetadata>true</GenerateWindowsMetadata>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINRT_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <CompileAsWinRT>true</CompileAsWinRT>
+      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <FloatingPointModel>Fast</FloatingPointModel>
+      <OmitFramePointers>false</OmitFramePointers>
+      <CallingConvention>Cdecl</CallingConvention>
+      <AdditionalOptions> /Qpar-report:1 %(AdditionalOptions)</AdditionalOptions>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <Optimization>Full</Optimization>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <SDLCheck>false</SDLCheck>
+      <AssemblerOutput>NoListing</AssemblerOutput>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <IgnoreSpecificDefaultLibraries>ole32.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+      <GenerateWindowsMetadata>true</GenerateWindowsMetadata>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Reference Include="platform.winmd">
+      <IsWinMDFile>true</IsWinMDFile>
+      <Private>false</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Animation\CpuAnimatedVertexBufferHelper.h" />
+    <ClInclude Include="Data\Int4Data.h" />
+    <ClInclude Include="Data\Matrix.h" />
+    <ClInclude Include="Data\Vector2Data.h" />
+    <ClInclude Include="Data\Vector3Data.h" />
+    <ClInclude Include="Data\Vector4Data.h" />
+    <ClInclude Include="Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.h" />
+    <ClInclude Include="pch.h" />
+    <ClInclude Include="VertexPositionNormalTextureData.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Animation\CpuAnimatedVertexBufferHelper.cpp" />
+    <ClCompile Include="pch.cpp">
+      <PrecompiledHeader>Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 114 - 0
Native.Animation/Animation/CpuAnimatedVertexBufferHelper.cpp

@@ -0,0 +1,114 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#include "pch.h"
+#include <malloc.h>
+#include "CpuAnimatedVertexBufferHelper.h"
+#include <vector>
+#include <collection.h>
+
+//using namespace DirectX;
+using namespace Platform;
+using namespace Platform::Collections;
+using namespace tainicom::Aether::Native::Animation;
+using namespace tainicom::Aether::Native::Animation::Data;
+
+
+tainicom::Aether::Native::Animation::CpuAnimatedVertexBufferHelper::CpuAnimatedVertexBufferHelper(void)
+{
+	_cpuVertices = nullptr;
+	_cpuVerticesLength = 0;
+}
+
+tainicom::Aether::Native::Animation::CpuAnimatedVertexBufferHelper::~CpuAnimatedVertexBufferHelper(void)
+{
+	delete _cpuVertices;
+	_cpuVerticesLength = 0;
+}
+
+void tainicom::Aether::Native::Animation::CpuAnimatedVertexBufferHelper::SetCpuVertices(const Platform::Array<VertexIndicesWeightsPositionNormal>^ cpuVertices)
+{
+	_cpuVerticesLength = cpuVertices->Length;
+	_cpuVertices = new VertexIndicesWeightsPositionNormal[_cpuVerticesLength = cpuVertices->Length];
+	for (int i = 0;i<_cpuVerticesLength;i++)
+	{
+		_cpuVertices[i] = cpuVertices[i];
+	}
+	return;
+}
+
+void tainicom::Aether::Native::Animation::CpuAnimatedVertexBufferHelper::UpdateVertices(
+	int64 pBoneTransforms, int64 pGpuVertices, int startIndex, int elementCount)
+{
+	MatrixData* pBone = (MatrixData*)pBoneTransforms;
+	VertexPositionNormalTextureData* pGpuVertex = (VertexPositionNormalTextureData*)pGpuVertices;
+	UpdateVertices(pBone, pGpuVertex, startIndex, elementCount);
+}
+
+
+void tainicom::Aether::Native::Animation::CpuAnimatedVertexBufferHelper::UpdateVertices(
+	MatrixData* pBoneTransforms, VertexPositionNormalTextureData* pGpuVertices, int startIndex, int elementCount)
+{
+	VertexPositionNormalTextureData* vout = pGpuVertices;
+
+	MatrixData transformSum;
+	transformSum.M14 = 0;
+	transformSum.M24 = 0;
+	transformSum.M34 = 0;
+	transformSum.M44 = 1;
+
+	// skin all of the vertices
+	int endIndex = (startIndex + elementCount - 1);
+	for (int i = startIndex; i <= endIndex; i++)
+	{
+		int b0 = _cpuVertices[i].BlendIndices.X;
+		int b1 = _cpuVertices[i].BlendIndices.Y;
+		int b2 = _cpuVertices[i].BlendIndices.Z;
+		int b3 = _cpuVertices[i].BlendIndices.W;
+
+		MatrixData* m1 = &pBoneTransforms[b0];
+		MatrixData* m2 = &pBoneTransforms[b1];
+		MatrixData* m3 = &pBoneTransforms[b2];
+		MatrixData* m4 = &pBoneTransforms[b3];
+
+		float w1 = _cpuVertices[i].BlendWeights.X;
+		float w2 = _cpuVertices[i].BlendWeights.Y;
+		float w3 = _cpuVertices[i].BlendWeights.Z;
+		float w4 = _cpuVertices[i].BlendWeights.W;
+
+		transformSum.M11 = (m1->M11 * w1) + (m2->M11 * w2) + (m3->M11 * w3) + (m4->M11 * w4);
+		transformSum.M12 = (m1->M12 * w1) + (m2->M12 * w2) + (m3->M12 * w3) + (m4->M12 * w4);
+		transformSum.M13 = (m1->M13 * w1) + (m2->M13 * w2) + (m3->M13 * w3) + (m4->M13 * w4);
+		transformSum.M21 = (m1->M21 * w1) + (m2->M21 * w2) + (m3->M21 * w3) + (m4->M21 * w4);
+		transformSum.M22 = (m1->M22 * w1) + (m2->M22 * w2) + (m3->M22 * w3) + (m4->M22 * w4);
+		transformSum.M23 = (m1->M23 * w1) + (m2->M23 * w2) + (m3->M23 * w3) + (m4->M23 * w4);
+		transformSum.M31 = (m1->M31 * w1) + (m2->M31 * w2) + (m3->M31 * w3) + (m4->M31 * w4);
+		transformSum.M32 = (m1->M32 * w1) + (m2->M32 * w2) + (m3->M32 * w3) + (m4->M32 * w4);
+		transformSum.M33 = (m1->M33 * w1) + (m2->M33 * w2) + (m3->M33 * w3) + (m4->M33 * w4);
+		transformSum.M41 = (m1->M41 * w1) + (m2->M41 * w2) + (m3->M41 * w3) + (m4->M41 * w4);
+		transformSum.M42 = (m1->M42 * w1) + (m2->M42 * w2) + (m3->M42 * w3) + (m4->M42 * w4);
+		transformSum.M43 = (m1->M43 * w1) + (m2->M43 * w2) + (m3->M43 * w3) + (m4->M43 * w4);
+
+		// Support the 4 Bone Influences - Position then Normal
+		Vector3Data position = _cpuVertices[i].Position;
+		vout[i].Position.X = position.X * transformSum.M11 + position.Y * transformSum.M21 + position.Z * transformSum.M31 + transformSum.M41;
+		vout[i].Position.Y = position.X * transformSum.M12 + position.Y * transformSum.M22 + position.Z * transformSum.M32 + transformSum.M42;
+		vout[i].Position.Z = position.X * transformSum.M13 + position.Y * transformSum.M23 + position.Z * transformSum.M33 + transformSum.M43;
+		Vector3Data normal = _cpuVertices[i].Normal;
+		vout[i].Normal.X = normal.X * transformSum.M11 + normal.Y * transformSum.M21 + normal.Z * transformSum.M31;
+		vout[i].Normal.Y = normal.X * transformSum.M12 + normal.Y * transformSum.M22 + normal.Z * transformSum.M32;
+		vout[i].Normal.Z = normal.X * transformSum.M13 + normal.Y * transformSum.M23 + normal.Z * transformSum.M33;
+	}
+
+}

+ 52 - 0
Native.Animation/Animation/CpuAnimatedVertexBufferHelper.h

@@ -0,0 +1,52 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+#include "..\Data\Matrix.h"
+#include "..\Graphics\VertexTypes\VertexIndicesWeightsPositionNormal.h" 
+#include "..\VertexPositionNormalTextureData.h"
+
+using namespace Platform;
+using namespace tainicom::Aether::Native::Animation::Data;
+using namespace tainicom::Aether::Native::Animation::VertexTypes;
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				public ref class CpuAnimatedVertexBufferHelper sealed
+				{
+				private:
+					VertexIndicesWeightsPositionNormal* _cpuVertices;
+					int _cpuVerticesLength;
+
+				public:
+					CpuAnimatedVertexBufferHelper(void);
+					virtual ~CpuAnimatedVertexBufferHelper(void);
+					void SetCpuVertices(const Platform::Array<VertexIndicesWeightsPositionNormal>^ cpuVertices);
+					void UpdateVertices(int64 pBoneTransforms, int64 pGpuVertices, int startIndex, int elementCount);
+
+				private:
+					void UpdateVertices(MatrixData* pBoneTransforms, VertexPositionNormalTextureData* pGpuVertex, int startIndex, int elementCount);
+
+				};
+			}
+		}
+	}
+}

+ 38 - 0
Native.Animation/Data/Int4Data.h

@@ -0,0 +1,38 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+#include <stdint.h>
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace Data
+				{
+					public value struct Int4Data
+					{
+					public:
+						int32_t X, Y, Z, W;
+					};
+				}
+			}
+		}
+	}
+}

+ 40 - 0
Native.Animation/Data/Matrix.h

@@ -0,0 +1,40 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace Data
+				{
+					public value struct MatrixData
+					{
+					public:
+						float M11, M12, M13, M14;
+						float M21, M22, M23, M24;
+						float M31, M32, M33, M34;
+						float M41, M42, M43, M44;
+					};
+				}
+			}
+		}
+	}
+}

+ 37 - 0
Native.Animation/Data/Vector2Data.h

@@ -0,0 +1,37 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace Data
+				{
+					public value struct Vector2Data
+					{
+					public:
+						float X, Y;
+					};
+				}
+			}
+		}
+	}
+}

+ 37 - 0
Native.Animation/Data/Vector3Data.h

@@ -0,0 +1,37 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace Data
+				{
+					public value struct Vector3Data
+					{
+					public:
+						float X, Y, Z;
+					};
+				}
+			}
+		}
+	}
+}

+ 37 - 0
Native.Animation/Data/Vector4Data.h

@@ -0,0 +1,37 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace Data
+				{
+					public value struct Vector4Data
+					{
+					public:
+						float X, Y, Z, W;
+					};
+				}
+			}
+		}
+	}
+}

+ 45 - 0
Native.Animation/Graphics/VertexTypes/VertexIndicesWeightsPositionNormal.h

@@ -0,0 +1,45 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+#include "Data/Int4Data.h"
+#include "Data/Vector4Data.h"
+#include "Data/Vector3Data.h"
+
+using namespace tainicom::Aether::Native::Animation::Data;
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				namespace VertexTypes
+				{
+					public value struct VertexIndicesWeightsPositionNormal
+					{
+					public:
+						Int4Data BlendIndices;
+						Vector4Data BlendWeights;
+						Vector3Data Position;
+						Vector3Data Normal;
+					};
+				}
+			}
+		}
+	}
+}

+ 41 - 0
Native.Animation/VertexPositionNormalTextureData.h

@@ -0,0 +1,41 @@
+//   Copyright 2015-2016 Kastellanos Nikolaos
+//
+//   Licensed under the Apache License, Version 2.0 (the "License");
+//   you may not use this file except in compliance with the License.
+//   You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+//   Unless required by applicable law or agreed to in writing, software
+//   distributed under the License is distributed on an "AS IS" BASIS,
+//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//   See the License for the specific language governing permissions and
+//   limitations under the License.
+
+#pragma once
+#include "Data/Vector4Data.h"
+#include "Data/Vector3Data.h"
+#include "Data/Vector2Data.h"
+
+using namespace tainicom::Aether::Native::Animation::Data;
+
+
+namespace tainicom
+{
+	namespace Aether
+	{
+		namespace Native
+		{
+			namespace Animation
+			{
+				public value struct VertexPositionNormalTextureData
+				{
+				public:
+					Vector3Data Position;
+					Vector3Data Normal;
+					Vector2Data TextureCoordinate;
+				};
+			}
+		}
+	}
+}

+ 6 - 0
Native.Animation/pch.cpp

@@ -0,0 +1,6 @@
+//
+// pch.cpp
+// Include the standard header and generate the precompiled header.
+//
+
+#include "pch.h"

+ 13 - 0
Native.Animation/pch.h

@@ -0,0 +1,13 @@
+//
+// pch.h
+// Header for standard system include files.
+//
+
+#pragma once
+
+//#include <wrl/client.h>
+//#include <d3d11.h>
+//#include <d3d11_1.h>
+//#include <DirectXMath.h>
+//#include <memory>
+//#include <agile.h>

+ 8 - 0
README.md

@@ -4,7 +4,15 @@ MonoGame Content Importers, Shaders, etc
 
 ## Content Importers
 
+* 'Animation' - Import animations from a Model.
+* 'GPU AnimatedModel' - Import an animated Model.
+* 'CPU AnimatedModel' - Import an animated Model to be animated by the CPU. Based on DynamicModelProcessor, the imported asset is of type Microsoft.Xna.Framework.Graphics.Model where the VertexBuffer is replaced by a CpuAnimatedVertexBuffer. CpuAnimatedVertexBuffer inherits from DynamicVertexBuffer.
 * 'DDS Importer' - Import of DDS files (images, Cubemaps). Supports conversion from DTX to Color (ex. import DTX cubemaps for Android that doesn't support DXT compressed cubemaps).
 * 'RawModelProcessor' - Import 3D Models with a raw copy of Vertex/Index data for platforms that don't support GetData().
 * 'DynamicModel' - Base Processor to customize the build in Model. It allows to modify
 VertexBuffer & IndexBuffers, make them Dynamic and WriteOnly.
+
+## tainicom.Aether.Animation
+
+Play animated 3D models and support for CPU animation.
+CPU animation is optimized using unsafe code, writing directly to mapped VertexBuffer memory using reflection (DirectX) and unmanaged/C++ code (WP8.0). 

BIN
bin/Release/Portable/Aether.Animation.dll


BIN
bin/Release/Portable/Aether.Content.Pipeline.AnimationImporters.dll


BIN
bin/Release/W10/Aether.Animation.dll


BIN
bin/Release/W10/Aether.Animation.pri


+ 33 - 0
bin/Release/W10/Aether.Animation/Properties/Aether.Animation.rd.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    This file contains Runtime Directives, specifications about types your application accesses
+    through reflection and other dynamic code patterns. Runtime Directives are used to control the
+    .NET Native optimizer and ensure that it does not remove code accessed by your library. If your
+    library does not do any reflection, then you generally do not need to edit this file. However,
+    if your library reflects over types, especially types passed to it or derived from its types,
+    then you should write Runtime Directives.
+
+    The most common use of reflection in libraries is to discover information about types passed
+    to the library. Runtime Directives have three ways to express requirements on types passed to
+    your library.
+
+    1.  Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
+        Use these directives to reflect over types passed as a parameter.
+
+    2.  SubTypes
+        Use a SubTypes directive to reflect over types derived from another type.
+
+    3.  AttributeImplies
+        Use an AttributeImplies directive to indicate that your library needs to reflect over
+        types or methods decorated with an attribute.
+
+    For more information on writing Runtime Directives for libraries, please visit
+    http://go.microsoft.com/fwlink/?LinkID=391919
+-->
+<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
+  <Library Name="Aether.Animation">
+
+  	<!-- add directives for your library here -->
+
+  </Library>
+</Directives>

BIN
bin/Release/W8_1/Aether.Animation.dll


BIN
bin/Release/W8_1/Aether.Animation.pri


BIN
bin/Release/WP7_1/Aether.Animation.dll


BIN
bin/Release/WP8/ARM/Aether.Animation.dll


BIN
bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.dll


BIN
bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.exp


BIN
bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.lib


BIN
bin/Release/WP8/ARM/tainicom.Aether.Native.Animation.winmd


BIN
bin/Release/WP8/x86/Aether.Animation.dll


BIN
bin/Release/WP8/x86/tainicom.Aether.Native.Animation.dll


BIN
bin/Release/WP8/x86/tainicom.Aether.Native.Animation.exp


BIN
bin/Release/WP8/x86/tainicom.Aether.Native.Animation.lib


BIN
bin/Release/WP8/x86/tainicom.Aether.Native.Animation.winmd


BIN
bin/Release/Windows.XNA/Aether.Animation.dll


BIN
bin/Release/Windows.XNA/Aether.Content.Pipeline.AnimationImporters.dll


BIN
bin/Release/Windows/Aether.Animation.dll


BIN
bin/Release/Windows/Aether.Content.Pipeline.AnimationImporters.dll


+ 2 - 0
packages/repositories.config

@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <repositories>
+  <repository path="..\Animation\packages.config" />
+  <repository path="..\Content.Pipeline\AnimationImporter\packages.config" />
   <repository path="..\Content.Pipeline\DDSImporter\packages.config" />
   <repository path="..\Content.Pipeline\GraphicsImporters\packages.config" />
   <repository path="..\Content.Pipeline\RawModelProcessor\packages.config" />