自己根据C++ D3D的源码改写一个相机类(第一人称)。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.DirectX;
using Microsoft.DirectX.PrivateImplementationDetails;
using Microsoft.DirectX.Direct3D; namespace AppScene
{
public enum CameraType { LANDOBJECT, AIRCRAFT };
public class Camera
{
CameraType mCameraType;
Vector3 mPosition; //相机位置
Vector3 mLook;//LookVector
Vector3 mUp;// UpVector
Vector3 mRight;// RightVector
Vector3 ViewFrustum;// 平面截投体 protected Viewport mViewPort;//视口大小
protected Matrix m_ProjectionMatrix; //上一次渲染采用的投影变换矩阵 Projection matrix used in last render.
protected Matrix m_ViewMatrix; //上一次渲染采用的观察矩阵 View matrix used in last render.
protected Matrix m_WorldMatrix = Matrix.Identity;//世界变换矩阵
public Camera()
{
mCameraType = CameraType.AIRCRAFT;
mPosition = new Vector3(0.0f, 0.0f, -50.0f);//注意默认位置,现在对了。
mRight = new Vector3(0.0f, 1.0f, 0.0f);
mUp = new Vector3(0.0f, 1.0f, 0.0f);
mLook = new Vector3(0.0f, 0.0f, 10.0f);
}
public Camera(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 upVector)
{
mCameraType = CameraType.AIRCRAFT;
mPosition = new Vector3(0.0f, 0.0f, -100.0f);
mRight = new Vector3(1.0f, 0.0f, 0.0f);
mUp = new Vector3(0.0f, 1.0f, 0.0f);
mLook = new Vector3(0.0f, 0.0f, 0.0f);
}
public void setCameraType(CameraType cameraType)
{
mCameraType = cameraType;
}
//前后移动
public void walk(float units)
{
// move only on xz plane for land object
if (mCameraType == CameraType.LANDOBJECT)
mPosition += new Vector3(mLook.X, 0.0f, mLook.Z) * units; if (mCameraType == CameraType.AIRCRAFT)
mPosition += mLook * units;
}
//左右移动,扫射
public void strafe(float units)
{
// move only on xz plane for land object
if (mCameraType == CameraType.LANDOBJECT)
mPosition += new Vector3(mRight.X, 0.0f, mRight.Z) * units; if (mCameraType == CameraType.AIRCRAFT)
mPosition += mRight * units;
}
//上下移动
public void fly(float units)
{
// move only on y-axis for land object
if (mCameraType == CameraType.LANDOBJECT)
mPosition.Y += units; if (mCameraType == CameraType.AIRCRAFT)
mPosition += mUp * units;
} // 倾斜角
public void Pitch(float angle)
{
Matrix T = Matrix.Identity;
//D3DXMatrixRotationAxis(&T, &_right, angle);
T.RotateAxis(mRight, angle);
// rotate _up and _look around _right vector
mUp.TransformCoordinate(T);
mLook.TransformCoordinate(T);
//D3DXVec3TransformCoord(&_up, &_up, &T);
//D3DXVec3TransformCoord(&_look, &_look, &T);
}
//俯仰角
public void Roll(float angle)
{
// only roll for aircraft type
if (mCameraType == CameraType.AIRCRAFT)
{
Matrix T = Matrix.Identity;
T.RotateAxis(mLook, angle); // rotate _up and _right around _look vector
mRight.TransformCoordinate(T);
mUp.TransformCoordinate(T);
}
}
// 航偏角
public void Yaw(float angle)
{
Matrix T = Matrix.Identity; // rotate around world y (0, 1, 0) always for land object
if (mCameraType == CameraType.LANDOBJECT)
T.RotateY(angle);
// rotate around own up vector for aircraft
if (mCameraType == CameraType.AIRCRAFT)
T.RotateAxis(mUp, angle); // rotate _right and _look around _up or y-axis
mRight.TransformCoordinate(T);
mLook.TransformCoordinate(T);
}
public void SetPosition(Vector3 position)// 设置相机世界坐标
{
mPosition = position;
}
//更新相机状态
public Matrix UpdateCamera()
{
Matrix mViewMatrix = Matrix.Identity;
// Keep camera's axes orthogonal to eachother
//D3DXVec3Normalize(&_look, &_look);
mLook.Normalize();
//D3DXVec3Cross(&, &_look, &_right);
// _up = Vector3.Cross(_look, _right);
//D3DXVec3Normalize(&_up, &_up);
mUp.Normalize();
//D3DXVec3Cross(&_right, &_up, &_look);
mRight = Vector3.Cross(mUp, mLook);
//D3DXVec3Normalize(&_right, &_right);
mRight.Normalize();
// Build the view matrix:
//float x = -D3DXVec3Dot(&_right, &_pos);
//float y = -D3DXVec3Dot(&_up, &_pos);
//float z = -D3DXVec3Dot(&_look, &_pos);
float x = -Vector3.Dot(mRight, mPosition);
float y = -Vector3.Dot(mUp, mPosition);
float z = -Vector3.Dot(mLook, mPosition); mViewMatrix.M11 = mRight.X; mViewMatrix.M12 = mUp.X; mViewMatrix.M13 = mLook.X; mViewMatrix.M14 = 0.0f;
mViewMatrix.M21 = mRight.Y; mViewMatrix.M22 = mUp.Y; mViewMatrix.M23 = mLook.Y; mViewMatrix.M24 = 0.0f;
mViewMatrix.M31 = mRight.Z; mViewMatrix.M32 = mUp.Z; mViewMatrix.M33 = mLook.Z; mViewMatrix.M34 = 0.0f;
mViewMatrix.M41 = x; mViewMatrix.M42 = y; mViewMatrix.M43 = z; mViewMatrix.M44 = 1.0f;
return mViewMatrix;
} public void Update(Microsoft.DirectX.Direct3D.Device m_Device3d)
{
Matrix V = UpdateCamera();
m_Device3d.SetTransform(TransformType.View, V);
}
//视口大小
public Viewport Viewport
{
get
{
return mViewPort;
}
}
//观察变换矩阵
public Matrix ViewMatrix
{
get
{
return m_ViewMatrix;
}
}
//投影变换矩阵
public Matrix ProjectionMatrix
{
get
{
return m_ProjectionMatrix;
}
}
//世界变换矩阵
public Matrix WorldMatrix
{
get
{
return m_WorldMatrix;
}
}
/// <summary>
/// UnProject和Project之前需要调用该方法
/// </summary>
/// <param name="m_Device3d"></param>
public void ComputeMatrix(Device m_Device3d)
{
m_WorldMatrix = m_Device3d.GetTransform(TransformType.World);
m_ProjectionMatrix = m_Device3d.GetTransform(TransformType.Projection);
m_ViewMatrix = m_Device3d.GetTransform(TransformType.View);
mViewPort = m_Device3d.Viewport;
}
/// <summary>
/// Projects a point from world to screen coordinates.
/// 计算指定世界坐标的屏幕坐标
/// </summary>
/// <param name="point">Point in world space</param>
/// <returns>Point in screen space</returns>
public Vector3 Project(Vector3 point)
{
point.Project(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
return point;
} internal Vector3 UnProject(Vector3 v1)
{
v1.Unproject(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
return v1;
}
}
}

增加一个围绕某条射线旋转的方法:

  //
public void RotateRay(float angle, Vector3 vOrigin, Vector3 vAxis)
{
// 计算新的焦点
Vector3 vView = mLook - vOrigin;
Matrix temp = Matrix.RotationAxis(vAxis, angle);
vView.TransformCoordinate(temp);
//vView.RotateAxis(angle, vAxis);
mLook = vOrigin + vView; // 计算新的视点
vView = mPosition - vOrigin;
// Matrix temp2 = Matrix.RotationAxis(vAxis, angle);
vView.TransformCoordinate(temp);
//vView.RotateAxis(angle, vAxis);
mPosition = vOrigin + vView; mUp.TransformCoordinate(temp);
// m_strafe.RotateAxis(angle, vAxis);
}

[3D]第一人称相机类Camera的更多相关文章

  1. 关于Unity中FPS第一人称射击类游戏制作(专题十)

    当前Unity最新版本5.6.3f1,我使用的是5.5.1f1 场景搭建 1: 导入人物模型, 手持一把枪;2: 导入碎片模型;3: 创建一个平面;4: 创建一个障碍物;5: 导入人物模型;6: 配置 ...

  2. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 代码工程地址: https://g ...

  3. 【转】265行JavaScript代码的第一人称3D H5游戏Demo

    译文:http://blog.jobbole.com/70956/ 原文:http://www.playfuljs.com/a-first-person-engine-in-265-lines/ 这是 ...

  4. android Camera相机类

    Camera相机类相关的几个流程方法 Camera.open(cameraId) 打开相机 camera.setDisplayOrientation(0) 设置相机水平方向 mCamera.setPr ...

  5. Opengl绘制我们的小屋(二)第一人称漫游

    这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...

  6. 【Unity】2.8 相机(Camera)

    分类:Unity.C#.VS2015 创建日期:2016-03-31 一.简介 Unity的相机用来向玩家呈现游戏世界.你在场景中始终至少有一个相机,但也可以有多个.多个相机可以带给您双人分屏效果或创 ...

  7. unity3d学习笔记(一) 第一人称视角实现和倒计时实现

    unity3d学习笔记(一) 第一人称视角实现和倒计时实现 1. 第一人称视角 (1)让mainCamera和player(视角对象)同步在一起 因为我们的player是生成的,所以不能把mainCa ...

  8. D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建

    说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...

  9. 基于HTML5及WebGL开发的2D3D第一人称漫游进行碰撞检测

    为了实现一个基于HTML5的场景小游戏,我采用了HT for Web来实现,短短200行代码,我就能实现用“第一人称”来操作前进后退上下左右,并且实现了碰撞检测. 先来看下实现的效果:http://h ...

随机推荐

  1. VC++实现编辑框输入提示效果

    编辑框在第一次输入时最好给出一个虚拟的输入提示信息文本,这样的效果更佳友好.,我在编辑框添加灰色提示字(html+VC)一文中简单介绍了一些方法,但是效果欠佳. 原始的编辑框CEdit类没有这样的功能 ...

  2. 拼凑sql语句另外一个方法

    经常拼凑sql语句,经常是手工拼写 也可以利用字典另外一个模式拼凑 这里采用的是Dictionary中的Aggregate方法. 代码如下: static void Main(string[] arg ...

  3. mysql数据库,如何在登录mysql之后执行操作系统上的SQL脚本?

    需求描述: 通过mysql客户端登录到mysql数据库,如何执行操作系统上的SQL脚本文件呢? 操作过程: 1.编写测试脚本文件 [mysql@redhat6 scripts]$ cat SeCoun ...

  4. 使用CXF为webservice添加拦截器

      拦截器分为Service端和Client端 拦截器是在发送soap消息包的某一个时机拦截soap消息包,对soap消息包的数据进行分析或处理.分为CXF自带的拦截器和自定义的拦截器 1.Servi ...

  5. 南京IT企业环境之最深心得体会

    我是南京做嵌入式的. 之前搞过一年的PC平台Linux内核开发,Linux内核态的仅仅要不是非常复杂的BUG还是能修复的.一年的Linux用户态软件开发. 然后近期搞了两年ARM嵌入式开发. 做的CM ...

  6. Python 入门(五)条件判断和循环

    if语句 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,可以用if语句实现: age = 20 if age > ...

  7. C++模板中的嵌套

    在下面的程序中,我们创建了一个模板类用于实现Queue容器的部分功能,并且在模板类中潜逃使用了一个Node类.queuetp.h // queuetp.h -- queue template with ...

  8. ubuntu下code::blocks编译运行一个简单的gtk+2.0项目

    在具体的操作之前,首先需要安装一些必要的软件.ubuntu下默认安装了gcc,不过缺少必要的Header file,可以在命令行中输入下面的指令安装build-essential套件:sudo apt ...

  9. php PDO简介和操作

    PDO:数据访问抽象层 具有三大特点: 1.可以访问其它数据库  所有数据库都可以 2.具有事务功能 3.带有预处理语句功能(防止SQL注入攻击) <?php //1.造PDO对象 $dsn = ...

  10. MQTT的学习研究(十四) MQTT moquette 的 Callback API 消息发布订阅的实现

    在moquette-mqtt中提供了回调callback模式的发布和订阅但是在订阅之后没有发现有消息接收的方法,参看moquette-mqtt中Block,Future式的发布订阅基础是callbac ...