using UnityEngine;
using System.Collections;

public class SlerpImp
{
static float Dot(Quaternion a, Quaternion b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}

static Quaternion Lerp(Quaternion a, Quaternion b, float t)
{
return new Quaternion(a.x * (1 -t) + b.x * t,
a.y * (1 -t) + b.y * t,
a.z * (1 -t) + b.z * t,
a.w * (1 -t) + b.w * t);
}

static Quaternion Inverse(Quaternion a)
{
a.x = -a.x;
a.y = -a.y;
a.z = -a.z;

return a;
}

public static Quaternion Slerp1(Quaternion a, Quaternion b, float t)
{
t = Mathf.Clamp01 (t);

float similar = Dot(a,b);
float sign = 1.0f;
if(similar >= 1f - Mathf.Epsilon)
return a == Quaternion.identity ? Quaternion.identity : Lerp(a,b,t);
else if (similar < 0f)
{
a.x = -a.x;
a.y = -a.y;
a.z = -a.z;
a.w = -a.w;
sign = -1f;
}

Quaternion result = Quaternion.identity;

// 0-pi, otherwise, inverse the xyz axis space
float aw = Mathf.Acos(a.w);
float bw = Mathf.Acos(b.w);

float saw = new Vector3(a.x, a.y, a.z).magnitude;
float sbw = new Vector3(b.x, b.y, b.z).magnitude;

aw = saw != 0.0f ? aw * (1 - t) / saw : 0.0f;
bw = sbw != 0.0f ? bw * t / sbw : 0.0f;
result.x = a.x * aw + b.x * bw;
result.y = a.y * aw + b.y * bw;
result.z = a.z * aw + b.z * bw;

Vector3 v = new Vector3(result.x, result.y, result.z);
float theta = v.magnitude;
if (theta == 0f)
return Quaternion.identity;

float sintheta = sign * Mathf.Sin(theta) / theta;
result.x *= sintheta;
result.y *= sintheta;
result.z *= sintheta;
result.w = sign * Mathf.Cos(theta);

return result;
}

public static Quaternion Slerp2(Quaternion a, Quaternion b, float t)
{
t = Mathf.Clamp01 (t);

float sign = 1.0f;
float similar = Dot(a,b);
if(similar >= 1f - Mathf.Epsilon)
return a == Quaternion.identity ? Quaternion.identity : Lerp(a,b,t);
else if (similar < 0f)
{
a.x = -a.x;
a.y = -a.y;
a.z = -a.z;
a.w = -a.w;
sign = -1.0f;
}

Quaternion result = Inverse(a);
result *= b;
Vector3 v = new Vector3(result.x, result.y, result.z);
float sintheta = v.magnitude;
// 0-pi, otherwise, inverse the xyz axis space
float theta = Mathf.Acos(result.w);
theta *= t;
sintheta = sign * Mathf.Sin(theta) / sintheta;
result.x *= sintheta;
result.y *= sintheta;
result.z *= sintheta;
result.w = sign * Mathf.Cos(theta);
return a * result;
}

}

[ExecuteInEditMode]
public class SlerpTest : MonoBehaviour {

public int callTimes = 1000000;
[Range(0,1)]
public float t = 0.3f;
// Use this for initialization
void Start ()
{

int callCount = callTimes;
float time = Time.realtimeSinceStartup;
while(callCount-- > 0)
{
SlerpImp.Slerp1(this.transform.rotation, Camera.main.transform.rotation, t);
}
Debug.LogWarning("Slerp1 "+ callTimes + " calls took: " + (Time.realtimeSinceStartup - time));

callCount = callTimes;
time = Time.realtimeSinceStartup;
while(callCount-- > 0)
{
SlerpImp.Slerp2(this.transform.rotation, Camera.main.transform.rotation, t);
}
Debug.LogWarning("Slerp2 "+ callTimes + " calls took: " + (Time.realtimeSinceStartup - time));

callCount = callTimes;
time = Time.realtimeSinceStartup;
while(callCount-- > 0)
{
Quaternion.Slerp(this.transform.rotation, Camera.main.transform.rotation, t);
}
Debug.LogWarning("UnityS "+ callTimes + " calls took: " + (Time.realtimeSinceStartup - time));
}

void Update()
{
Debug.LogWarning("------------------");
Debug.LogWarning("Slerp1: " + SlerpImp.Slerp1(this.transform.rotation, Camera.main.transform.rotation, t).eulerAngles);
Debug.LogWarning("Slerp2: " + SlerpImp.Slerp2(this.transform.rotation, Camera.main.transform.rotation, t).eulerAngles);
Debug.LogWarning("UnitySLerp: " + Quaternion.Slerp(this.transform.rotation, Camera.main.transform.rotation, t).eulerAngles);
}
}

Two kinds of Quaternion SlerpImp (Unity)的更多相关文章

  1. C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型

    遇到一个想做的功能,但是实现不了,核心原因是因为对U3D的3D数学概念没有灵活吃透.故再次系统学习之—第三次学习3D数学. 本次,希望实现的功能很简单: 如在小地图中,希望可以动态画出Player当前 ...

  2. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  3. [Unity Quaternion]四元数Quaternion的计算方式

    什么是Quaternion四元数 1843年,William Rowan Hamilton发明了四元数,但直到1985年才有一个叫Ken Shoemake的人将四元数引入计算机图形学处理领域.四元数在 ...

  4. 【Unity技巧】四元数(Quaternion)和旋转

    四元数介绍 旋转,应该是三种坐标变换--缩放.旋转和平移,中最复杂的一种了.大家应该都听过,有一种旋转的表示方法叫四元数.按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法--矩阵旋转和欧拉旋转. ...

  5. 【Unity】6.8 Quaternion类(四元数)

    分类:Unity.C#.VS2015 创建日期:2016-04-20 一.四元数的概念 四元数包含一个标量分量和-个三维向量分量,四元数Q可以记作: Q=[w,(x,y,z)] 在3D数学中使用单位四 ...

  6. 【Unity编程】四元数(Quaternion)与欧拉角

    版权声明:本文为博主原创文章,欢迎转载.请保留博主链接:http://blog.csdn.net/andrewfan 欧拉旋转.四元数.矩阵旋转之间的差异 除了欧拉旋转以外,还有两种表示旋转的方式:矩 ...

  7. unity, 由Matrix4x4提取Quaternion和Vector3 及 由Quaternion,Vector3构造Matrix4x4

    一,由Matrix4x4提取Quaternion和Vector3 Quaternion getRotationFromMatrix(Matrix4x4 m) {         return Quat ...

  8. unity quaternion vector

    做脚印呢 做了曲面细分和decal两种 先用正交camera生成 高度图 采样uv由pos 从world到camera space生成 unity对tessellation的支持限制还是比较大的 只能 ...

  9. Unity string 转换为 Quaternion

    public Quaternion QuaternionParse(string name) { name = name.Replace("(", "").Re ...

随机推荐

  1. Delphi 类方法和普通方法的区别 .

    //类声明  TMyClass = class  public    class procedure MyProc;  //类方式    constructor Create;      //Crea ...

  2. 使用for循环嵌套实现乘法口诀表

    九九乘法表的实现: package com.liaojianya.chapter1; /** * This program demonstrates the way of using * for-lo ...

  3. PC110304/UVA850

    这题目WA了好几次,主要是我没有理解清楚No solution.这个情况. 如果在match原文做好了,基本map一下就能过了. 与原句match的条件就是: 1.出现了26个字母 2.该空格的地方要 ...

  4. php递归数组中的应用

    <?php $arr = array(array(1,2), array(3, 4), array(array(5, 6), array(7, 8)));function t($a){    i ...

  5. 开发语言大PK:php和Java哪个更好?

    Java通过jdbc来访问数据库,通过不同的数据库厂商提供的数据库驱动方便地访问数据库.访问数据库的接口比较统一. PHP对于不同的数据库采用不同的数据库访问接口,所以数据库访问代码的通用性不强.例如 ...

  6. IS脚本学习

    OnFirstUIBefore:函数块用于第一安装应用时安装部件前所要完成的任务.一般在这里进行下列设: 1. 设置屏蔽 2. 显示欢迎信息,软件协议书或关于软件安装的其他说明信息 3. 从用户处获取 ...

  7. js 删除数组方法

    今天遇到一个比较脑残的问题 ,在在用js删除数组的时候 delete 数组[下标]的方法删除数组时,该数组的下标变为null,但是数组的长度并没有发生相应的变化 转而使用splice(小标,第N个)删 ...

  8. git推送失败的问题

    git报错如下: fatal: 'origen' does not appear to be a git repositoryfatal: The remote end hung up unexpec ...

  9. linux系统下,递归删除.svn文件

    linux系统下,递归删除.svn文件 SVNLinux 进入要删除的目录,执行下面的命令就可以啦. find . -name "*.svn"  | xargs rm -rf

  10. EF自动生成的(T4模板) 关联属性元数据修改

    为了实现 T4模板关联属性 不要序列化的问题 就是要在具体的 关联属性上面添加一个元数据 这里利用以前的 Newtonsoft.Json 这个框架为例 效果应该为 就是要在关联属性上面添加元数据  [ ...