Maya FEM节点框架完成

这几天把物理模拟框架移植到maya之中了。


maya编程有一点比较关键,就是要让自己的程序逻辑适应maya的节点求值机制。在物理模拟中,往往需要进行时间积分,对此我的解决办法是,写一个节点rigSimulator,存放模拟的状态数据(例如: 位置、速度、加速度、过去模拟的结果),再写一个mel命令rigSimulate,让指定的节点进行求值。模拟的主循环是一个mel 脚本,伪代码如下


int $t = 0;
for ($t = $begTime; $t < $begTime + $length; $t++)
{	
	// 设置当前时间
	currentTime $t;
	
	// 对指定节点执行计算,结果存在节点内部
	int $res = `rigSimulate -step -name $nodeName`;
	if($res == 0)
		break;
}

节点的属性如下:


Rigged Mesh为受到参数控制的网格

Mesh Transform为网格变换矩阵

Rig Parameter为控制网格变形的参数,是一个数组


节点的属性编辑器面板如下:

用法是先设置好物理参数,点Initialize,然后设置模拟的长度,点Simulate开始模拟,模拟过程中可以按ESC退出。

前两个参数控制四面体网格化的精细程度。

Young Modulus 为杨氏模量,与模型硬度有关。

Nu是不用轴向变形的影响程度。

Density是密度。

Step Time为每步的时间间隔,初始设置为1/24秒。


节点进行模拟时,需要获得给定参数下的网格形状。具体的做法是先设置Rig Parameter,然后读取Rigged Mesh,此时Maya便会对节点求值,返回一个被参数控制的网格。

模拟后的结果存在节点内部,一旦节点的draw函数被调用,节点会首先根据当前帧查找对应的模拟结果,再显示出来。

下图显示一个体网格化之后的圆柱体。


我给这个圆柱体加了一个平移动画,以及一个弯曲变形器。希望做出圆柱体移动的时候弯曲的效果。

节点求值网络如下:


这个是原来节点的动画


这个是模拟之后的动画。



最后说一点,就是模拟过程中按ESC退出功能的实现。这个功能虽然不是核心功能,但是却对程序调试带来方便。下面贴出代码:


global proc execSimulator(string $nodeName)
{	
	//  获取模拟长度
	int  $length = `intSliderGrp   -query -value simLengthSlider`;
	
	// 设置进度条属性, -isInterruptable 表示能用ESC终止
	global string $gMainProgressBar;	// 这个全局变量由Maya定义,表示界面左下角的进度条
    progressBar -edit
        -beginProgress
        -isInterruptable true
        -status "Simulating... "
        -maxValue $length
        $gMainProgressBar;
		
	int  $begTime = `currentTime -q`;
	int  $t;
	for ($t = $begTime; $t < $begTime + $length; $t++)
	{	
		// 若发现ESC被按下,中止模拟
        if(`progressBar -query -isCancelled $gMainProgressBar`)
            break;
        progressBar -edit -step 1 $gMainProgressBar;
			
		// 否则继续模拟
		currentTime $t;										// 移动时间滑块到下一帧
		int $res = `rigSimulate -step -name $nodeName`;		// 执行模拟命令
		if($res == 0)
			break;
	}
	
	// 模拟结束,不再显示进度条,同时鼠标指针回复正常
    progressBar -edit  -endProgress $gMainProgressBar;
}

估计有人会说“你这个只用Maya也能做到啊”,没错,而且这个插件现在还不完善。

其实,下一步还有功能要实现,例如给某些自由参数一些指导,而不是让它们完全自由。我把代码移植到maya的目的是在实现这些下一步的功能时,有个方便调试的平台(其中一个好处就是,不用自己实现maya的各种变形器)。


当前的问题,以及下一步的改进有如下几点:

1. 发现多个控制参数的时候模拟结果存在问题。不知道是不是雅可比矩阵的导数算错了的缘故。下一步需要检查。

2. 不能处理有洞的网格,估计自相交的也不行。

3. 暂时只支持corotational模型,不支持其他本构模型,例如NeoHookean。

4. 没有使用BFGS算法。

5. Rig Space Physics文中提及的硬度控制、反向运动学没有实现。

6. 把模拟出来的参数转成动画曲线,这一步估计用mel可以完成。


接下来几天可能要转向Python、Lua学习了。等这两个任务搞定了,再接着完成这些改进,到时候可以考虑尝试在maya用python编程。

原文地址:https://www.cnblogs.com/dydx/p/4222503.html