C# 使用DrawUserPrimitive并将其与一些矩阵进行转换
这里是我所拥有的:一个定制的C# 使用DrawUserPrimitive并将其与一些矩阵进行转换,c#,matrix,xna,primitive,C#,Matrix,Xna,Primitive,这里是我所拥有的:一个定制的DrawableGameComponent,其中包含一些我称之为DrawUserPrimitve的子级。每个子项都可以包含子项等。 我在每个组件中存储一个描述其形状的顶点列表,并存储一个矩阵来存储其相对位置(以及最终的变换)。 因此,在我“DrawUserPrimitive”之前,我需要“应用”一个矩阵。该矩阵必须是组件的变换及其父级和父级的父级等的乘积 这个系统允许我保持组件变量的独立性,如果我理解正确,这就是方法 为此,我在XNA中看到了basicefect对象,
DrawableGameComponent
,其中包含一些我称之为DrawUserPrimitve
的子级。每个子项都可以包含子项等。
我在每个组件中存储一个描述其形状的顶点列表,并存储一个矩阵来存储其相对位置(以及最终的变换)。
因此,在我“DrawUserPrimitive
”之前,我需要“应用”一个矩阵。该矩阵必须是组件的变换及其父级和父级的父级等的乘积
这个系统允许我保持组件变量的独立性,如果我理解正确,这就是方法
为此,我在XNA中看到了basicefect
对象,我可以用它应用一些矩阵。因此,我试图用我的组件.Transformation
(矩阵
)乘以基本效果.World
)
所以我应该继续询问,但现在它没有给我我所期待的结果。我想知道我是否选择了好的方法来做这件事。我看到两个系统的结果相同:
一些代码用于说明:
public void override Draw(GameTime gameTime){
Game.basicEffect.World *= Transformation;
foreach(var child in this.Children){
child.Draw(gameTime);
}
Game.basicEffect.World *= Matrix.Invert(Transformation);
}
多亏@nico schertler的评论,我才得以成功 使用矩阵堆栈存储“铅笔”的当前状态是解决方案。但有一点我遗漏了: 每次深入对象层次(例如:机器人的手臂)时,将新矩阵乘以当前矩阵,并将得到的矩阵放到堆栈上。因此,堆栈始终具有(在其顶部)必须用于绘制的矩阵。当您处理完这个对象并返回到它的父对象时,只要弹出一次,您就可以检索用于它的矩阵。 (我正在堆叠每个矩阵,然后每次都重新计算要使用的结果矩阵。) 备注:请注意乘法的顺序。矩阵的乘法不是可交换的!始终将子矩阵乘以当前矩阵
internal void HandleDraw(GameTime gameTime)
{
Draw(gameTime);
if (Children.Count > 0)
{
// draw children
foreach (Control child in Children.Values.OfType<Control>())
{
if (child.Visible)
{
Engine.CurrentTransformation.Push(Matrix.Multiply(
child.Transformation,
Engine.CurrentTransformation.Peek()
));
child.HandleDraw(gameTime);
Engine.CurrentTransformation.Pop();
}
}
}
}
internalvoid HandleDraw(游戏时间游戏时间)
{
抽签(游戏时间);
如果(Children.Count>0)
{
//画孩子
foreach(Children.Values.OfType()中的控件子级)
{
if(子级可见)
{
引擎。电流转换。推送(矩阵。乘法(
儿童转化,
Engine.CurrentTransformation.Peek()
));
儿童手绘(游戏时间);
Engine.CurrentTransformation.Pop();
}
}
}
}
结果中到底出了什么问题?根据变换的不同,使用World=Transformation*World
计算World
矩阵可能更合理。我需要对其进行更多测试,以查看,但使用2个深度级别,第2个是错误的,但第3个是好的。这在我的代码中看起来确实是个问题,而不是在逻辑中。但我想问的是,是否有一个通用的解决方案可以使用。通常,像这样的场景图是用矩阵堆栈实现的。导航到子级时,将世界矩阵推到堆栈顶部,然后使用变换矩阵进行修改。当作用域离开子级时,将删除顶部矩阵,并将世界矩阵恢复为该值。因此,您不必使用昂贵的Invert
功能。但一般来说,如果所有的孩子行为都一样,代码也应该这样做。有关矩阵以及如何组合矩阵的更多信息,请参见此处:谢谢,我假设以这种方式执行操作而不是使用堆栈将获得更好的性能,但是如果您这样说,我将返回使用堆栈,因为它听起来也更干净。好吧,你加上这个方法,我就保留它。谢谢