Two kinds of Quaternion SlerpImp (Unity)
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)的更多相关文章
- C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型
		遇到一个想做的功能,但是实现不了,核心原因是因为对U3D的3D数学概念没有灵活吃透.故再次系统学习之—第三次学习3D数学. 本次,希望实现的功能很简单: 如在小地图中,希望可以动态画出Player当前 ... 
- 用好lua+unity,让性能飞起来——lua与c#交互篇
		前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ... 
- [Unity Quaternion]四元数Quaternion的计算方式
		什么是Quaternion四元数 1843年,William Rowan Hamilton发明了四元数,但直到1985年才有一个叫Ken Shoemake的人将四元数引入计算机图形学处理领域.四元数在 ... 
- 【Unity技巧】四元数(Quaternion)和旋转
		四元数介绍 旋转,应该是三种坐标变换--缩放.旋转和平移,中最复杂的一种了.大家应该都听过,有一种旋转的表示方法叫四元数.按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法--矩阵旋转和欧拉旋转. ... 
- 【Unity】6.8 Quaternion类(四元数)
		分类:Unity.C#.VS2015 创建日期:2016-04-20 一.四元数的概念 四元数包含一个标量分量和-个三维向量分量,四元数Q可以记作: Q=[w,(x,y,z)] 在3D数学中使用单位四 ... 
- 【Unity编程】四元数(Quaternion)与欧拉角
		版权声明:本文为博主原创文章,欢迎转载.请保留博主链接:http://blog.csdn.net/andrewfan 欧拉旋转.四元数.矩阵旋转之间的差异 除了欧拉旋转以外,还有两种表示旋转的方式:矩 ... 
- unity, 由Matrix4x4提取Quaternion和Vector3 及 由Quaternion,Vector3构造Matrix4x4
		一,由Matrix4x4提取Quaternion和Vector3 Quaternion getRotationFromMatrix(Matrix4x4 m) { return Quat ... 
- unity quaternion vector
		做脚印呢 做了曲面细分和decal两种 先用正交camera生成 高度图 采样uv由pos 从world到camera space生成 unity对tessellation的支持限制还是比较大的 只能 ... 
- Unity string 转换为 Quaternion
		public Quaternion QuaternionParse(string name) { name = name.Replace("(", "").Re ... 
随机推荐
- Delphi 类方法和普通方法的区别 .
			//类声明 TMyClass = class public class procedure MyProc; //类方式 constructor Create; //Crea ... 
- 使用for循环嵌套实现乘法口诀表
			九九乘法表的实现: package com.liaojianya.chapter1; /** * This program demonstrates the way of using * for-lo ... 
- PC110304/UVA850
			这题目WA了好几次,主要是我没有理解清楚No solution.这个情况. 如果在match原文做好了,基本map一下就能过了. 与原句match的条件就是: 1.出现了26个字母 2.该空格的地方要 ... 
- php递归数组中的应用
			<?php $arr = array(array(1,2), array(3, 4), array(array(5, 6), array(7, 8)));function t($a){ i ... 
- 开发语言大PK:php和Java哪个更好?
			Java通过jdbc来访问数据库,通过不同的数据库厂商提供的数据库驱动方便地访问数据库.访问数据库的接口比较统一. PHP对于不同的数据库采用不同的数据库访问接口,所以数据库访问代码的通用性不强.例如 ... 
- IS脚本学习
			OnFirstUIBefore:函数块用于第一安装应用时安装部件前所要完成的任务.一般在这里进行下列设: 1. 设置屏蔽 2. 显示欢迎信息,软件协议书或关于软件安装的其他说明信息 3. 从用户处获取 ... 
- js 删除数组方法
			今天遇到一个比较脑残的问题 ,在在用js删除数组的时候 delete 数组[下标]的方法删除数组时,该数组的下标变为null,但是数组的长度并没有发生相应的变化 转而使用splice(小标,第N个)删 ... 
- git推送失败的问题
			git报错如下: fatal: 'origen' does not appear to be a git repositoryfatal: The remote end hung up unexpec ... 
- linux系统下,递归删除.svn文件
			linux系统下,递归删除.svn文件 SVNLinux 进入要删除的目录,执行下面的命令就可以啦. find . -name "*.svn" | xargs rm -rf 
- EF自动生成的(T4模板) 关联属性元数据修改
			为了实现 T4模板关联属性 不要序列化的问题 就是要在具体的 关联属性上面添加一个元数据 这里利用以前的 Newtonsoft.Json 这个框架为例 效果应该为 就是要在关联属性上面添加元数据 [ ... 
