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. python基础知识七

    我们会使用raw_input和print语句来完成这些功能. 对于输出,也可以使用多种多样的str(字符串)类. 例如使用rjust方法来得到一个按一定宽度右对齐的字符串. 可以通过创建一个file类 ...

  2. 对于百川SDK签名验证的问题

    SDK是要在wantu.taobao.com生成的.而生成这个SDK其实是要上传一个apk,而这个上传其实就是取他的签名而已.验证就是那张yw222那张图片.重点是你上传的apk的签名是不是跟你的生成 ...

  3. ASCII 码表对照 2

    http://www.asciima.com/ ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的 ...

  4. 枚举N行N列的自然数列

    数据库环境:SQL SERVER 2005 现有一个需求,要枚举1-50个自然数,分10行5列展示.如图,

  5. SSH整合笔记

    SSH:spring+struts+hibernate. 一:所需jar: 需要注意的是: hibernate+spring需要Spring-orm-xxx.jar struts+spring需要st ...

  6. cocos2dx arpg单机手游

    这只是一个DEMO. ARPG 单机手游, 个人DEMO. 支持剧情编辑, 支持气泡对话, 支持人物图像对话, 支持随时角色切换, 支持NPC跟随, 共同作战, 支持LUA扩展, 支持BUFF技能, ...

  7. 谷歌的C++智能指针实现

    //智能指针基类所有智能指针对象都继承该类class RefCountedBase { public: ; ; protected: virtual ~RefCountedBase(){} }; 智能 ...

  8. 24种设计模式--桥梁模式【Bridge Pattern】

    今天我要说说我自己,梦想中的我自己,我身价过亿,有两个大公司,一个是房地产公司,一个是服装制造业,这两个公司都很赚钱,天天帮我在累加财富,其实是什么公司我倒是不关心,我关心的是是不是在赚钱,赚了多少, ...

  9. [转]Python核心模块——urllib模块

    现在Python基本入门了,现在开始要进军如何写爬虫了! 先把最基本的urllib模块弄懂吧. urllib模块中的方法 1.urllib.urlopen(url[,data[,proxies]]) ...

  10. JavaScript 高阶函数 + generator生成器

    map/reduce map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果: function pow(x ...