简介

impulse 简单而言就是脉冲. 脉冲就是, 在碰撞的时候给一个脉冲. 导致其速度和角速度改变.

pipeline

Q&A

简述Vi 和 ViNew

Vi 就是碰撞点速度的均值

ViNew 就是碰撞点速度的改变.

J 有什么用

通过 ViNew 和 Vi 计算除了 J. 然后通过J 计算出整个模型的速度v和角速度w.

TIPS

通过角速度的更新来更新, 物体的四元数

code

using UnityEngine;
using System.Collections; public class Rigid_Bunny : MonoBehaviour
{
bool launched = false;
float dt = 0.015f;
Vector3 v = new Vector3(0, 0, 0); // velocity
Vector3 w = new Vector3(0, 0, 0); // angular velocity float mass; // mass
Matrix4x4 I_ref; // reference inertia float linear_decay = 0.999f; // for velocity decay
float angular_decay = 0.98f;
float restitution = 0.5f; // for collision
float mu_T = 0.5f;// may be coefficient of air resistance
Vector3 G = new Vector3(0.0f, -9.8f, 0.0f); // Use this for initialization
void Start ()
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices; float m=1;
mass=0;
for (int i=0; i<vertices.Length; i++)
{
mass += m;
float diag=m*vertices[i].sqrMagnitude;
I_ref[0, 0]+=diag;
I_ref[1, 1]+=diag;
I_ref[2, 2]+=diag;
I_ref[0, 0]-=m*vertices[i][0]*vertices[i][0];
I_ref[0, 1]-=m*vertices[i][0]*vertices[i][1];
I_ref[0, 2]-=m*vertices[i][0]*vertices[i][2];
I_ref[1, 0]-=m*vertices[i][1]*vertices[i][0];
I_ref[1, 1]-=m*vertices[i][1]*vertices[i][1];
I_ref[1, 2]-=m*vertices[i][1]*vertices[i][2];
I_ref[2, 0]-=m*vertices[i][2]*vertices[i][0];
I_ref[2, 1]-=m*vertices[i][2]*vertices[i][1];
I_ref[2, 2]-=m*vertices[i][2]*vertices[i][2];
}
I_ref [3, 3] = 1;
} Quaternion addTwoQuaternion(Quaternion q0, Quaternion q1)
{
Quaternion result = new Quaternion(q0.x + q1.x, q0.y + q1.y,
q0.z + q1.z, q0.w + q1.w);
return result;
} Matrix4x4 Get_Cross_Matrix(Vector3 a)
{
//Get the cross product matrix of vector a
Matrix4x4 A = Matrix4x4.zero;
A [0, 0] = 0;
A [0, 1] = -a [2];
A [0, 2] = a [1];
A [1, 0] = a [2];
A [1, 1] = 0;
A [1, 2] = -a [0];
A [2, 0] = -a [1];
A [2, 1] = a [0];
A [2, 2] = 0;
A [3, 3] = 1;
return A;
}
Matrix4x4 multiplyScalar(Matrix4x4 a, float b)
{
Matrix4x4 rlt = Matrix4x4.zero;
for(int i=0; i<4; i++)
{
for(int j = 0; j<4; j++)
{
rlt[i, j] = a[i, j] * b;
}
}
return rlt;
}
Matrix4x4 addTwoMatrix(Matrix4x4 a, Matrix4x4 b)
{
Matrix4x4 rlt = Matrix4x4.zero;
for(int i=0; i<4; i++)
{
for (int j = 0; j<4; j++)
{
rlt[i, j] = a[i, j] + b[i, j];
}
}
return rlt;
}
Matrix4x4 minusTwoMatrix(Matrix4x4 a, Matrix4x4 b)
{
return addTwoMatrix(a, multiplyScalar(b, -1));
}
// In this function, update v and w by the impulse due to the collision with
//a plane <P, N>
void Collision_Impulse(Vector3 P, Vector3 N)
{
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices; // may be this is local position
int[] vid_collision = new int[vertices.Length];
int num_collision = 0; Matrix4x4 R = Matrix4x4.Rotate(transform.rotation);
for(int i=0; i<vertices.Length; i++)
{
Vector3 xi = transform.position + R.MultiplyVector(vertices[i]);
if(Vector3.Dot(xi - P, N) < 0)
{
vid_collision[num_collision] = i;
num_collision++;
}
} if(num_collision == 0)
{
return;
} Vector3 ri = new Vector3(0, 0, 0);
for(int i = 0; i<num_collision; i++)
{
ri += vertices[vid_collision[i]];
}
ri = ri / (float)(num_collision);
Vector3 Rri = R.MultiplyVector(ri);
Vector3 Vi = v + Vector3.Cross(w, Rri);
if (Vector3.Dot(Vi, N) > 0) return; // it may be in the state of Rebound ?? // calc Compute the wanted _^new
Vector3 VN = Vector3.Dot(Vi, N) * N;
Vector3 VT = Vi - VN;
restitution = Mathf.Max(restitution - 0.0005f, 0); // We can decrease the restitution _ to reduce oscillation
float a = Mathf.Max(0, 1.0f - mu_T * (1.0f + restitution)) * Vector3.Magnitude(VN) / Vector3.Magnitude(VT);
Vector3 ViNew = -1.0f * restitution * VN + a * VT;
// Compute the impulse j
Matrix4x4 I_rot = R * I_ref * Matrix4x4.Transpose(R);
Matrix4x4 I_inverse = Matrix4x4.Inverse(I_rot); Matrix4x4 Rri_star = Get_Cross_Matrix(Rri);
Matrix4x4 K = minusTwoMatrix(multiplyScalar(Matrix4x4.identity , (1.0f / mass)) ,
Rri_star * I_inverse * Rri_star);
Vector3 J = K.inverse.MultiplyVector(ViNew - Vi); // update v and w
v = v + 1 / mass * J;
w = w + I_inverse.MultiplyVector(Vector3.Cross(Rri, J));
} // Update is called once per frame
void Update ()
{
//Game Control
if(Input.GetKey("r"))
{
transform.position = new Vector3 (0, 0.6f, 0);
restitution = 0.5f;
launched=false;
}
if(Input.GetKey("l"))
{
v = new Vector3 (5, 2, 0);
launched=true;
} // Part I: Update velocities
if (launched == false) return; v = v + dt * G;
v = v * linear_decay; w *= angular_decay; // Part II: Collision Impulse
Collision_Impulse(new Vector3(0, 0.01f, 0), new Vector3(0, 1, 0));
Collision_Impulse(new Vector3(2, 0, 0), new Vector3(-1, 0, 0)); // Part III: Update position & orientation
//Update linear status
Vector3 x = transform.position;
x += dt * v;
//Update angular status
Quaternion q = transform.rotation;
Vector3 dw = 0.5f * dt * w;
Quaternion qua_rotate = new Quaternion(dw.x, dw.y, dw.z, 0.0f);
q = addTwoQuaternion(q, qua_rotate * q);
// Part IV: Assign to the object
transform.position = x;
transform.rotation = q;
}
}

Image

GAMES 103 动画基础作业1 impulse 浅浅解析的更多相关文章

  1. iOS开发UI篇—核心动画(基础动画)

    转自:http://www.cnblogs.com/wendingding/p/3801157.html 文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(基础动画) iOS ...

  2. 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业

    游戏中的动画系统作业说明文档   一.实现一个动画状态机:至少包含3组大的状态节点

  3. 《Programming WPF》翻译 第8章 1.动画基础

    原文:<Programming WPF>翻译 第8章 1.动画基础 动画包括在一段时间内改变用户界面的某些可见的特征,如它的大小.位置或颜色.你可以做到这一点,非常困难的通过创建一个tim ...

  4. 【2017-04-01】JS字符串的操作、时间日期的操作、函数、事件、动画基础

    一.字符串的操作 1.转大写: s.toLowerCase(); 2.转大写: s.toUpperCase(); 3.字符串的截取: s.substr(3,4);      -从索引3开始截取,截取4 ...

  5. 炫丽的倒计时效果Canvas绘图与动画基础

    前言 想要在自己做的网页中,加入canvas动画效果,但是发现模板各种调整不好,觉得还是要对canvas有所了解,才可以让自己的网页变得狂拽炫酷吊炸天! 一.绘制基础 1 <!DOCTYPE h ...

  6. 动画基础--基于Core Animation(3)

    参考:https://zsisme.gitbooks.io/ios-/content/ 前面的文章动画基础--基于Core Animation(1),动画基础--基于Core Animation(2) ...

  7. 动画基础--基于Core Animation(2)

    参考:https://zsisme.gitbooks.io/ios-/content/ 前面的文章动画基础--基于Core Animation(1)提到了图层的基本概念以及可动画参数几何学等知识. 本 ...

  8. iOS 动画基础总结篇

    iOS 动画基础总结篇   动画的大体分类(个人总结可能有误) 分类.png UIView 动画 属性动画 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1 ...

  9. HTML5+JavaScript动画基础 完整版 中文pdf扫描版

    <HTML5+JavaScript动画基础>包括了基础知识.基础动画.高级动画.3D动画和其他技术5大部分,分别介绍了动画的基本概念.动画的JavaScript基础.动画中的三角学.渲染技 ...

  10. Expression Blend学习动画基础

    原文:Expression Blend学习动画基础 什么是动画(Animation)? 动画就是时间+换面的组合,画面跟着时间变化.最常见的是flash的动画,还有GIF动态图片. 动画的主要元素 时 ...

随机推荐

  1. classpath类路径

    一.classpath类路径,包含java包下和resource下

  2. .net core基础(一):安装并创建第一个webapi

    一..net介绍 .net是一个开发者平台的统称,用它可以构建多种类型的应用程序. .net平台下的开发语言:C#,F#,Visual Basic .net平台标准:.NET Standard .ne ...

  3. python,去掉“xa0”和“\r\n”

    爬小说网站,输出内容有时候会出现下图字符 首先,去掉"xa0" s = 'T-shirt\xa0\xa0短袖圆领衫,体恤衫\xa0' out = "".join ...

  4. MySQL 默认的事务隔离级别是什么?为什么选择这个级别?

    MySQL 默认的事务隔离级别是什么?为什么选择这个级别? 在 MySQL 中,默认的事务隔离级别是 可重复读(Repeatable Read).这是 InnoDB 存储引擎的默认事务隔离级别. 为什 ...

  5. 通过引用实现php无限极分类

    /** * 递归加引用实现无限极分类 * @param $items * @return array */ public function getTree2($items) {   $array = ...

  6. quartz——Corn表达式

    摘录:quartz Cron表达式一分钟教程 - 简书 (jianshu.com) Quartz学习之Cron表达式详解_five-five的博客-CSDN博客_quartz cron表达式 每隔5秒 ...

  7. jetbrains这是作啥妖呢,用了好久都没有问题,现在这是咋了?

    rider今天更新了下2025.1 数据库驱动下载不来: 插件不能正常访问: 清理下用户的配置目录: %UserProfile%\AppData\Local\JetBrains %UserProfil ...

  8. 【记录】Truenas scale|Truenas 的 SSH 服务连不上 VScode,终端能连上

    一般 Truenas连不上 就只有两种情况: 第一种:用户没对应用户目录.需要去用户管理里面对每个用户设置目录. 第二种情况,服务有个选项没勾选.这时会发现能输入密码但是一点反应都没有,打开detai ...

  9. 【经验】博客|Windows下,一键安装和部署 hexo-admin 插件(Hexo 静态博客)

    1. 在博客根目录下运行下列指令 npm install --save hexo-admin -y echo "hexo clean && hexo g -d"&g ...

  10. CANopen TPDO 配置详解:对象 1800h、1A00h 与实践指南

    CANopen TPDO 配置详解:对象 1800h.1A00h 与实践指南 目录 CANopen TPDO 配置详解:对象 1800h.1A00h 与实践指南 目录 引言 TPDO 通讯参数详解 ( ...