3D中的相机 - 投影矩阵和视图矩阵
3d游戏中,一般通过相机的设置来计算投影矩阵和视图矩阵,比如untiy和cocos,一般情况下我们不用关注如何计算,
可以直接在可视化的编辑器中调整参数就可以了,但是了解下总是好的。
具体计算可以参考:
可以参考现在cocos2dx的代码中的Camera源码,里面有根据相机的设置(位置等)计算上面两个矩阵的代码。
也可以参考下面这个,github上面一个项目,这个项目有很好的参考价值:
https://github.com/wantnon2/3DToolKit-2-for-cocos2dx/blob/master/c3dToolKit/core/c3dCamera.h
```
//
// c3dCamera.h
// HelloCpp
//
// Created by Yang Chao (wantnon) on 14-1-7.
//
//
#ifndef __HelloCpp__c3dCamera__
#define __HelloCpp__c3dCamera__ #include <iostream>
using namespace std;
#include "cocos2d.h"
using namespace cocos2d;
#include "c3dVector.h"
#include "c3dMatrix.h"
#include "c3dGLMath.h"
#include "c3dCommonFunc.h"
#include "c3dMatrixStackInfoGetor.h"
#include "c3dRange.h"
class Cc3dCamera:public CCCamera
{
public:
Cc3dCamera(){
CCSize winSize=CCDirector::sharedDirector()->getWinSize();
m_fovy=;
m_aspect=winSize.width/winSize.height;
m_zNear=;//554/2;//0.5;
m_zFar=; const float w=winSize.width;//11;
const float h=winSize.height;//w*winSize.height/winSize.width;
m_range.init(-w/, -w/+w, -h/, -h/+h,
-,//yeah, better to use negative value
);
m_projectionMode=ec3dPerspectiveMode;
m_isViewMatDirty=false;
m_isViewMatInverseDirty=false; }
virtual ~Cc3dCamera(){ } Cc3dVector4 getEyePos()const;
Cc3dVector4 getCenter()const;
Cc3dVector4 getUp()const;
void setEyePos(const Cc3dVector4&eyePos);
void setCenter(const Cc3dVector4&center);
void setUp(const Cc3dVector4&up);
float getFovy()const {return m_fovy;}
float getAspect()const {return m_aspect;}
float getzNear()const {return m_zNear;}
float getzFar()const {return m_zFar;}
void setFovy(float fovy){m_fovy=fovy;}
void setAspect(float aspect){m_aspect=aspect;}
void setzNear(float zNear){m_zNear=zNear;}
void setzFar(float zFar){m_zFar=zFar;}
Cc3dRange getRange()const {return m_range;}
void setRange(const Cc3dRange&range){m_range=range;}
Cc3dMatrix4 calculateViewMat();
Cc3dMatrix4 calculateViewMatInverse();
Cc3dMatrix4 calculateProjectionMat();
Ec3dProjectionMode getProjectionMode(){return m_projectionMode;}
void setProjectionMode(Ec3dProjectionMode projectionMode){m_projectionMode=projectionMode;}
void applyProjection();
void printProjectionMode()const;
protected:
//projection mode type
Ec3dProjectionMode m_projectionMode;
//perspective projection mode params
float m_fovy;
float m_aspect;
float m_zNear;
float m_zFar;
//Ortho projection mode params
Cc3dRange m_range;//in the camera space
protected:
//cache viewMat
Cc3dMatrix4 m_viewMatCache;
bool m_isViewMatDirty;
Cc3dMatrix4 m_viewMatInverseCache;
bool m_isViewMatInverseDirty; };
#endif /* defined(__HelloCpp__c3dCamera__) */ //
// c3dCamera.cpp
// HelloCpp
//
// Created by Yang Chao (wantnon) on 14-1-7.
//
// #include "c3dCamera.h" Cc3dVector4 Cc3dCamera::getEyePos()const{
//getEyeXYZ is not const, but i want getEyePos to be const
//so i convert this from const to nonconst
float eyex,eyey,eyez;
((Cc3dCamera*)this)->getEyeXYZ(&eyex, &eyey, &eyez);
return Cc3dVector4(eyex,eyey,eyez,);
}
Cc3dVector4 Cc3dCamera::getCenter()const{
//getCenterXYZ is not const, but i want getCenter to be const
//so i convert this from const to nonconst
float centerX,centerY,centerZ;
((Cc3dCamera*)this)->getCenterXYZ(&centerX, &centerY, &centerZ);
return Cc3dVector4(centerX,centerY,centerZ,);
}
Cc3dVector4 Cc3dCamera::getUp()const{
//getUpXYZ is not const, but i want getUp to be const
//so i convert this from const to nonconst
float upX,upY,upZ;
((Cc3dCamera*)this)->getUpXYZ(&upX, &upY, &upZ);
return Cc3dVector4(upX,upY,upZ,);
}
void Cc3dCamera::setEyePos(const Cc3dVector4&eyePos){
this->setEyeXYZ(eyePos.x(), eyePos.y(), eyePos.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true; }
void Cc3dCamera::setCenter(const Cc3dVector4&center){
this->setCenterXYZ(center.x(), center.y(), center.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true; }
void Cc3dCamera::setUp(const Cc3dVector4&up){
this->setUpXYZ(up.x(), up.y(), up.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true;
} Cc3dMatrix4 Cc3dCamera::calculateViewMat(){
//why we not just return CCCamera::m_lookupMatrix?
//because m_lookupMatrix may be dirty (m_lookupMatrix got updated only when locate is called)
//so we calculate view matrix ourselves.
Cc3dMatrix4 ret;
if(m_isViewMatDirty){//dirty
//calculate and cache
ret=::calculateViewMatrix(getEyePos(), getCenter(), getUp());
m_viewMatCache=ret;
}else{//not dirty
//get from cache
ret=m_viewMatCache;
}
return ret; };
Cc3dMatrix4 Cc3dCamera::calculateViewMatInverse(){
Cc3dMatrix4 ret;
if(m_isViewMatInverseDirty){
ret=::calculateViewMatrixInverse(getEyePos(), getCenter(), getUp());
m_viewMatInverseCache=ret;
}else{
ret=m_viewMatInverseCache;
}
return ret;
}
Cc3dMatrix4 Cc3dCamera::calculateProjectionMat(){
Cc3dMatrix4 projectionMat;
switch (m_projectionMode) {
case ec3dPerspectiveMode:
projectionMat=::calculatePerspectiveProjectionMatrix(m_fovy, m_aspect, m_zNear, m_zFar);
break;
case ec3dOrthographicMode:
projectionMat=::calculateOrthoProjectionMatrix(m_range.getMinX(), m_range.getMaxX(), m_range.getMinY(), m_range.getMaxY(), m_range.getMinZ(), m_range.getMaxZ());
break;
default:
assert(false);
break;
}
return projectionMat;
}
void Cc3dCamera::applyProjection()
//note: after apply projection matrix, will be back to modelview matrix stack
{
Cc3dMatrix4 projectionMat=calculateProjectionMat();
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity();
kmMat4 projMat;
memcpy(projMat.mat, projectionMat.getArray(), *sizeof(float));
kmGLMultMatrix(&projMat);
//restore to model view stack
kmGLMatrixMode(KM_GL_MODELVIEW); };
void Cc3dCamera::printProjectionMode()const{
if(m_projectionMode==ec3dPerspectiveMode){
C3DLOG("projectionMode: perspectiveMode");
}else if(m_projectionMode==ec3dOrthographicMode){
C3DLOG("projectionMode: orthographic");
}else{
assert(false);
}
}
```

3D中的相机 - 投影矩阵和视图矩阵的更多相关文章

  1. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  2. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  3. 2d,3d中旋转推导

    二维绕原点旋转,其实点为(x,y),旋转角度为黄色标注的角度. 推导过程如下: x' = r cos(al+be); y' = r sin(al+be);x '= rcosalcosbe-rsinal ...

  4. 3D中的旋转变换

    相比 2D 中的旋转变换,3D 中的旋转变换复杂了很多.关于 2D 空间的旋转,可以看这篇文章.本文主要粗略地探讨一下 3D 空间中的旋转. 旋转的要素 所谓旋转要素就是说,我们只有知道了这些条件,才 ...

  5. [原][osgEarth]在osgearth中添加相机路径动画

    在osg中添加相机动画路径请参考:http://www.cnblogs.com/lyggqm/p/8075277.html 这里的代码是在osgearth中添加相机动画路径漫游器: #include ...

  6. 3D数学读书笔记——3D中的方位与角位移

    本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...

  7. WebView中打开相机,文件选择器的问题和解决方法

    近几年前端开发真是越来越火,H5页面开发的移动端页面甚至有夺我原生开发半壁江山的意思,忧伤忧伤.不过从实际情况考虑,H5一套代码到处跑的特性,我们的Android, IOS ...也就只能呵呵了.然而 ...

  8. OpenGL(五) 三维变换之模型视图矩阵

    计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...

  9. 对CSS3中的transform:Matrix()矩阵的一些理解

    只要有CSS基础的人肯定都知道,我们可以通过transform中的translate,scale,rotate,skew这些方法来控制元素的平移,缩放,旋转,斜切,其实这些方法呢都是为了便于开发者使用 ...

随机推荐

  1. iframe中操作主体页面的元素,方法

    在不使用三大框架的情况下,iframe的使用可以做到在页面中直接引入别的页面作为当前页面的一部分,但是在iframe的使用过程中存在一些相互之间的操作 例如在iframe中获取主页面的元素,使用主页面 ...

  2. Android-----创建SQLite数据库

    简单介绍一下Android系统内置轻便又功能强大的嵌入式数据库--SQLite. SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎,它是一款轻型的数据库,是遵守ACID的关 ...

  3. k8s的node节点无法调度的问题

    1.现象,创建deployment时 2.查看污点 [fedora@k8s-cluster--ycmwlao4q5wz-master- ~]$ kubectl describe node k8s-cl ...

  4. Django 之 restframework 解析器的使用

    请求头ContentType application/x-www-form-urlencoded 这应该是最常见的 POST 提交数据的方式了.浏览器的原生 <form> 表单,如果不设置 ...

  5. Centos 7 kubernetes集群搭建

    一.环境准备 Kubernetes支持在物理服务器或虚拟机中运行,本次使用虚拟机准备测试环境,硬件配置信息如表所示: IP地址 节点角色 CPU Memory Hostname 磁盘 192.168. ...

  6. delay timer的wrap around

    span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror ...

  7. 接口自动化--读取Excel操作(openpyxl)

    上次我们已经将requests库封装成我们想要的样子了,我们的接口自动化已经完成了最开始的一步了,接下来我们需要完成我们相应的其他模块的封装,下面简单介绍下我们在接口自动化需要用到的模块吧在接口自动化 ...

  8. Ueditor 自动设置上传图片的宽度或高度

    Uedior在上传图片的生活,需要自动设置上传图片的宽度或高度属性.该方法只能用于多图上传组件,单图上传无法使用. 该方法基于 ueditor 1.4.3 版本制作: 1.添加属性字段,在config ...

  9. Tensorflow中保存模型时生成的各种文件区别和作用

    假如我们得到了如下的checkpoints, 上面的文件主要可以分成三类:一种是在保存模型时生成的文件,一种是我们在使用tensorboard时生成的文件,还有一种就是plugins这个文件夹,这个是 ...

  10. vue 项目中安装npm--save-dev 和 --save 命令

    在vue项目中我们常用npm install 安装模块或插件 有两种命令把他们写入到 package.json 文件里面去 例如安装axios 安装到开发环境npm axios --save-dev ...