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. 模版引擎(NVelocity)开发

    在net中用模版开发,在handler中用到了大量的html代码.为解决这个问题,我可以采用模版引擎(NVelocity)进行开发.1.首先需要将NVelocity.dll文件放入项目,其次引用.2. ...

  2. [XML] Resource帮助类

    点击下载 Resources.rar /// <summary> /// 类说明:Resources /// 编 码 人:苏飞 /// 联系方式:361983679 /// 更新网站:[u ...

  3. Fragment的生命周期和Activity之间的通信以及使用

    Fragment通俗来讲就是碎片,不能单独存在,意思就是说必须依附于Activity,一般来说有两种方式把Fragment加到Activity,分为静态,动态. 静态即为右键单击,建立一个Fragme ...

  4. 使用DataList 分页方法

    什么是DataList我想应该不需要解释了,接下来分享本人在项目里使用到的通过DataList进行分页展示方法. 首先在ASPX页面添加一个DataList(后面都简称DL)控件,示例代码如下: &l ...

  5. Script: Who’s using a database link?(找出谁在使用dblink)

    Every once in awhile it is useful to find out which sessions are using a database link in an Oracle ...

  6. iOS,长按图片保存实现方法,轻松搞定!

    1.添加手势识别: UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@s ...

  7. localStorage.ie6.js

    !window.localStorage && function() { window.localStorage = {}; var prefix = 'data-userdata' ...

  8. java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解(勿删)

    head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数.该怎么理解呢? 看例子: public class Test1 { pu ...

  9. 下载安装sublime text3,打包sublime text3便携版,激活sublime text3,配置sublime text3的php环境

      下载安装sublime text3: http://www.sublimetext.com/3 安装就一直下一步   打包sublime text3便携版 : 参考http://segmentfa ...

  10. php生成二维码

    <?php $urlToEncode="163.com";   generateQRfromGoogle($urlToEncode);   function generate ...