简介

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. MCP应用docker部署,docker-compose部署

    一.概述 前面几篇文章,MCP应用直接用的python3 server.py运行的,如果服务器重启,进程就会关掉,很不方便. 所以需要使用docker部署,实现开机自启动. 二.docker部署 my ...

  2. QUBO建模

    技术背景 QUBO(Quadratic Unconstrained Binary Optimization)模型是一种常用于求解组合优化问题的一种技术,它所能够求解的问题是这样定义的:给定一个布尔类型 ...

  3. 开源项目YtyMark文本编辑器--UI界面相关功能(关于设计模式的实战运用)

    开源项目地址 GitHub 开源地址(YtyMark-java) 欢迎提交 PR.Issue.Star ️! 1. 简述 YtyMark-java项目分为两大模块: UI界面(ytyedit-mark ...

  4. STM32操作GPIO外设(点亮LED灯)的两种方式——使用官方库函数或直接操作寄存器

    STM32操作外设(点亮LED灯)的两种方式 准备工作: 硬件gec6818开发板.搭载stm32f407zet6芯片 keil项目模板,准备好官方库函数 官方提供的<STM32f407数据手册 ...

  5. CentOS 7怎么开放端口

    转自:https://www.jb51.net/os/Ubuntu/617627.html 以开放8080端口为例,其他类似 centos7已经开始使用firewall作为防火墙,而不是iptable ...

  6. openstack-Train部署文档

    部署参考资料:1,环境准备https://blog.csdn.net/m0_61777116/article/details/123702147阿里yum源https://blog.csdn.net/ ...

  7. codeup之Day of Week(给定日期判断周几

    题目描述 We now use the Gregorian style of dating in Russia. The leap years are years with number divisi ...

  8. WPF应用启动时,检测触摸失效的几种方式

    在开发OPS项目,发现插拔式的OPS在切换系统.开关机.重启,会时不时出现部分WPF开机自启的 应用触摸失效的问题.而且出现问题的应用都是全屏窗口应用.用snoop 附加上去,没有Touch 和Sty ...

  9. JS+CSS多行文本显示“更多”

    本代码展示最多显示3行,每行行高16px,3行总高48px,4行总高64px 当文本行数1-3行,正常显示:当文本行数大于3行,显示"更多". CSS: #CourseDesc { ...

  10. Hyperledger Fabric出块配置详解

    Hyperledger Fabric的出块主要是Orderer节点负责,出块配置位于创世区块中,支持定时出块.达到一定交易数出块两种条件.出块配置位于configtx.yaml中,修改出块配置后需要重 ...