2013-11-05 01:14:22 +08:00
|
|
|
//
|
|
|
|
// CCNewSprite.cpp
|
|
|
|
// cocos2d_libs
|
|
|
|
//
|
|
|
|
// Created by NiTe Luo on 10/31/13.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "CCNewSprite.h"
|
|
|
|
#include "Renderer.h"
|
2013-11-27 10:35:12 +08:00
|
|
|
#include "Frustum.h"
|
|
|
|
#include "CCDirector.h"
|
2013-12-07 06:59:06 +08:00
|
|
|
#include "QuadCommand.h"
|
2013-11-05 01:14:22 +08:00
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
2013-11-07 08:39:20 +08:00
|
|
|
#if CC_SPRITEBATCHNODE_RENDER_SUBPIXEL
|
|
|
|
#define RENDER_IN_SUBPIXEL
|
|
|
|
#else
|
|
|
|
#define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__))
|
|
|
|
#endif
|
|
|
|
|
2013-11-05 01:14:22 +08:00
|
|
|
NewSprite* NewSprite::create()
|
|
|
|
{
|
|
|
|
NewSprite* sprite = new NewSprite();
|
|
|
|
if(sprite && sprite->init())
|
|
|
|
{
|
|
|
|
sprite->autorelease();
|
|
|
|
return sprite;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(sprite);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewSprite* NewSprite::create(const char *filename)
|
|
|
|
{
|
|
|
|
NewSprite* sprite = new NewSprite();
|
|
|
|
if(sprite && sprite->initWithFile(filename))
|
|
|
|
{
|
|
|
|
sprite->autorelease();
|
|
|
|
return sprite;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(sprite);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewSprite::NewSprite()
|
|
|
|
:Sprite()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-11-13 03:14:34 +08:00
|
|
|
NewSprite::~NewSprite(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-11-23 08:09:11 +08:00
|
|
|
bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotated)
|
|
|
|
{
|
|
|
|
bool result = Sprite::initWithTexture(texture, rect, rotated);
|
|
|
|
_recursiveDirty = true;
|
|
|
|
setDirty(true);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2013-11-27 09:01:32 +08:00
|
|
|
void NewSprite::updateQuadVertices()
|
2013-11-07 08:39:20 +08:00
|
|
|
{
|
2013-11-26 08:33:05 +08:00
|
|
|
|
|
|
|
#ifdef CC_USE_PHYSICS
|
|
|
|
updatePhysicsTransform();
|
|
|
|
setDirty(true);
|
|
|
|
#endif
|
|
|
|
|
2013-11-23 08:09:11 +08:00
|
|
|
//TODO optimize the performance cache affineTransformation
|
2013-11-26 08:33:05 +08:00
|
|
|
|
|
|
|
// recalculate matrix only if it is dirty
|
|
|
|
if(isDirty())
|
|
|
|
{
|
2013-11-27 03:48:37 +08:00
|
|
|
|
|
|
|
// if( ! _parent || _parent == (Node*)_batchNode )
|
|
|
|
// {
|
|
|
|
// _transformToBatch = getNodeToParentTransform();
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// CCASSERT( dynamic_cast<NewSprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite");
|
|
|
|
// _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast<NewSprite*>(_parent)->_transformToBatch );
|
|
|
|
// }
|
|
|
|
|
|
|
|
//TODO optimize this transformation, should use parent's transformation instead
|
|
|
|
_transformToBatch = getNodeToWorldTransform();
|
|
|
|
|
|
|
|
//
|
|
|
|
// calculate the Quad based on the Affine Matrix
|
|
|
|
//
|
2013-12-10 09:32:51 +08:00
|
|
|
Rect newRect = RectApplyTransform(_rect, _transformToBatch);
|
2013-12-05 09:41:18 +08:00
|
|
|
|
|
|
|
_quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ );
|
|
|
|
_quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMinY()), _vertexZ );
|
|
|
|
_quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMinX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ );
|
|
|
|
_quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(newRect.getMaxX()), RENDER_IN_SUBPIXEL(newRect.getMaxY()), _vertexZ );
|
2013-11-26 08:33:05 +08:00
|
|
|
|
|
|
|
_recursiveDirty = false;
|
|
|
|
setDirty(false);
|
|
|
|
}
|
2013-11-07 08:39:20 +08:00
|
|
|
}
|
|
|
|
|
2013-11-05 01:14:22 +08:00
|
|
|
void NewSprite::draw(void)
|
|
|
|
{
|
2013-12-06 11:04:01 +08:00
|
|
|
kmMat4 mv;
|
|
|
|
kmGLGetMatrix(KM_GL_MODELVIEW, &mv);
|
2013-11-13 03:14:34 +08:00
|
|
|
//TODO implement z order
|
2013-12-03 14:08:47 +08:00
|
|
|
QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand();
|
2013-12-06 11:04:01 +08:00
|
|
|
renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1, mv);
|
2013-11-05 01:14:22 +08:00
|
|
|
|
2013-12-07 06:59:06 +08:00
|
|
|
if(!culling())
|
|
|
|
{
|
|
|
|
renderCommand->releaseToCommandPool();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-18 09:50:17 +08:00
|
|
|
Director::getInstance()->getRenderer()->addCommand(renderCommand);
|
2013-11-05 01:14:22 +08:00
|
|
|
}
|
|
|
|
|
2013-11-27 10:35:12 +08:00
|
|
|
bool NewSprite::culling() const
|
|
|
|
{
|
|
|
|
Frustum* frustum = Director::getInstance()->getFrustum();
|
2013-12-07 06:59:06 +08:00
|
|
|
//TODO optimize this transformation, should use parent's transformation instead
|
2013-12-10 09:32:51 +08:00
|
|
|
kmMat4 worldTM = getNodeToWorldTransform();
|
2013-11-27 10:35:12 +08:00
|
|
|
//generate aabb
|
2013-12-07 06:59:06 +08:00
|
|
|
|
|
|
|
//
|
|
|
|
// calculate the Quad based on the Affine Matrix
|
|
|
|
//
|
2013-12-10 09:32:51 +08:00
|
|
|
Rect newRect = RectApplyTransform(_rect, worldTM);
|
2013-12-07 06:59:06 +08:00
|
|
|
|
|
|
|
kmVec3 point = {newRect.getMinX(), newRect.getMinY(), _vertexZ};
|
2013-11-27 10:35:12 +08:00
|
|
|
|
|
|
|
AABB aabb(point,point);
|
2013-12-07 06:59:06 +08:00
|
|
|
point = {newRect.getMaxX(), newRect.getMinY(), _vertexZ};
|
2013-11-27 10:35:12 +08:00
|
|
|
aabb.expand(point);
|
2013-12-07 06:59:06 +08:00
|
|
|
point = {newRect.getMinX(), newRect.getMaxY(), _vertexZ};
|
2013-11-27 10:35:12 +08:00
|
|
|
aabb.expand(point);
|
2013-12-07 06:59:06 +08:00
|
|
|
point = {newRect.getMaxX(), newRect.getMaxY(), _vertexZ};
|
2013-11-27 10:35:12 +08:00
|
|
|
aabb.expand(point);
|
|
|
|
|
|
|
|
return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-05 01:14:22 +08:00
|
|
|
NS_CC_END
|