Games 103 作业三

Games 103 作业三

作业三的内容主要就是实现一下FVM。我们按照文档中的步骤,第一步就是去独立地更新mesh的速度和位置,在初始化每个顶点的受力时,需要考虑到重力的影响。

for(int i=0 ;i<number; i++)
{//TODO: Add gravity to Force.Force[i] = new Vector3(0, -9.8f * mass, 0);
}for(int i=0; i<number; i++)
{//TODO: Update X and V here.V[i] += Force[i] * dt / mass;V[i] *= damp;X[i] += V[i]*dt;
}

接下来要考虑mesh的碰撞处理。在作业给的场景中,就只有一个简单的floor。

Games 103 作业三1

floor的世界坐标是(0, -3, 0),那么这里就直接简化碰撞处理了:

//TODO: (Particle) collision with floor.
if (X[i].y < -3f)
{V[i].y += (-3f - X[i].y) / dt;X[i].y = -3f;
}

下一步,我们要在Start方法中预先计算好常量矩阵 D m \textbf{D}_m Dm以及它的逆。根据PPT的第25页,有
D m = [ X 10 X 20 X 30 ] \textbf{D}_m = [\textbf{X}_{10} \textbf{X}_{20} \textbf{X}_{30}] Dm=[X10X20X30]
每个四面体都有这样的一个矩阵:

//TODO: Need to allocate and assign inv_Dm
inv_Dm = new Matrix4x4[tet_number];
for(int i = 0; i < tet_number; i++)
{Matrix4x4 Dm = Build_Edge_Matrix(i);inv_Dm[i] = Dm.inverse;
}Matrix4x4 Build_Edge_Matrix(int tet)
{Matrix4x4 ret=Matrix4x4.zero;//TODO: Need to build edge matrix here.Vector4 e1 = X[Tet[tet * 4 + 1]] - X[Tet[tet * 4 + 0]];Vector4 e2 = X[Tet[tet * 4 + 2]] - X[Tet[tet * 4 + 0]];Vector4 e3 = X[Tet[tet * 4 + 3]] - X[Tet[tet * 4 + 0]];ret.SetColumn(0, e1);ret.SetColumn(1, e2);ret.SetColumn(2, e3);ret.SetColumn(3, new Vector4(0, 0, 0, 1));return ret;
}

接下来,计算Deformation gradient F和Green strain G,计算的方法也在PPT第25页:
F = [ x 10 x 20 x 30 ] D m − 1 \textbf{F} = [\textbf{x}_{10} \textbf{x}_{20} \textbf{x}_{30}] \textbf{D}_m^{-1} F=[x10x20x30]Dm1

G = 1 2 ( F T F − I ) \textbf{G} = \dfrac{1}{2}(\textbf{F}^T\textbf{F} - \textbf{I}) G=21(FTFI)

//TODO: Deformation Gradient
Matrix4x4 m = Build_Edge_Matrix(tet);
Matrix4x4 F = m * inv_Dm[tet];
//TODO: Green Strain
Matrix4x4 G = Matrix_Mul(0.5f, Matrix_Sub(F.transpose * F, Matrix4x4.identity));

作业里使用的是the second Piola-Kirchho stress,也给出了相应的公式:
S = 2 s 1 G + s 0 t r ( G ) I \textbf{S} = 2s_1\textbf{G} + s_0tr(\textbf{G})\textbf{I} S=2s1G+s0tr(G)I

//TODO: Second PK Stress
Matrix4x4 S = Matrix_Add(Matrix_Mul(2.0f * stiffness_1, G),Matrix_Mul(stiffness_0 * Matrix_Trace(G), Matrix4x4.identity));

那么根据ppt,就可以计算出四面体上每个顶点的力了:
P = FS \textbf{P} = \textbf{F}\textbf{S} P=FS

[ f 1 f 2 f 3 ] = − 1 6 d e t ( D m − 1 ) P D m − T [\textbf{f}_1 \textbf{f}_2 \textbf{f}_3] = - \dfrac{1}{6det(\textbf{D}_m^{-1})}\textbf{P}\textbf{D}_m^{-\textbf{T}} [f1f2f3]=6det(Dm1)1PDmT

f 0 = − f 1 − f 2 − f 3 \textbf{f}_0 = -\textbf{f}_1 - \textbf{f}_2 - \textbf{f}_3 f0=f1f2f3

//TODO: Elastic Force
Matrix4x4 fm = Matrix_Mul(-1.0f / (6.0f * inv_Dm[tet].determinant),F * S * inv_Dm[tet].transpose);
f1 = fm.GetColumn(0);
f2 = fm.GetColumn(1);
f3 = fm.GetColumn(2);Force[Tet[tet * 4 + 0]] -= f1 + f2 + f3;
Force[Tet[tet * 4 + 1]] += f1;
Force[Tet[tet * 4 + 2]] += f2;
Force[Tet[tet * 4 + 3]] += f3;

其实这个时候房子已经可以跳动起来了,只是。。。

Games 103 作业三2

模拟很不稳定,房子直接飞了。作业中为了避免这一情况,使用了拉普拉斯平滑。我们需要统计每个顶点所邻接的所有其他顶点,计算出一个邻接的平均速度,然后进行加权:

void Laplacian_Smoothing(float blend)
{for (int i = 0; i < number; i++){V_sum[i] = Vector3.zero;V_num[i] = 0;}for(int tet=0; tet<tet_number; tet++){Vector3 sum = V[Tet[tet * 4 + 0]] + V[Tet[tet * 4 + 1]] + V[Tet[tet * 4 + 2]] + V[Tet[tet * 4 + 3]];V_sum[Tet[tet * 4 + 0]] += sum;V_sum[Tet[tet * 4 + 1]] += sum;V_sum[Tet[tet * 4 + 2]] += sum;V_sum[Tet[tet * 4 + 3]] += sum;V_num[Tet[tet * 4 + 0]] += 4;V_num[Tet[tet * 4 + 1]] += 4;V_num[Tet[tet * 4 + 2]] += 4;V_num[Tet[tet * 4 + 3]] += 4;}for(int i = 0; i < number; i++){V[i] = (V[i] + blend * V_sum[i] / V_num[i]) / (1 + blend);}
}

我们取blend为0.1,再看看现在的效果:

Games 103 作业三3

基础部分就完成了。下面再看一下附加题部分,其实就是根据PPT的第35页,换一种方法计算P。

Games 103 作业三4

首先是利用SVD得到三个矩阵:

Matrix4x4 U = Matrix4x4.zero;
Matrix4x4 S = Matrix4x4.zero;
Matrix4x4 V = Matrix4x4.zero;svd.svd(F, ref U, ref S, ref V);

根据公式:
P = U d i a g ( ∂ W ∂ λ 0 , ∂ W ∂ λ 1 , ∂ W ∂ λ 2 ) V T P = \textbf{U} diag(\dfrac{\partial W}{\partial \lambda_0}, \dfrac{\partial W}{\partial \lambda_1}, \dfrac{\partial W}{\partial \lambda_2}) \textbf{V}^\textbf{T} P=Udiag(λ0W,λ1W,λ2W)VT
那么问题就只剩计算这三个偏导数。而W是关于 I C I_C IC I I C II_C IIC的函数(注意,这里PPT给的公式有误)
W = s 0 8 ( I C − 3 ) 2 + s 1 4 ( I I C − 2 I C + 3 ) W = \dfrac{s_0}{8}(I_C - 3)^2 + \dfrac{s_1}{4}(II_C - 2I_C + 3) W=8s0(IC3)2+4s1(IIC2IC+3)

I C = λ 0 2 + λ 1 2 + λ 2 2 I_C = \lambda_0^2 + \lambda_1^2 + \lambda_2^2 IC=λ02+λ12+λ22

I I C = λ 0 4 + λ 1 4 + λ 2 4 II_C = \lambda_0^4 + \lambda_1^4 + \lambda_2^4 IIC=λ04+λ14+λ24

又有
∂ W ∂ λ = ∂ W ∂ I C ∂ I C ∂ λ + ∂ W ∂ I I C ∂ I I C ∂ λ \dfrac{\partial W}{\partial \lambda} = \dfrac{\partial W}{\partial I_C} \dfrac{\partial I_C}{\partial \lambda} + \dfrac{\partial W}{\partial II_C} \dfrac{\partial II_C}{\partial \lambda} λW=ICWλIC+IICWλIIC
所以只要分别计算上述式子中右侧的偏导数,就能得到最终的P了:

float lambda0 = S[0, 0];
float lambda1 = S[1, 1];
float lambda2 = S[2, 2];float Ic = lambda0 * lambda0 + lambda1 * lambda1 + lambda2 * lambda2;float dWdIc = 0.25f * stiffness_0 * (Ic - 3f) - 0.5f * stiffness_1;
float dWdIIc = 0.25f * stiffness_1;
float dIcdlambda0 = 2f * lambda0;
float dIcdlambda1 = 2f * lambda1;
float dIcdlambda2 = 2f * lambda2;
float dIIcdlambda0 = 4f * lambda0 * lambda0 * lambda0;
float dIIcdlambda1 = 4f * lambda1 * lambda1 * lambda1;
float dIIcdlambda2 = 4f * lambda2 * lambda2 * lambda2;
float dWd0 = dWdIc * dIcdlambda0 + dWdIIc * dIIcdlambda0;
float dWd1 = dWdIc * dIcdlambda1 + dWdIIc * dIIcdlambda1;
float dWd2 = dWdIc * dIcdlambda2 + dWdIIc * dIIcdlambda2;Matrix4x4 diag = Matrix4x4.zero;
diag[0, 0] = dWd0;
diag[1, 1] = dWd1;
diag[2, 2] = dWd2;
diag[3, 3] = 1;
Matrix4x4 P = U * diag * V.transpose;

最终效果如下,感觉两种计算方式的效果差不多:

Games 103 作业三5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/202998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wsl安装虚拟机平台报错“无法解析服务器的名称或地址

wsl安装虚拟机平台报错“无法解析服务器的名称或地址” 1.问题 利用wsl安装拟机平台报错“无法解析服务器的名称或地址” 2.解决方案 修改DNS即可 控制面板->网络和Internet&#xff0c;选择查看网络状态和任务 选择更改适配器设置 选择所连接的网络&#xff0c;选择属性…

Java研学-Lambda表达式

一 Lambda表达式 – 箭头函数 1 含义 JDK8首次将函数式编程引入到Java代码中;这是一种新型的方法参数传递的方式;直接将获取参数的步骤传递给需要该参数的方法中–Lambda表达式 2 特点 1 简化代码 2 多核友好 3 面向对象思想不足 public class Play {public static void mai…

我不是DBA之慢SQL诊断方式

最近经常遇到技术开发跑来问我慢SQL优化相关工作&#xff0c;所以干脆出几篇SQL相关优化技术月报&#xff0c;我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到&#xff0c;尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…

C++ Core Guidelines解析 ( 好书推荐 )

C Core Guidelines是Bjarne和 Herb Sutter发起编写的一个开源项目&#xff0c;汇聚了 C社区多年来积累的宝贵经验&#xff0c;是非常全面的编程最佳实践指导&#xff0c;包括代码风格、函数、类、错误处理、性能优化等&#xff0c;可以说是C社区的集大成者。用Effective Modern…

网络安全缓冲区溢出实验

实验要求实验步骤函数 f00()函数 f01()函数 f02() 实验要求 C 程序 homework08.c 的主函数如下&#xff1a; int main(int argc, char * argv[]) { init_buf(Lbuffer, LEN);switch(argc) {case 1: f00(); break;case 2: f01(); break;case 3: f02(); break; default: f00(); …

JIT/Just-In-Time Compilation

即时编译&#xff08;Just-In-Time Compilation&#xff0c;JIT&#xff09;是一种将程序在运行时动态地编译成机器代码的编译技术。相对于传统的静态编译&#xff0c;即时编译将编译过程延迟到程序执行的时候进行&#xff0c;而不是在程序执行之前。这种方法允许编译器根据程序…

国内AI大模型已近80个,哪个最有前途?

目前&#xff0c;国内已经推出了近80个人工智能大模型&#xff0c;这些大模型各有优势&#xff0c;难以直接判断哪个最有前途。然而&#xff0c;以下几个大模型值得关注&#xff1a; 1、华为云盘古大模型&#xff1a;盘古大模型聚焦于为行业服务&#xff0c;包括自然语言、视觉…

【Markdown】Markdown 公式书写

Markdown 公式书写 文章目录 Markdown 公式书写公式风格上下标以及希腊字母分式根式等结构函数名运算符矩阵写法行列式写法多行公式数学字母样式 公式风格 Markdown公式方面主要是用的Latex数学公式的写法&#xff08;也是不完全相同&#xff0c;比Latax少了一些内容&#xff…

出错:I/O文件读取JAVA

I/O文件读取 /** author:xiaowang* date:2023/12/6* demand:读取java1班的数据* * */ package homework;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException;public class FileReadTest {public static void main(String[] args) …

月入9K, 95后夫妻转行网优:人生路远,我们只愿携手前行!

用心专注一门课&#xff0c;让教育改变更多人是优橙教育成立的初心与使命。 在优小橙的教育生涯里&#xff0c;见过许多学生&#xff0c;他们或是因为追求一份美好的前程来优橙&#xff1b;或是想要改变泥泞的现状来优橙&#xff1b;或是因为想要深耕通信行业来优橙……理由很多…

【头歌系统Python实验】字符串处理

目录 第1关&#xff1a;字符串的拼接&#xff1a;名字的组成 第2关&#xff1a;字符转换 第3关&#xff1a;字符串查找与替换 如果对你有帮助的话&#xff0c;不妨点赞收藏评论一下吧&#xff0c;爱你么么哒&#x1f618;❤️❤️❤️ 第1关&#xff1a;字符串的拼接&#x…

Linux--程序地址空间

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 [TOC](文章目录) 一、程序地址空间回顾 我们在讲C语言的时候&#xff0c;老师给大家画过这样的空间布局…

Qt-Q_OBJECT宏使用与“无法解析的外部符号qt_metacall/metaObject/qt_metacast“

有时候我们编写Qt类的时候&#xff0c;修改代码时直接加上Q_OBJECT宏&#xff0c;然后直接构建&#xff0c;会报如下错误&#xff1a; 这里的几个函数的声明是由Q_OBJECT宏引入的&#xff0c;而其对应的实现是由moc实现的&#xff0c;如果我们更新了代码但是没有执行qmake&…

基于Java学生宿舍管理系统

基于Java学生宿舍管理系统 功能介绍&#xff1a; 1、用户管理&#xff1a;系统需要提供用户注册、登录和权限管理功能。管理员可以创建和管理学生、宿舍员工等用户账号&#xff0c;并设置不同的权限级别。 2、宿舍管理&#xff1a;系统需要能够管理宿舍的基本信息&#xff0…

SQL小技巧:where条件后为什么要写1=1?

【微信公众号&#xff1a;跟强哥学SQL】 相信第一次看到下面这个SQL的同学心里都不免会产生疑问。 SELECT * FROM employeesWHERE 11 为什么要在where条件中使用11这样的写法&#xff1f;这不是废话吗&#xff1f; 其实还真不是。 为什么使用11这样的条件&#xff1f; 在…

Linux网卡命名规则

Linux网卡命名规则 网卡命名 一、为什么需要这个 服务器通常有多块网卡&#xff0c;有板载集成的&#xff0c;同时也有插在PCIe插槽的。Linux系统的命名原来是eth0,eth1这样的形式&#xff0c;但是这个编号往往不一定准确对应网卡接口的物理顺序。 为解决这类问题&…

基于FPGA的图像RGB转CIE-Lab实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1RGB颜色空间 4.2CIE-Lab颜色空间 4.3RGB转CIE-Lab算法原理 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的结果导入到matlab&#xff0c;并和matlab的仿真结果进行对比&#xff1a…

使用TouchSocket适配一个c++的自定义协议

这里写目录标题 说明一、新建项目二、创建适配器三、创建服务器和客户端3.1 服务器3.2 客户端3.3 客户端发送3.4 客户端接收3.5 服务器接收与发送 四、关于同步Send 说明 今天有小伙伴咨询我&#xff0c;他和同事&#xff08;c端&#xff09;协商了一个协议&#xff0c;如果使…

【Hadoop_01】Hadoop介绍与安装

1、Hadoop、HDFS、YARN介绍&#xff08;1&#xff09;Hadoop简介与优势&#xff08;2&#xff09;Hadoop组成&#xff08;3&#xff09;HDFS概述&#xff08;4&#xff09;YARN概述&#xff08;5&#xff09;MapReduce概述 2、安装&#xff08;1&#xff09;Centos7.5软硬件安装…

基于jsp+servlet+mybatis的简易在线选课系统

目录 一.数据库 1.数据库和表的创建 2.数据插入 二.代码实现 1.pojo类 &#xff08;1&#xff09;Course &#xff08;2&#xff09;User &#xff08;3&#xff09;Elective 2.mapper接口 &#xff08;1&#xff09;UserMapper &#xff08;2&#xff09;ElectiveMap…