调了一上午才发现是把下面这个函数:

private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector3> vertices)//切割三角形
{
float re = -1;
int p = 0;
for (int i = 0; i < 3; i++)
{
int a = triangle[i];
int b = triangle[(i + 1) % 3];
var len = (vertices[b] - vertices[a]).magnitude;
if ( len > re)
{
p = i;
re = len;
}
}
outTriangle = new int[] { triangle[p],triangle[(p+1)%3],triangle[3-p- (p + 1) % 3] };//最长边的两个点以及该边所对的点的标号
return re;
}

  写成了:

private float DivideTriangle(int []triangle,out int []outTriangle,List<Vector3> vertices)//切割三角形
{
float re = -1;
int p = 0;
for (int i = 0; i < 3; i++)
{
int a = triangle[i];
int b = triangle[(i + 1) % 3];
var len = (vertices[b] - vertices[a]).magnitude;
if ( len > re)
{
p = i;
re = len;
}
}
outTriangle = new int[] { p,(p+1)%3,3-p- (p + 1) % 3 };//最长边的两个点以及该边所对的点的标号
return re;
}

  简直被自己蠢哭。不过改了之后还是不太对,三角形变多了,但是模型被我弄得支离破碎,颇有艺术美感...





  看了半天都没发现到底哪里有问题,直到我把

var t1 = new int[] { outTriangle[0], outTriangle[2], tot };
var t2 = new int[] { outTriangle[1], outTriangle[2], tot };

  改成了

var t1 = new int[] { outTriangle[0], tot, outTriangle[2] };
var t2 = new int[] { outTriangle[1], outTriangle[2], tot};

  才变正常了。仔细观察发现貌似三角形顶点的顺序不能瞎给,得统一是逆时针的才行,下面那一种就是两个三角形的顶点顺序都是逆时针的,tot是新加的顶点的标号,[2]是最长边所对点。

  现在终于正常了:







  在ContactPointsPanel里添加了一个clear按钮,一点就能删除所有接触点,方便又快捷!





  然后来看看一倍和三倍的区别,先是一倍的,有14740个点:



  三倍的,稍微精确一点,只有11445个点,少了3000多个冗余点。



  记录一下椅子和人的位置信息,以后也按这个数据测下:

人:

-0.25 -0.25 -0.1

90 0 0

1 1 1

椅子:

0 0 0

0 60 0

1 1 1

  有时候计算接触点的时候不知道要等多久,所以弄个进度条再好不过了。

  又调整了一下算法,先判断两个物体包围盒是否相交,再枚举一个物体所有三角面片包围盒,若不和另一个物体包围盒相交直接枚举下一个三角面片,否则和另一个物体所有三角面片包围盒求交。效率是稍微提高了点,不过为啥准确度也会提高就不得而知了,椅子只有一倍三角形的时候竟然只有8440多个接触点,三倍时只有4807个接触点,看上去少了很多冗余接触点的样子。





  还是很好玩的。



  突然想测一测这玩意的极限,首先拿人的模型来试试,先是1倍三角形:



  2.5倍:



  结果3倍就爆炸了,也没有提示运行错误,不知道啥原因:



  15倍就更看不得了:



  然后是这个简陋的椅子,先是1倍:



  3倍:



  6倍:



  10倍:



  15倍都没爆炸:



  以为这就是极限吗?不存在的。

  76倍:



  219倍:



  290.5倍:



  297.5倍,终于爆了哈哈哈!



  像我们程序员就得有刨根问底的精神!发现差不多将近20w左右的三角形顶点就爆了。

  不过怎么改代码都无济于事,这应该是unity的上限,超过了这个值就GG了!

  这个 yield return 不要经常调用,不然运算起来会慢出翔来。于是我设置了进度条更新的间隔为0.05(最大值为1),超过这个间隔才调用yield return来显示一下:

var tmpV = sliderValueFz / (unselectedObjList.Count * totalSelectedObjTriangleNum);
if (tmpV- sliderGCP.value >= 0.05) {
sliderGCP.value = tmpV;//更新进度条的值
yield return new WaitForSeconds(0);
}

  突然发现一个严峻的问题,那个调用物体bounds来优化的方法写错了,我竟然直接用的mesh.bounds,然而应该是用变换后的点的包围盒bounds来优化,o(︶︿︶)o 唉~再一次被自己蠢哭T_T

  更正之后又被打回原形,先是1倍的,耗时2分04秒,共14740个接触点:



  然后是3倍的,耗时1分34秒,共11445个接触点:



  最后是10倍的,耗时1分40秒,共个9885个接触点:

  至于为什么椅子三角面片变多耗时反而变少?应该是算出来的冗余接触点少了,显示出来的物体少了,自然耗时变少了。



  拉近点看,感觉效果还不错:









  不过计算时间这么慢肯定是不行的,之后想办法用k-d树或者瞎搞算法来优化一下计算的复杂度好了。另外那个Clear接触点按钮要是点数太多可能光清除就要一分钟左右,贼慢无比。

  鉴于今天是周五晚上,就提前进入欢乐时光吧!

3dContactPointAnnotationTool开发日志(十六)的更多相关文章

  1. 3dContactPointAnnotationTool开发日志(六)

      一种可行的思路就是枚举一个模型的三角面片,然后判断三角形是否与另一个物体相交即可.为了让效果更好我想只渲染模型的线框.   在网上查了半天好像Unity里都没有自带的方便的渲染线框的方式,我又自己 ...

  2. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...

  3. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

  4. 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)

    转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...

  5. 3dContactPointAnnotationTool开发日志(三十)

      在vs2017里生成opencv时遇到了无法打开python27_d.lib的问题,具体解决请看这个,不过我用的是方法2,python37_d.lib找不到同理.   Windows下可以用的op ...

  6. 3dContactPointAnnotationTool开发日志(二六)

      之前给老师看了看我的毕设,老师觉得操作太复杂了,要能像3ds max里那样可以拖动物体的轴进行平移,沿着显示的圆圈旋转以及缩放啥的.说白了就是在Unity3d的Game视图显示出Scene视图里的 ...

  7. 3dContactPointAnnotationTool开发日志(二十)

      为了使工具更人性化,我又在每个status的text上绑了个可以拖拽实现值改变的脚本,但是不知道为啥rotx那个值越过+-90范围后连续修改就会产生抖动的现象,试了很多方法也没能弄好,不过实际用起 ...

  8. 3dContactPointAnnotationTool开发日志(十九)

      增加了输出接触点信息到文件功能.

  9. 3dContactPointAnnotationTool开发日志(十八)

      今天实现了tab效果,按tab键可以在status面板的各个输入框内来回切换,参考Unity3D - UGUI实现Tab键切换输入框.按钮(按Tab键切换高亮显示的UI)

随机推荐

  1. layui sleect获取value值

    <div class="layui-form-item"> <label for="username" class="layui-f ...

  2. linux 操作之压缩与解压

    压缩与解压 压缩格式:zip , rar , 7z , iso , exe gzip (以下是命令操作) gzip [文件名]  #压缩成gz格式 , 原来的文件消失 , 不支持目录. bzip2 - ...

  3. PHP基础1--环境搭建

    主要: 环境搭建 站点配置 环境搭建 web运行流程: 1. 浏览器输入地址,回车(发送请求) 2. 根据规则找到对应web服务器.规则如下: 首先在本机hosts文件中找对应IP hosts位置: ...

  4. Linux的基础命令大全

    linux的基础命令大全 1.shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口(命令解释器) ls -al /bin/sh   ls -al /bin/bash 查看这些shell的 ...

  5. python学习笔记:第7天 深浅拷贝

    目录 1. 基础数据类型补充 2. set集合 3. 深浅拷贝 1. 基础数据类型补充 (1)join方法 join方法是把一个列表中的数据进行拼接,拼接成字符串(与split方法相反,split方法 ...

  6. 20145209 2016-2017-2 《Java程序设计》第4周学习总结

    20145209 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 继承是面向对象最显著的一个特性.继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性 ...

  7. Git项目的目录结构

     branch是分支   trunk是主干   bug修正和新功能的添加一般在branch进行 测试好了没问题了就可以合并到trunk 每隔一段时间就可以打包成一个版本放到tags 用于发布的版本一般 ...

  8. WPF 为 PasswordBox 控件添加水印,最低级版

    原因也很直接,老板需要,一开始为TextBox发愁,就找了这个控件凑合用,至于版权什么的,内部工具也不卖钱,而且我不懂英文,也就无视了: Extended WPF Toolkit™ Community ...

  9. java 程序文本文档形式的编写,编译,及运行

    一.程序的编写 1.在指定路径下新建文本文档 如在f盘新建了一个名为demo的文件夹,在该文件夹路径下新建了一个文本文档 2.打开文本文档,进行编写,例如: 3.保存 选择文件另存为,文件名称为你创建 ...

  10. Tomcat - 远程调试配置

    复制一份startup.bat,更名为“startup-debug”. 替换内容如下: call "%EXECUTABLE%" start %CMD_LINE_ARGS% 替换为 ...