您的位置:首页 > 其它

CCCamera(可以用来做3d效果 如卡牌翻转 等需要展示物体的立体效果 )

2014-05-21 18:48 239 查看
.h

#ifndef __CCCAMERA_H__
#define __CCCAMERA_H__

#include "cocoa/CCObject.h"
#include "ccMacros.h"
#include "kazmath/mat4.h"
#include <string>

NS_CC_BEGIN

////////////////////////////////////////
A CCCamera is used in every CCNode.
Useful to look at the object from different views.
The OpenGL gluLookAt() function is used to locate the
camera.

If the object is transformed by any of the scale, rotation or
position attributes, then they will override(推翻 重写) the camera.

IMPORTANT: Either your use the camera or the rotation/scale/position properties(property
性能,道具). You can't use both.
World coordinates(坐标) won't work if you use the camera.

Limitations:(camera无效情况1和2,建议只在需要3d效果时使用camera)

-1、 Some nodes, like CCParallaxNode, CCParticle uses world node coordinates(坐标), and they won't work properly(适当的) if you move them (or any of their
ancestors(祖先))
using the camera.

-2、It doesn't work on batched(batch 一批) nodes like CCSprite objects when they are parented(专利的) to a CCSpriteBatchNode object.

- It is recommended(推荐) to use it ONLY if you are going to create 3D effects. For 2D effects, use the action CCFollow or position/scale/rotate.
/////////////////////////////////////////
class CC_DLL CCCamera : public CCObject
{
protected:
float m_fEyeX;
float m_fEyeY;
float m_fEyeZ;

float m_fCenterX;
float m_fCenterY;
float m_fCenterZ;

float m_fUpX;
float m_fUpY;
float m_fUpZ;

bool m_bDirty;
kmMat4 m_lookupMatrix;
public:
CCCamera(void);
~CCCamera(void);

void init(void);

const char* description(void);//为了更方便的输出调试信息,增加了description函数

inline void setDirty(bool bValue) { m_bDirty = bValue; }

inline bool isDirty(void) { return m_bDirty; }

void restore(void);//初始化时调用 给camera赋默认初值
/** Sets the camera using gluLookAt using its eye, center and up_vector */
void locate(void);

//以“Eye”为起点 eye是一个位置点
void setEyeXYZ(float fEyeX, float fEyeY, float fEyeZ);

//朝“Center”看 center是一个向量
void setCenterXYZ(float fCenterX, float fCenterY, float fCenterZ);

//沿着“Up”方向 站着看地上一个图片 转动身体后看到的图片会也会转
void setUpXYZ(float fUpX, float fUpY, float fUpZ);

void getEyeXYZ(float *pEyeX, float *pEyeY, float *pEyeZ);
void getCenterXYZ(float *pCenterX, float *pCenterY, float *pCenterZ);
void getUpXYZ(float *pUpX, float *pUpY, float *pUpZ);
public:
static float getZEye();//返回一个无限趋于0的folat (用来初始化 z)

private:
DISALLOW_COPY_AND_ASSIGN(CCCamera);
};

NS_CC_END

#endif // __CCCAMERA_H__

——————————————————————————————————————————————————————————
.cpp

const char* CCCamera::description(void)
{
return CCString::createWithFormat("<CCCamera | center = (%.2f,%.2f,%.2f)>", m_fCenterX, m_fCenterY, m_fCenterZ)->getCString();
}

void CCCamera::init(void)
{
restore();
}

void CCCamera::restore(void)
{
m_fEyeX = m_fEyeY = 0.0f;
m_fEyeZ = getZEye();

m_fCenterX = m_fCenterY = m_fCenterZ = 0.0f;

m_fUpX = 0.0f;
m_fUpY = 1.0f;
m_fUpZ = 0.0f;

kmMat4Identity( &m_lookupMatrix );

m_bDirty = false;
}
//////////////////

kmMat4* const kmMat4Identity(kmMat4* pOut)//参数是 输出参数 m_lookupMatrix
{
//将pOut->mat中前 sizeof(float) * 16个字节用
0 替换并返回 pOut->mat。
memset(pOut->mat, 0, sizeof(float) * 16);

pOut->mat[0] = pOut->mat[5] = pOut->mat[10] = pOut->mat[15] = 1.0f;
return pOut;
}
////////////////////

void CCCamera::locate(void)
{
if (m_bDirty)
{
kmVec3 eye, center, up;

kmVec3Fill( &eye, m_fEyeX, m_fEyeY , m_fEyeZ );
kmVec3Fill( ¢er, m_fCenterX, m_fCenterY, m_fCenterZ );

kmVec3Fill( &up, m_fUpX, m_fUpY, m_fUpZ);
kmMat4LookAt( &m_lookupMatrix, &eye, ¢er, &up);

m_bDirty = false;
}
kmGLMultMatrix( &m_lookupMatrix );
}
///////////////// (线性代数)

/**

* Fill a kmVec3 structure using 3 floating point values

* The result is store in pOut, returns pOut

*/
kmVec3* kmVec3Fill(kmVec3* pOut, kmScalar x, kmScalar y, kmScalar z)
{
pOut->x = x;
pOut->y = y;
pOut->z = z;
return pOut;
}

/**

* Builds a translation matrix in the same way as gluLookAt()

* the resulting matrix is stored in pOut. pOut is returned.

*/

kmMat4* const kmMat4LookAt(kmMat4* pOut, const kmVec3* pEye,
const kmVec3* pCenter, const kmVec3* pUp)
{
kmVec3 f, up, s, u;
kmMat4 translate;

kmVec3Subtract(&f, pCenter, pEye);
kmVec3Normalize(&f, &f);

kmVec3Assign(&up, pUp);
kmVec3Normalize(&up, &up);

kmVec3Cross(&s, &f, &up);
kmVec3Normalize(&s, &s);

kmVec3Cross(&u, &s, &f);
kmVec3Normalize(&s, &s);

kmMat4Identity(pOut);

pOut->mat[0] = s.x;
pOut->mat[4] = s.y;
pOut->mat[8] = s.z;

pOut->mat[1] = u.x;
pOut->mat[5] = u.y;
pOut->mat[9] = u.z;

pOut->mat[2] = -f.x;
pOut->mat[6] = -f.y;
pOut->mat[10] = -f.z;

kmMat4Translation(&translate, -pEye->x, -pEye->y, -pEye->z);
kmMat4Multiply(pOut, pOut, &translate);

return pOut;
}

/**

* Subtracts 2 vectors and returns the result. The result is stored in

* pOut.

*/

kmVec3* kmVec3Subtract(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
{
kmVec3 v;

v.x = pV1->x - pV2->x;
v.y = pV1->y - pV2->y;
v.z = pV1->z - pV2->z;

pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;

return pOut;
}

/**

* Returns the vector passed in set to unit length

* the result is stored in pOut.

*/

kmVec3* kmVec3Normalize(kmVec3* pOut, const kmVec3* pIn)
{
kmScalar l = 1.0f / kmVec3Length(pIn);

kmVec3 v;
v.x = pIn->x * l;
v.y = pIn->y * l;
v.z = pIn->z * l;

pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;

return pOut;
}

kmVec3* kmVec3Assign(kmVec3* pOut, const kmVec3* pIn) {
if (pOut == pIn) {
return pOut;
}

pOut->x = pIn->x;
pOut->y = pIn->y;
pOut->z = pIn->z;

return pOut;
}

/**

* Returns a vector perpendicular to 2 other vectors.

* The result is stored in pOut.

*/
kmVec3* kmVec3Cross(kmVec3* pOut, const kmVec3* pV1, const kmVec3* pV2)
{

kmVec3 v;

v.x = (pV1->y * pV2->z) - (pV1->z * pV2->y);
v.y = (pV1->z * pV2->x) - (pV1->x * pV2->z);
v.z = (pV1->x * pV2->y) - (pV1->y * pV2->x);

pOut->x = v.x;
pOut->y = v.y;
pOut->z = v.z;

return pOut;
}

/**

* Builds a translation matrix. All other elements in the matrix

* will be set to zero except for the diagonal which is set to 1.0

*/

kmMat4* const kmMat4Translation(kmMat4* pOut, const kmScalar x,
const kmScalar y, const kmScalar z)
{
//FIXME: Write a test for this
memset(pOut->mat, 0, sizeof(float) * 16);

pOut->mat[0] = 1.0f;
pOut->mat[5] = 1.0f;
pOut->mat[10] = 1.0f;

pOut->mat[12] = x;
pOut->mat[13] = y;
pOut->mat[14] = z;
pOut->mat[15] = 1.0f;

return pOut;
}

/**
* Multiplies pM1 with pM2, stores the result in pOut, returns pOut
*/
kmMat4* const kmMat4Multiply(kmMat4* pOut, const kmMat4* pM1, const kmMat4* pM2)
{
#if defined(__ARM_NEON__)

float mat[16];

// Invert column-order with row-order
NEON_Matrix4Mul( &pM2->mat[0], &pM1->mat[0], &mat[0] );

#else
float mat[16];

const float *m1 = pM1->mat, *m2 = pM2->mat;

mat[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
mat[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
mat[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
mat[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];

mat[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
mat[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
mat[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
mat[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];

mat[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
mat[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
mat[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
mat[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];

mat[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
mat[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
mat[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
mat[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];

#endif

memcpy(pOut->mat, mat, sizeof(float)*16);

return pOut;
}

/////////////////

//////////////////////////////////////////////////////////////////

关于cocos2dx中的摄像机

关于cocos2dx中的摄像机

1、CCCamera 默认是从前往后看(center是原点,eye的z值很小,方向是z轴),所以z值越大,越是在前面,

2、球坐标:原点是圆心,仰角theata(从z轴开始),方位角 fai,一般数学坐标系中的逆时针角

3、 CCOrbitCamera::create(float t, float radius, float deltaRadius, float angleZ, float deltaAngleZ, float angleX, float deltaAngleX)

参数依次是持续时间、半径初始值、半径增量、仰角初始值、仰角增量、离x轴的偏移角、离x轴的偏移角的增量

4、cocos2dx中的camera与一般3d中的camera的区别

cocos2dx中的camera是一个辅助类,主要是修改当前渲染的camera的matrix的(核心函数是locate),也就是尽管每个node有一个camera,实际上这个camera不是真的

opengl的camera,整个scene在渲染时一定是只有一台camera在渲染场景。这样做的好处:每个node可以单独的用2d来模拟3d的效果,而不会影响到别的node

3d引擎中的camera是一个真正的opengl的camera,有多个camera存在时会有效率方面的问题。

5、为什么3d引擎中不采用cocos2d中的方式来提高效率?

因为3d对视觉效果要求高,比如画中画效果、render to texture 实现的特效等,这时是必须要实现多个摄像机的;而对于cocos2dx而言基本上不存在这样的问题

6、CCOrbitCamera的实现逻辑

每帧根据输入的参数插值球坐标,之后改变节点eye的位置

/////////////////////////////////////////////////////


Cocos2dx概念介绍(游戏开发中不同的坐标系,cocos2dx锚点)

2013-09-06 发布: qinning199 来源: CSDN 我要评论 字号: 大 中 小

摘要: 注:ccp是cocos2dx中的一个宏定义,#define ccp(__X__,__Y__)CCPointMake((float)__X__, (float)__Y__),在此文章中表示坐标信息 1、笛卡尔坐标系 你可能在学校的几何学上已经知道笛卡尔坐标系。如...

注:ccp是cocos2dx中的一个宏定义,#define ccp(__X__,__Y__)CCPointMake((float)__X__, (float)__Y__),在此文章中表示坐标信息

1、笛卡尔坐标系

你可能在学校的几何学上已经知道笛卡尔坐标系。如果你忘记了,下面的图片可以让你回忆一下:



有3中类型的坐标系在游戏开发中你会用的到。

1)UI坐标系:

一般用于iso、android、windows sdk中:

原点(x=0,y=0)在左上角。

x方向从左侧向右侧递增。

y方向从屏幕顶部向底部递增。



2)Direct3D坐标系

DirectX用左手笛卡尔坐标系

3)OpenGL和Cocos2D坐标系

Cocos2dx和OpenGL一样用右手坐标系,在二维世界里,我们仅仅使用x轴和y轴,那么在cocos2d游戏中:



原点在屏幕的左下角,意味着屏幕在右手坐标系的第一象限中。

X轴从屏幕左侧向右侧延伸

Y轴从屏幕底部向顶部延伸

底下有张图片可以帮你理解cocos2dx坐标系:



2 父类和子类:

每一个继承自CCNode的类都有一个锚点属性。当决定如何绘制对象(Sprite,Layer,一起其他的)的时候,cocos2d-x将会考虑位置信息以及锚点信息。并且,当旋转一个物体的时候,cocos2d-x也会绕着锚点旋转。

我们创建一个灰色的Sprite的图像作为父对象,创建一个绿色的Sprite作为子对象。设置父对象的位置为ccp(100,100),锚点ccp(0,0),子对象的位置在ccp(0,0),锚点ccp(0.5,0.5)。

1    CCSprite* parent = CCSprite::create("parent.png");
2    parent->setAnchorPoint(ccp(0, 0));// Anchor Point
3    parent->setPosition(ccp(100, 100));
4    parent->setAnchorPoint(ccp(0, 0));
5    addChild(parent);
6
7    //create child
8    CCSprite* child = CCSprite::create("child.png");
9    child->setAnchorPoint(ccp(0.5, 0.5));
10    child->setPosition(ccp(0, 0));
11    parent->addChild(child);//add child sprite into parent sprite.


我们设置了子对象的位置在ccp(0,0),父对象的位置在ccp(100,100),因此,子对象显示在如图所示位置:



6、锚点

锚点被用于位置和旋转物体。锚点是相对坐标(也就是一个百分比),经常被用来对应一个物体内的点。例如,锚点是ccp(0.5,0.5)(表示x方向在物体50%的位置,y方向50%的位置)对应物体的中心。当设置物体位置的时候,调用setPositon时,锚点信息也会在坐标系中展示。相同的,当转动物体,物体将会随锚点转动。

例如,如下精灵有一个锚点cpp(0,0)并且位置在ccp(0,0):



因此,精灵被放置在屏幕左下角。


1// create sprite
2CCSprite* sprite = CCSprite::create("bottomleft.png");
3sprite->setAnchorPoint(ccp(0, 0));// Anchor Point
4sprite->setPosition(ccp(0,0));
5addChild(sprite);


在如下的例子中,展示了锚点坐标的相对性,锚点被赋值为ccp(0.5,0.5),位于精灵的中心。



1// create sprite
2CCSprite* sprite = CCSprite::create("center.png");
3sprite->setAnchorPoint(ccp(0.5, 0.5));// Anchor Point
4sprite->setPosition(ccp(0,0));
5addChild(sprite);




正如你所看到的的,精灵的中心位置被放置在了坐标原点(0,0)。这也就是说锚点不是一个像素值。锚点的X和Y值是相对于该节点的大小。

你也可以设置锚点为ccp(0.3,0.3),物体左下角锚点是(0,0),右上角是(1,1),因此ccp(0.3,0.3)表示在X方向上30%位置,Y方向上30%位置。

///////////////////////////////////////////////////////////////////////////////


一个cocos2dx的图片效果貌似的做法



旁边翻转角度效果:

var distance = (this.getPosition().x + scrollViewOffset.x );

var value = VisibleRect.center().x - distance;

var temp = value / VisibleRect.center().x / 2.5;

this.setScale(1 - Math.abs(temp));

this.getCamera().setEye(10 * temp ,0, 10);

var x = value / wd;

var offset = cc.p(x * x* x* 30, 0);

this._node.setPosition(offset);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: