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. 我碰到的stackoverflow error

    出现这种问题,首先需要检查自己的代码: 要么代码小错误:或者逻辑错误: 如果出现循环调用更要仔细检查: 我的问题: 循环调用:一个实体他有自己的父栏目,含有子栏目的list集合:两者结果映射resul ...

  2. JavaWeb分页-----PageBean.java

    package com.zzuli.util; import java.util.List; /** * PageBean类 * @author hejjon * @date 2019年6月8日 下午 ...

  3. HTML5深入学习之 WebSQL 数据库

    概述 WebSQL 并不是 HTML5规范的一部分,而是一个独立的规范,它可以用来做一些离线应用 核心API openDatabase() => 用来打开或创建数据库(没有时则创建,有则打开) ...

  4. MySQL导入数据报错Got a packet bigger than‘max_allowed_packet’bytes错误的解决方法

    由于max_allowed_packet的值设置过小的原因,只需要将max_allowed_packet值设置大一点就OK了.通过终端进入mysql控制台,输入如下命令可以查看max_allowed_ ...

  5. 为 Linux 应用程序编写 DLL

    插件和 DLL 通常是用来无须编写整个新应用程序而添加功能的极好方法. 在 Linux 中,插件和 DLL 是以动态库形式实现的. 电子商务顾问兼设计师 Allen Wilson 介绍了动态库,并且向 ...

  6. android Camera 之 ZSL

    ZSL的概念 ZSL (zero shutter lag) 中文名称为零延时拍照,是为了减少拍照延时,让拍照&回显瞬间完成的一种技术. Single Shot 当开始预览后,sensor 和  ...

  7. PHP实现Redis单据锁,防止并发重复写入

    一.写在前面 在整个供应链系统中,会有很多种单据(采购单.入库单.到货单.运单等等),在涉及写单据数据的接口时(增删改操作),即使前端做了相关限制,还是有可能因为网络或异常操作产生并发重复调用的情况, ...

  8. linux常见依赖

    1. 搭建LNMP环境用到的依赖包 yum -y install gcc gcc-c++ libxml2 libxml2-devel openssl openssl-devel curl libcur ...

  9. XSS简单练习

    xss平台: https://xss.haozi.me题解: https://blog.csdn.net/AlexYoung28/article/details/82315538 对在xss.haoz ...

  10. Matplotlib同时绘制多张图片

    我现在有一组图片,一共100张图片,每张大小是200*200,即imgs.shape=100*200*200*3 (注意通道数在最后一维). 我需要同时绘制这100张图片,而且每张图片需要写上对应的名 ...