GAMES 103 动画基础作业1 Shape Matching 浅浅解析
简介
作业1简单实现了一个以一定初始速度和角速度的模型和墙壁碰撞的效果.
总共讲解了三种算法
-
impulse (脉冲法)
-
Shape Matching(基于形状保持的算法, 不包含物理特性)
-
Penalty methods
Shape Matching 可以说是最简单的方法之一
因为完全不涉及角速度. 基础逻辑理论就是, 当模型和墙壁发生碰撞的时候.这些碰撞的粒子会产生相反的形变但是. 我们强制将其整理保持形状的一致性. 就是先形变. 再变回来.
由于形变的步骤. 是中间步骤. 不会展示出来. 所以效果还是挺好的.
Image
TIPS
code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rigid_Bunny_by_Shape_Matching : MonoBehaviour
{
public bool launched = false;
Vector3[] X; // world position
Vector3[] Y; // temp world position
Vector3[] Q; // Local coordinates
Vector3[] V; // speed
Vector3[] OldX;
Matrix4x4 QQt = Matrix4x4.zero;
Vector3 G = new Vector3(0.0f, -9.8f, 0.0f);
float linear_decay = 0.999f;
Vector3 ground = new Vector3(0, 0.01f, 0);
Vector3 groundNormal = new Vector3(0, 1, 0);
Vector3 wall = new Vector3(2.01f, 0, 0);
Vector3 wallNormal = new Vector3(-1, 0, 0);
float mu_T = 0.5f; // μ_T may be coefficient of air resistance
float mu_N = 5.0f; // μ_N may be Coefficient of Restitution
float m_timer = 0;
// Start is called before the first frame update
void Start()
{
Mesh mesh = GetComponent().mesh;
V = new Vector3[mesh.vertices.Length];
X = mesh.vertices;
Y = mesh.vertices;
OldX = mesh.vertices;
Q = mesh.vertices;
//Centerizing Q.
Vector3 c=Vector3.zero;
for(int i=0; i 1.0f) value= 1.0f;
float phi = Mathf.Acos(value);
float lambda2=(I_c+2*k_root*Mathf.Cos(phi/3))/3.0f;
float lambda=Mathf.Sqrt(lambda2);
float III_u = Mathf.Sqrt(III_c);
if(det<0) III_u=-III_u;
float I_u = lambda + Mathf.Sqrt(-lambda2 + I_c + 2*III_u/lambda);
float II_u=(I_u*I_u-I_c)*0.5f;
float inv_rate, factor;
inv_rate=1/(I_u*II_u-III_u);
factor=I_u*III_u*inv_rate;
Matrix4x4 U = Matrix4x4.zero;
U[0,0]=factor;
U[1,1]=factor;
U[2,2]=factor;
factor=(I_u*I_u-II_u)*inv_rate;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
U[i,j]+=factor*C[i,j]-inv_rate*C2[i,j];
inv_rate=1/III_u;
factor=II_u*inv_rate;
inv_U[0,0]=factor;
inv_U[1,1]=factor;
inv_U[2,2]=factor;
factor=-I_u*inv_rate;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
inv_U[i,j]+=factor*U[i,j]+inv_rate*C[i,j];
}
Matrix4x4 R=Matrix4x4.zero;
for(int ii=0; ii<3; ii++)
for(int jj=0; jj<3; jj++)
for(int kk=0; kk<3; kk++)
R[ii,jj]+=F[ii,kk]*inv_U[kk,jj];
R[3,3]=1;
return R;
}
// Update the mesh vertices according to translation c and rotation R.
// It also updates the velocity.
void Update_Mesh(Vector3 c, Matrix4x4 R, float inv_dt)
{
for(int i=0; i().mesh;
mesh.vertices=X;
}
void Collision(float inv_dt)
{
for(int i=0; i
TRICK
PIPELINE
计算 C (模型质心坐标)
计算 A (通过A计算得到R, 即 旋转矩阵) == 从A得到R. 老师已经提供了.
更新顶点坐标
Trick
在处理碰撞的函数中. 里面的参数是自己调整的参数. 比如 5.0f 逻辑上 μ_T μ_N 都应该是一个小于1的数. 但是, 测试后感觉效果不是特别好. 如果你知道为什么的话, 请留言.
请看完bilibli 4个视屏后开始自己的作业.
参考链接
配置VS 作为 Unity 的配置环境
https://blog.csdn.net/qq_34405576/article/details/105572069
源码参考师弟写出来的, 大部分是抄的嘿嘿~~ 侵权删除.