使用 XNA 创建游戏/数学物理/角色动画
在这里,我们必须区分骨骼动画和关键帧动画。重点是展示如何使用 XNA 实现这两种类型的动画。应特别注意 XNA 框架提供的约束(例如,着色器 2.0 模型不允许超过 59 个关节)。
动画仅仅是一种错觉——它是由一系列图像创建的。每个图像都与前一个略有不同。我们只是将这样一组图像感受为变化的场景。
呈现动画最常见的方法是作为一部电影或视频程序,尽管还有其他方法。 [1]
在计算机动画中,它有两种形式:一种更“经典”的,源自翻书本的已知关键帧动画;另一种是骨骼动画,默认情况下,它来自 3D 动画。
关键帧动画是一种动画技术,最初用于经典卡通中。关键帧定义了动画的起点和终点。它们填充了所谓的中间帧或过渡帧。
在传统的关键帧动画中,例如用于手绘动画片,高级艺术家(或关键艺术家)将绘制关键帧。(仅动画的重要图片)在粗略动画测试之后,他将其交给助手,助手进行必要的“中间帧和清理”。
在计算机图形学中,它与卡通的概念相同:关键帧由用户创建,中间帧由计算机补充。“关键帧”保存对象的位置、旋转和缩放等参数。计算机对后续的中间帧进行插值。
一个对象将从一个角移动到另一个角。第一个关键帧显示对象位于左上角,第二个关键帧显示对象位于右下角。两者之间的所有内容都进行了插值。
-
起始关键帧 -
结束关键帧 -
完成的动画
前面的部分提到了一些关键帧动画支持多种插值方法。动画的插值描述了动画在其持续时间内如何在值之间过渡。通过选择与动画一起使用的关键帧类型,可以定义该关键帧段的插值方法。有三种不同的插值方法:线性、离散和样条。
[2]
各个片段以恒定的速度通过。
使用离散插值,动画函数在值之间跳转,而不进行插值。
http://msdn.microsoft.com/uk-en/library/ms742524.aspx
待编辑各个参数存储在一个列表中。如果现在有了时间线的长度和元素的数量,就可以从中推断出在何时可以访问哪个关键帧。(通过增加时间线计数器,然后调用相应关键帧,就像例如在连环画中,其中 1 页是 1 个关键帧,翻到相应的页一样)。
下面显示了一个类,可以用它来实现这一点。源代码在下面可以找到。
一个小的关键帧动画类
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace PuzzleGame
{
/// <summary>
/// Keyframe animation helper class.
/// </summary>
public class Animation
{
/// <summary>
/// List of keyframes in the animation.
/// </summary>
List<Keyframe> keyframes = new List<Keyframe>();
/// <summary>
/// Current position in the animation.
/// </summary>
int timeline;
/// <summary>
/// The last frame of the animation (set when keyframes are added).
/// </summary>
int lastFrame = 0;
/// <summary>
/// Marks the animation as ready to run/running.
/// </summary>
bool run = false;
/// <summary>
/// Current keyframe index.
/// </summary>
int currentIndex;
/// <summary>
/// Construct new animation helper.
/// </summary>
public Animation()
{
}
/// <summary>
/// Add a keyframe to the animation.
/// </summary>
/// <param name="time">Time for keyframe to happen.</param>
/// <param name="value">Value at keyframe.</param>
public void AddKeyframe(int time, float value)
{
Keyframe k = new Keyframe();
k.time = time;
k.value = value;
keyframes.Add(k);
keyframes.Sort(delegate(Keyframe a, Keyframe b) { return a.time.CompareTo(b.time); });
lastFrame = (time > lastFrame) ? time : lastFrame;
}
/// <summary>
/// Reset the animation and flag it as ready to run.
/// </summary>
public void Start()
{
timeline = 0;
currentIndex = 0;
run = true;
}
/// <summary>
/// Update the animation timeline.
/// </summary>
/// <param name="gameTime">Current game time.</param>
/// <param name="value">Reference to value to change.</param>
public void Update(GameTime gameTime, ref float value)
{
if (run)
{
timeline += gameTime.ElapsedGameTime.Milliseconds;
value = MathHelper.SmoothStep(keyframes[currentIndex].value, keyframes[currentIndex + 1].value
(float)timeline / (float)keyframes[currentIndex + 1].time);
if (timeline >= keyframes[currentIndex + 1].time && currentIndex != keyframes.Count) { currentIndex++; }
if (timeline >= lastFrame) { run = false; }
}
}
/// <summary>
/// Represents a keyframe on the timeline.
/// </summary>
public struct Keyframe
{
public int time;
public float value;
}
}
}
资源: http://tcsavage.org/2011/04/keyframe-animation-in-xna/
http://xnanimation.codeplex.com/
http://msdn.microsoft.com/uk-en/library/ms742524.aspx
http://en.wikipedia.org/wiki/Animation
http://msdn.microsoft.com/uk-en/library/ms752312.aspx
http://tcsavage.org/2011/04/keyframe-animation-in-xna/
http://de.wikipedia.org/wiki/Spline-Interpolation
http://en.wikipedia.org/wiki/Spline_interpolation
ARei
骨骼动画是计算机动画中的一种技术,它由两部分组成:皮肤部分(称为网格)和骨骼部分(称为绑定)。皮肤表示为表面的组合,骨骼表示为骨骼的组合。这些骨骼像真正的骨骼一样相互连接,并且是分层集的一部分。结果是,您移动一根骨骼,其他应该相互作用的骨骼也会随之移动。骨骼以相同的方式动画化网格(表面)。虽然此技术通常用于动画化人类或更普遍地用于有机建模,但它仅用于使动画过程更直观,并且可以使用相同的技术来控制任何对象的变形,例如建筑物、汽车等。
这种技术对动画师非常有用,因为在所有动画系统中,这种简单的技术都是一个移植版本。因此,他们不需要任何复杂的算法来动画化模型。如果没有这种技术,几乎不可能将网格与骨骼结合起来进行动画化。
http://en.wikipedia.org/wiki/Skeletal_animation
绑定是创建骨骼以动画化模型的技术。这个骨骼由骨骼(绑定)和关节组成,关节是骨骼之间的连接。通常,您将这些骨骼和关节与真实骨骼的特性相关联。例如,您首先创建上腿作为骨骼,然后创建膝盖作为关节。
http://de.wikipedia.org/wiki/Rigging_%28Animation%29
蒙皮(Skinning)是一种将皮肤材质赋予骨骼框架(骨骼)的技术,皮肤的运动如同骨骼的运动。蒙皮技术在绑定(Rigging)之后进行。蒙皮和绑定的区别在于,蒙皮是模型(你的模型)的视觉变形。能够设置每个单独的表面是一个很有用的特性,这在诸如手臂运动之类的场景中非常有用。即使你移动你的手臂(或模型的手臂),你的皮肤(模型的表面)会以不同的方式与运动交互,这取决于位置,例如你的肘部内侧或肘部外侧。在此背景下,还可以模拟肌肉运动。http://de.wikipedia.org/wiki/Skinning
- 骨骼:4.0版本中最多可达59到79根。
- 多边形:取决于硬件。
- Motion Builder http://www.autodesk.de/adsk/servlet/pc/index?id=15013088&siteID=403786
- 3ds Max http://www.autodesk.de/adsk/servlet/pc/index?id=14642267&siteID=403786
- Maya http://www.autodesk.de/adsk/servlet/pc/index?siteID=403786&id=14657512
在XNA中,获取模型动画的最简单方法是在3D开发工具中创建动画。这些动画会自动成为导出的.x文件或.fbx文件的一部分。
一个展示XNA中动画处理的简单方法是来自http://create.msdn.com/en-US/education/catalog/sample/skinned_model的一个不错的演示。
首先我们需要一个模型和一个动画。
Model currentModel;
AnimationPlayer animationPlayer;
下一步是更新LoadContent()方法。
protected override void LoadContent()
{
// Load the model.
currentModel = Content.Load<Model>("dude");
// Look up our custom skinning information.
SkinningData skinningData = currentModel.Tag as SkinningData;
if (skinningData == null)
throw new InvalidOperationException
("This model does not contain a SkinningData tag.");
// Create an animation player, and start decoding an animation clip.
animationPlayer = new AnimationPlayer(skinningData);
AnimationClip clip = skinningData.AnimationClips["Take 001"];
animationPlayer.StartClip(clip);
}
如果将clib变量设置为数组,可以保存许多不同的动画。
AnimationClip clips= new AnimationClip[skinningData.AnimationClips.Keys.Count];
clips[0] = skinningData.AnimationClips["moveleft"];
clips[1] = skinningData.AnimationClips["moveright"];
clips[2] = skinningData.AnimationClips["jump"];
之后就可以轻松地调用不同的动画,例如通过按下跳跃键。
animationPlayer.StartClip(clip[2]);
其他动画也适用相同的方法。
-
不同的运动
http://de.wikipedia.org/wiki/Skinning
http://create.msdn.com/en-US/education/catalog/sample/skinned_model
http://de.wikipedia.org/wiki/Rigging_%28Animation%29
http://www.mit.edu/~ibaran/autorig/
http://www.mixamo.com/c/auto-rigger
http://www.der-softwareentwickler-blog.de/2011/05/30/video-tutorials-rigging-und-animation/
http://www.digitalproducer.com/2004/01_jan/tutorials/01_26/maya_rigging.htm
FixSpix
在本章中,我们学习了两种不同的角色动画方法。首先是关键帧动画,然后是骨骼动画。这两种技术在XNA中非常重要。
在这个语境下,“更好”这个词用得不太合适,让我们用“在什么情况下更好”来替换“更好”。很简单……在3D场景中使用骨骼动画,在2D场景中使用关键帧动画。
fixspix
A.Rei 和 FixSpix