// // CCNewSprite.cpp // cocos2d_libs // // Created by NiTe Luo on 10/31/13. // // #include "CCNewSprite.h" #include "RenderCommand.h" #include "Renderer.h" #include "QuadCommand.h" #include "CCMenuItem.h" #include "Frustum.h" #include "CCDirector.h" NS_CC_BEGIN #if CC_SPRITEBATCHNODE_RENDER_SUBPIXEL #define RENDER_IN_SUBPIXEL #else #define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__)) #endif 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() { } NewSprite::~NewSprite(void) { } bool NewSprite::initWithTexture(Texture2D *texture, const Rect &rect, bool rotated) { bool result = Sprite::initWithTexture(texture, rect, rotated); _recursiveDirty = true; setDirty(true); return result; } void NewSprite::updateQuadVertices() { #ifdef CC_USE_PHYSICS updatePhysicsTransform(); setDirty(true); #endif //TODO optimize the performance cache affineTransformation // recalculate matrix only if it is dirty if(isDirty()) { // if( ! _parent || _parent == (Node*)_batchNode ) // { // _transformToBatch = getNodeToParentTransform(); // } // else // { // CCASSERT( dynamic_cast(_parent), "Logic error in Sprite. Parent must be a Sprite"); // _transformToBatch = AffineTransformConcat( getNodeToParentTransform() , static_cast(_parent)->_transformToBatch ); // } //TODO optimize this transformation, should use parent's transformation instead _transformToBatch = getNodeToWorldTransform(); // // calculate the Quad based on the Affine Matrix // Rect newRect = RectApplyAffineTransform(_rect, _transformToBatch); _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 ); _recursiveDirty = false; setDirty(false); } } void NewSprite::draw(void) { updateQuadVertices(); if(!culling()) { return; } //TODO implement z order QuadCommand* renderCommand = QuadCommand::getCommandPool().generateCommand(); renderCommand->init(0, _vertexZ, _texture->getName(), _shaderProgram, _blendFunc, &_quad, 1); Renderer::getInstance()->addCommand(renderCommand); } bool NewSprite::culling() const { Frustum* frustum = Director::getInstance()->getFrustum(); AffineTransform worldTM = getNodeToWorldTransform(); //generate aabb kmVec3 point = {_quad.bl.vertices.x, _quad.bl.vertices.y, _vertexZ}; AABB aabb(point,point); point = {_quad.br.vertices.x, _quad.br.vertices.y, _vertexZ}; aabb.expand(point); point = {_quad.tl.vertices.x, _quad.tl.vertices.y, _vertexZ}; aabb.expand(point); point = {_quad.tr.vertices.x, _quad.tr.vertices.y, _vertexZ}; aabb.expand(point); return Frustum::IntersectResult::OUTSIDE !=frustum->intersectAABB(aabb); } NS_CC_END