我开始制作各种3D文件格式的查看器,我之前使用的那些格式没有出现问题,直到我来到PRC文件(这是可以嵌入到PDF中的支持的3D格式之一).我可以从PDF中提取所有数据并显示那些以无损方式编码的模型,但是当我尝试解码他们所谓的“高度压缩的Tesselations”时,我遇到了一个我认为是精度问题的问题,但是我不太清楚如何解决它或在哪里寻找解决方案.
本质上它是一种有损格式,它们所做的是采用原始(基于浮点的)顶点坐标,并使用公差值 – 将这些坐标除以它并将结果四舍五入到最接近的整数.当遍历网格以编码所有三角形时,只有第一个三角形存储绝对值,其余三角形总是基于前一个相邻三角形并构建一个局部坐标系统,共享边缘的中间是原点,向量共享边缘是x轴,三角形法线是z轴.然后,y轴只是那些的叉积的结果,并且使用这3个局部轴,它存储新三角形的第三点的坐标.
我的系统通常都在工作,对于没有太多三角形的简单模型,它也可以很好地工作,但是一旦模型变得更复杂,结果就会出错,并且看起来距离最后一个绝对坐标越远,越大偏差是.
在下面的示例图片中,您可以在左侧看到预期结果(在Adobe Reader中呈现),在右侧看到.这个模型基本上有一个内部和一个我们的部分,在这种情况下,内部部分由一个绝对三角形后跟相对的部分组成(而外部部分主要由绝对坐标构成,这就是为什么它在我看来是正确的),以及从内圈到外圈的遍历.在Adobe渲染中,您可以看到线条应该或多或少地径向指向外部,而在我的渲染中,从大约第四个“圆圈”开始,事情开始出错:
Expected result on the left, my result on the right
我目前仍然坚持这一点,并不太清楚如何解决这个问题.我发现做一些小改动(例如将double改为float或反之亦然)会对结果产生巨大影响,很快就会变得更糟.但基本上我遵循规范,它说使用双精度浮点变量进行所有计算,并且还使用他们自己的计算平方根的实现(归一化轴所需).例如,通过使用他们的sqrt函数而不是普通数学库中的函数,结果已经更好(没有它,我甚至不会像上面显示的图片那样接近).
但我想知道是否存在某种我不理解的数学方面?或者其他一些可能有帮助的想法?同样在该特定模型中,所有值似乎都足够大,因此由于缺乏浮点格式的精度而不应该是数据丢失的问题.此外,在规范中也存在特殊情况,其中如果y轴或z轴太短(< FLT_EPSILON),则必须使用另一种解决方案,但在该特定模型中再次使用if info from the PRC spec on how to encode points
任何输入都将非常感激.如果需要,我可以提供更多数据,信息,示例,规格摘录等.
最佳答案 根据我之前使用PRC的经验,这看起来非常像是在错误的地方应用了对象偏移(我认为它被称为原始偏移)的问题.
由于每个新顶点都基于前一个顶点,使用基于最后三角形的局部坐标系来获得新三角形的第三个点,因此这种格式的错误似乎非常快速地增长.有损格式也无济于事.在我原来的方法中,我尝试计算所有三角形,然后在末尾应用偏移量将其放入正确的位置,导致出现与您的相似的问题.
通过更改它以将偏移应用于“绝对顶点”(即那些未经修改的读取,并在启动新三角形时充当“锚点”)我能够解决问题.
当然,作为中华人民共和国,你可能还需要解决各种其他事情,我不知道你是否已经在这里.官方ISO规范中的很多东西都是完全错误的,其他的没有提到(例如当你应该重新计算法线而不是从文件中获取明确的法线时),像霍夫曼压缩这样的东西有点错误等等.如果你能避免它,然后最好不要实现它;-)