zoukankan      html  css  js  c++  java
  • 3dContactPointAnnotationTool开发日志(十六)

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

    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;
    }
    

      简直被自己蠢哭。不过改了之后还是不太对,三角形变多了,但是模型被我弄得支离破碎,颇有艺术美感...
    1.png
    2.png
      看了半天都没发现到底哪里有问题,直到我把

    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]是最长边所对点。
      现在终于正常了:
    2t.png
    3.png
    4.png
      在ContactPointsPanel里添加了一个clear按钮,一点就能删除所有接触点,方便又快捷!
    5.png
    6.png
      然后来看看一倍和三倍的区别,先是一倍的,有14740个点:
    7.png
      三倍的,稍微精确一点,只有11445个点,少了3000多个冗余点。
    8.png
      记录一下椅子和人的位置信息,以后也按这个数据测下:
    人:
    -0.25 -0.25 -0.1
    90 0 0
    1 1 1
    椅子:
    0 0 0
    0 60 0
    1 1 1
      有时候计算接触点的时候不知道要等多久,所以弄个进度条再好不过了。
      又调整了一下算法,先判断两个物体包围盒是否相交,再枚举一个物体所有三角面片包围盒,若不和另一个物体包围盒相交直接枚举下一个三角面片,否则和另一个物体所有三角面片包围盒求交。效率是稍微提高了点,不过为啥准确度也会提高就不得而知了,椅子只有一倍三角形的时候竟然只有8440多个接触点,三倍时只有4807个接触点,看上去少了很多冗余接触点的样子。
    9.png
    10.png
      还是很好玩的。
    11.gif
      突然想测一测这玩意的极限,首先拿人的模型来试试,先是1倍三角形:
    10_.png
      2.5倍:
    11.png
      结果3倍就爆炸了,也没有提示运行错误,不知道啥原因:
    12.png
      15倍就更看不得了:
    13.png
      然后是这个简陋的椅子,先是1倍:
    14.png
      3倍:
    15.png
      6倍:
    16.png
      10倍:
    17.png
      15倍都没爆炸:
    18.png
      以为这就是极限吗?不存在的。
      76倍:
    19.png
      219倍:
    20.png
      290.5倍:
    21.png
      297.5倍,终于爆了哈哈哈!
    22.png
      像我们程序员就得有刨根问底的精神!发现差不多将近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个接触点:
    23.png
      然后是3倍的,耗时1分34秒,共11445个接触点:
    24.png
      最后是10倍的,耗时1分40秒,共个9885个接触点:
      至于为什么椅子三角面片变多耗时反而变少?应该是算出来的冗余接触点少了,显示出来的物体少了,自然耗时变少了。
    25.png
      拉近点看,感觉效果还不错:
    26.png
    27.png
    28.png
    29.png
      不过计算时间这么慢肯定是不行的,之后想办法用k-d树或者瞎搞算法来优化一下计算的复杂度好了。另外那个Clear接触点按钮要是点数太多可能光清除就要一分钟左右,贼慢无比。
      鉴于今天是周五晚上,就提前进入欢乐时光吧!
    1_18.jpg

  • 相关阅读:
    为什么要用where 1=1?
    idea中.ignore忽略提交文件到Git的使用
    IDEA开发工具使用 git 创建项目、拉取分支、合并分支
    Linux常用命令及Linux系统根目录下各个目录的作用
    Xshell和Xftp的安装与使用教程
    Moco使用简单指导
    这样写会有什么问题呢?
    grunt学习笔记
    基于nginx的WebSocket反向代理
    maven依赖查找方法
  • 原文地址:https://www.cnblogs.com/yaoling1997/p/10009683.html
Copyright © 2011-2022 走看看