Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在XNA中访问模型的面?_C#_Xna_Collision Detection - Fatal编程技术网

C# 如何在XNA中访问模型的面?

C# 如何在XNA中访问模型的面?,c#,xna,collision-detection,C#,Xna,Collision Detection,我正在为一款使用微软XNA框架4.0版编写的游戏进行碰撞检测。在内容框架加载模型后尝试访问模型本身时,我可以访问一个“ModelMesh”列表,并为每个模型访问一个MeshPart列表,但这些部分似乎只有诊断数据,如顶点数。对于模型的实际人脸数据发生了什么,我完全感到困惑 我试图实现球体扫描/平面碰撞——也就是说,我有一个球在移动,我想在球移动时测试与多边形的碰撞。我需要一种方法来定义所有要测试的多边形,对我来说,将碰撞贴图定义为一个简化的网格是有意义的,我与我的实际图形对象并行设计以用于碰撞,

我正在为一款使用微软XNA框架4.0版编写的游戏进行碰撞检测。在内容框架加载模型后尝试访问模型本身时,我可以访问一个“ModelMesh”列表,并为每个模型访问一个MeshPart列表,但这些部分似乎只有诊断数据,如顶点数。对于模型的实际人脸数据发生了什么,我完全感到困惑

我试图实现球体扫描/平面碰撞——也就是说,我有一个球在移动,我想在球移动时测试与多边形的碰撞。我需要一种方法来定义所有要测试的多边形,对我来说,将碰撞贴图定义为一个简化的网格是有意义的,我与我的实际图形对象并行设计以用于碰撞,但我完全不知道XNA的内容管道加载后我应该如何访问该信息


也许有一些见解?我整天都在搜索谷歌,但我找不到任何可能有用的东西,尽管我可能使用了错误的搜索词…

内置的XNA FBX/模型内容导入器和处理器处理“面”的方式与几乎所有建模程序处理“面”的方式相同,如顶点和索引列表。(顺便说一句,您的GPU本身也支持此方案,而现代游戏出于性能原因依赖于此。)

例如,考虑一个简单的两个三角形四边形。顶点可能是:

v0 (0,0,0)
v1 (1,0,0)
v2 (1,1,0)
v3 (0,1,0)
或者

要以“面”形式表示这一点,您需要一个与

三角形1(左上角):(0,0,0),(1,0,0),(0,1,0)=(v0,v1,v3)

三角形2(右下角):(1,0,0)、(1,1,0)、(0,1,0)=(v1、v2、v3)

这需要六个顶点记录

使用XNA本机结构,Vector3有三个元素,每个元素都是单精度浮点(4个字节),因此每个元素都是3*4=12个字节,您需要其中的六个元素,即72个字节

或者,您可以使用索引。除四个顶点外,还存储索引列表:

f1: 0,1,3
f2: 1,2,3
索引可以使用shorts(16位整数)存储。那么,让我们来看看区别:

无索引:两个面*3个顶点*3个组件(xyz)*每个4字节=2*3*3*4=72字节

索引:

顶点:4个顶点*3个组件每个*4字节每个组件=48字节

索引(每个三角形3个短路):6个索引*每个2字节=12字节

48+12=60,这对于非索引模型略小于72字节

这12个字节可能看起来不太多,除非你考虑100000个三角形的整个级别。此时,您将看到1.2MB的差异。尽管您的图形卡可能有2+GB的内存,但在主机RAM和GPU RAM之间来回移动这些数据是非常昂贵的

那么,如何获得这些数据呢

查看
Model.mesh[].MeshParts[].VertexBuffer.GetData()
Model.mesh[].MeshParts[].IndexBuffer.GetData()
。您可以使用这些方法提取顶点和索引,然后交叉引用两者以获得三角形列表

您不能直接访问
VertexBuffer
IndexBuffer
的元素,因为它们存储在GPU的RAM中-允许随机元素访问会将性能拖到接近负的速度

另外,请查看
GraphicsDevice.DrawIndexedPrimitives()
方法


如果有必要,我可以稍后发布一些示例代码。

值得注意的是:我遇到的每个教程似乎都在讨论对象与对象碰撞。由于该级别(a)是静态的,而且(b)很容易细分为较小的部分,因此我认为在该级别上执行每个多边形碰撞更有意义。如果这里有其他更可取的冲突处理方法,请在评论中随意提出,但这并不能解决主要问题--如何在XNA中获取人脸数据?我的答案是获取人脸数据,而不是冲突检测。当然,一旦你做到了这一点,构建一个BSP或任何东西都很容易,并且可以处理你的碰撞检测问题。另外,不要担心碰撞检测的“简化模型”。BSP将(理想情况下)使用静态树对冲突检测进行log-base-2(n)检查。因此,每64k三角形有16条10-20指令进行比较。它非常、非常快,不会成为您的性能瓶颈。好的,我大部分时间都遵循这一点。是否所有面都存储为三角形?比如,如果我抓取索引缓冲区,我可以安全地假设每3个索引值将定义一个新的面,还是需要某种方法来发现面中的点数?(我这里的意思是,如果我在模型中定义了四边形,它们是否会在发送到图形卡时自动转换为三角形?)。GPU不理解四边形。当你调用一个Device.Draw方法时,你给了它一个命令,告诉它你使用的是什么基元类型。直线列表、三角形列表或三角形带。没有四头肌,很好!还可以查看由Microsoft主办的app hub论坛。XNA开发人员在那里非常活跃。
f1: 0,1,3
f2: 1,2,3