积累旋转相机

看来有三种方式来存储相机的旋转:角度,视图matrix四元数。 我使用欧拉角度,因为当我使用matrix时,它倾向于快速累积舍入误差,将所有东西都扔掉,而四元数也会有同样的问题。

我遇到的问题是如何积累旋转? 当相机旋转时,它围绕其本地XYZ轴在本地空间中旋转。 你将如何使用旋转中的给定角度围绕这些任意轴旋转? 通常这个操作是用一个matrix完成的,但是试图从中提取新的角度是没有意义的。

或者,也许我应该只是将旋转存储在matrix或四元数中? 但是,这可以做到没有错误,最终导致问题?

Solutions Collecting From Web of "积累旋转相机"

您必须维护三个本地轴中的每一个。 当你围绕一个旋转时,你必须更新另外两个。

class gameclass { Vector3 forward = Vector3.UnitZ; //persistent orientation variables Vector3 left = -1 * Vector3.UnitX; Vector3 up = Vector3.UnitY Matrix world = Matrix.Identitiy; InputClass inputclass; //something to get your input data void Update() { Vector3 pitch = inputclass.getpitch(); //vertical swipe/stick forward = Vector3.transform(forward, Matrix.CreateFromAxisAngle(left, pitch)); up = Vector3.transform(up, Matrix.CreateFromAxisAngle(left, pitch)); Vector3 yaw = inputclass.getyaw(); //horizontal swipe/stick forward = Vector3.transform(forward, Matrix.CreateFromAxisAngle(up, yaw)); left = Vector3.transform(left, Matrix.CreateFromAxisAngle(up, yaw)); forward.Normalize(); left.Normalize(); top.Normalize(); //avoid rounding errors world = Matrix.CreateWorld( postition //this isn't defined in my code forward, up); } } 

既然你必须有一个视图matrix才能发送到着色器,并且你的相机已经在它的旋转了,这是一个正交matrix,为什么不把它用作你的“存储”设备呢?

假设你正在使用的任何框架都有用于转置matrix的方法,关于任意轴的旋转,将vector乘以matrix(变换),从2个vector构建matrix。 这里有一些xna代码,但可以认为是伪代码。

 Vector3 camPosition; Vector3 camTarget = new Vector3(0, 0, -1);//init to whatever you want. does not need to be unit length Matrix view = Matrix.Identity; //these items should be updated each frame before updating camera float pitchChangeFromLastFrame, yawChangeFromLastFrame;//long names just to clarify meaning float arcPitchChangeFromLastFrame, arcYawChangeFromLastFrame; Vector3 pointToArcAbout;//usually the camTarget Vector3 strafe; public void CameraUpdate() { Matrix camWorld = Matrix.Transpose(view); //pitch camera (tilt) camTarget = Vector3.Transform(camTarget - camPosition, Matrix.CreateFromAxisAngle(camWorld.Right, pitchChangeFromLastFrame)) + camPosition; //yaw camera (pan) camTarget = Vector3.Transform(camTarget - camPosition, Matrix.CreateFromAxisAngle(camWorld.Up, yawChangeFromLastFrame)) + camPosition;//often you would use 0,1,0 instead of camWorld.Up //strafe camera (track) camPosition += strafe; camTarget += strafe; //arc camera (pitch) camPosition = Vector3.Transform(camPosition - pointToArcAbout, Matrix.CreateFromAxisAngle(camWorld.Right, arcPitchChangeFromLastFrame)) + pointToArcAbout; //arc camera (yaw) camPosition = Vector3.Transform(camPosition - pointToArcAbout, Matrix.CreateFromAxisAngle(camWorld.Up, arcYawChangeFromLastFrame)) + pointToArcAbout; //rebuild view matrix view = Matrix.CreateLookAt(camPosition, camTarget, Vector3.Up);//creates an ortho normal matrix each frame from 2 vectors (camTarget - camPosition, & the up vector) } 

本质上这需要在空间(位置和目标)2点,并围绕彼此(使用本地轴)旋转它们或将它们一起移动(strafe),然后建立一个全新的ortho标准matrix从他们每帧。