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

  • 相关阅读:
    metal的gpu query
    体积雾 global fog unity 及改进
    hdr rt format对颜色的影响
    unity deferred lighting
    unity linear space时 photoshop blend的正确设置
    unity linear work flow
    一些数据 bandwidth之类
    deferred rendering with msaa
    unity 显示mipmaplevel
    【转】在C#中使用SendMessage
  • 原文地址:https://www.cnblogs.com/yaoling1997/p/10009683.html
Copyright © 2011-2022 走看看