[Laplace Deformation]拉普拉斯网格变形--Unity3D实现

这次Laplace Deformation的博客分为两个部分,理论实现

理论(含推导过程):https://blog.csdn.net/z136411501/article/details/107622967

以实现解最简单的拉普拉斯线性方程组为主,不引入加速求解,与旋转不变性,体积不变性。

实现Demo分为两类,基础变形静态的实现,与VR下动态的实现

程序源代码链接:https://pan.baidu.com/s/1R6siadh4vkxRB0tMP6WABg 提取码:hqdq 

(两份代码,静态与VR)

编译环境:

  • Unity3D 2017.4.34c1 
  • mathNet
  • VR额外配置:SteamVR+LeapMotion

一,实现Demo

静态:初始化一个20x20的mesh网格,将周围的vertex设为固定锚点,中间的单独黄色vertex设为移动锚点,向上移动(0, 1, 0)距离,其余vertex为变形区域。

扫描二维码关注公众号,回复: 14647261 查看本文章

VR动态:相同的网格,第一步确立改变的范围,将边缘处设为固定锚点,拖拽时,小球半径以内的所有点设为移动锚点。这里变形后的三角形太大,以至于有凹凸感,可加网格细分进行改善。(示意图因gif压缩保存导致色差)

二,代码解析

理论部分见另一篇博客,链接在上边。

采用半边(half-edge)作为mesh的存储数据结构。mathNet作为c#的数学库,用于计算矩阵的转置和逆。

本质是求解方程

                                       

然后,以静态demo为例,m为锚点的数目(固定锚点76+移动锚点1 = 77),n为mesh网格顶点的数目(20x20=400),

               

L是一个400x400的矩阵,为了计算方便,采用其对称形式Ls参与计算,即在方程组里,L=Ls,解不变,下为Ls矩阵的具体value

w是锚点的权,全部初始化为1. 是一个mxn的类单位矩阵,m为锚点的数目,n为网格顶点的数目,I的每一行只有一个非零元素,表示锚点在网格中的索引,矩阵value类似于下面这样

          0 0 0 0 0 0 0 1 0 0 0  .... 0 0 0 0

          0 0 0 0 0 0 0 0 1 0 0  .... 0 0 0 0


然后解释方程组的右边项,

δ(x)是一个400x3矩阵,存除这个网格变形前的所有vertex的拉普拉斯坐标,坐标公式计算如下

w是相同的锚点的权,C1:m 为 77x3的矩阵,存每个锚点变化后的坐标值,比如固定锚点的坐标不变,还是变形前的值,移动锚点的坐标改为加上偏移量(0,1, 0)变化后的坐标值。b矩阵示意值如下


至此,所有的矩阵填充完毕,求解变化后的坐标矩阵x(一个400x3矩阵,存变形后的mesh网格顶点的坐标值),

最后一步更新mesh顶点的坐标,注意锚点的更新坐标为c1:m的坐标,而不用计算出来的坐标,因为有些许误差。

额外补充:

  VR代码,用的是LeapMotion与HTC VIVE Pro套件,基本算法都一样,在这里,也是paper中强调了三次的一个技巧。

 决定了变形区域,在抓着某些点进行拖拽时,红色方框中的矩阵其实是不再改变的,所以只用计算一次就好,

拖拽过程中,不断地修改矩阵b,计算新的vertex位置并更新到mesh。

只有当松手并重新抓点拖拽时,才重新计算一次方框中的矩阵,因为移动锚点可能更新了。

猜你喜欢

转载自blog.csdn.net/z136411501/article/details/107623248