嘿!要到礼拜五,时间过得真快。好吧,切入正题,继续说我的loon开发心得!事先说明,说的不好,说错的,可别喷人!
我还没接触3d的时候,一直想着3d这视图是怎么定位的,怎么转起来,用到了什么技术。我一直带着这个疑问开始了自己的3d之路。3d是难,所以我选择了难中最简单的3d框架(xna)来学习。学的过程第一个接触到的就是3d世界里的摄像机。对,摄像机在3d里面是不可缺的组件!来说说像魔兽世界那样的相机是怎么实现的!
一个摄像机由两个矩阵组成,1:投影矩阵,视图矩阵。在xna里面的矩阵是4*4的。在xna下,创建这两个矩阵是很轻松的事情,不要任何基本技术。创建投影矩阵Matrix.CreatePerspectiveFieldOfView 用这个就很容易的创建出来, 只需要四个参数 ,视角弧度,摄像机长宽比,摄像机多近时无法看清物体,摄像机多远时无法看清物体。怎么样,很简单吧。一般投影矩阵创建了之后,就不会再改变它了,除非你屏幕拉大变小要重新创建投影矩阵。创建视图矩阵也简单,不过这个视图矩阵参数要了解清楚,因为在游戏过程中,我们要实时的更新这个视图矩阵。用Matrix.CreateLookAt 可以创建一个视图矩阵。来说下这个视图矩阵的参数,1摄像机的位置,这位在比较好理解。2:摄像机的方向,这个方向就重要了,这个方向要加上相机的位置才能得到摄像机最终的方向。好比你在马路上行走,你头一直向左看着,你人向前移动,你眼睛看得东西是不是在往后移动。因为你向前移动了,方向也跟着向前移动,所以,视图矩阵的第二参数(方向)一定要加上相机的位置才行!相机的方向很多地方会用到。比如:控制role向前移动的方向3:相机的朝向,相机到底是倒立着,还是正的,就靠这第三参数了。有了上面两个矩阵就可以组成一个相机了,不管复杂的相机都是如此!接下来,我也不废话了,看下魔兽的相机是怎么实现的,相机怎么围绕的role旋转,怎么用鼠标控制相机左右上下旋转。
说下基本知识:
向量 Vector3 就x,y,z。
矩阵 Matrix 矩阵旋转:Matrix.CreateRotationX 围绕x转旋转,还有y,z同理。
Vector3.Transform 这个根据一个矩阵获取一个向量。
xna里面的坐标系是右手坐标系(笛卡尔坐标系)。
好晚了,不写了,今天就到这把!我先把代码贴出来,下个微博再为你们解释,抱歉!
这是相机类,跟wow一样的相机,不会难。 支持者,请顶一下,让更多的人看到。
//鼠标控制相机旋转
int dx = this.engine.mouse.X - this.engine.oldMouse.X;
int dy = this.engine.mouse.Y - this.engine.oldMouse.Y;
this.engine.oldMouse = this.engine.mouse;
if (this.engine.mouse.RightButton == ButtonState.Pressed)
{
CameraOrbitAngle += dx * MathHelper.Pi / 300.0f;
CameraPitchAngle -= dy * MathHelper.Pi / 300.0f;
}
this.engine.camera.SetThirdPersonView(CameraOrbitAngle, CameraPitchAngle);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Loon.SceneNodes;
namespace Loon.Cameras
{
public class Camera
{
private Vector3 fang = Vector3.Zero;
private Matrix projectionMatrix;
private Matrix viewMatrix;
public Matrix cameraFacingMatrix = Matrix.Identity;
public Vector3 CameraPositionOffset = new Vector3(0, 0, 100);
public Vector3 CameraTargetOffset = new Vector3(0, 0, 0);
public Vector3 cameraPosition = Vector3.Zero;
public Vector3 cameraTarget = Vector3.Zero;
private float orbitRadians = 0.0f;
private float pitchRadians = 0.0f;
public GraphicsDevice graphicsDevice;
RoleModelSceneNode role;
public Camera(GraphicsDevice graphicsDevice)
{
this.graphicsDevice = graphicsDevice;
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f), graphicsDevice.Viewport.AspectRatio, 1f, 1000);
}
public void Update() {
cameraFacingMatrix = Matrix.CreateRotationX(-pitchRadians) * Matrix.CreateRotationY(-orbitRadians);
Vector3 positionOffset = Vector3.Transform(CameraPositionOffset,
cameraFacingMatrix);
Vector3 targetOffset = Vector3.Transform(CameraTargetOffset,
cameraFacingMatrix);
cameraPosition = Utility.JVectorToVector(role.Body.Position) + positionOffset;
cameraTarget = Utility.JVectorToVector(role.Body.Position) + targetOffset;
fang = cameraTarget - cameraPosition;
fang.Y = 0.0000001f;
fang.Normalize();
viewMatrix = Matrix.CreateLookAt(cameraPosition,
cameraTarget,
Vector3.Up);
}
public Vector3 GetCameraDirection() {
Vector3 dir = Vector3.Zero;
dir = cameraTarget - cameraPosition;
dir.Normalize();
return dir;
}
public void SetThirdPersonView(float orbitRadians, float pitchRadians)
{
this.orbitRadians = orbitRadians;
this.pitchRadians = pitchRadians;
}
public Vector3 Fang
{
get {
fang.Y = 0;
fang.Normalize();
return fang;
}
set { fang = value; }
}
public Matrix ViewMatrix
{
get { return viewMatrix; }
set { viewMatrix = value; }
}
public Matrix ProjectionMatrix
{
get { return projectionMatrix; }
set { projectionMatrix = value; }
}
public RoleModelSceneNode Role
{
get { return role; }
set { role = value; }
}
}
}