Merge pull request #6281 from ricardoquesada/autoculling_working_ok

Culling working again
This commit is contained in:
Ricardo Quesada 2014-04-14 20:37:43 -07:00
commit 582a597d78
7 changed files with 57 additions and 51 deletions

View File

@ -276,7 +276,6 @@ Sprite::Sprite(void)
: _shouldBeHidden(false)
, _texture(nullptr)
, _insideBounds(true)
, _cullingEnabled(false)
{
}
@ -590,7 +589,7 @@ void Sprite::updateTransform(void)
void Sprite::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
// Don't do calculate the culling if the transform was not updated
_insideBounds = transformUpdated ? isInsideBounds() : _insideBounds;
_insideBounds = transformUpdated ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
if(_insideBounds)
{
@ -622,42 +621,6 @@ void Sprite::drawDebugData()
}
#endif //CC_SPRITE_DEBUG_DRAW
void Sprite::setCullingEnabled(bool enabled)
{
_cullingEnabled = enabled;
}
// Culling function from cocos2d-iphone CCSprite.m file
bool Sprite::isInsideBounds() const
{
if(!_cullingEnabled) return true;
// half size of the screen
Size screen_half = Director::getInstance()->getWinSize();
screen_half.width /= 2;
screen_half.height /= 2;
float hcsx = _contentSize.width / 2;
float hcsy = _contentSize.height / 2;
// convert to world coordinates
float x = hcsx * _modelViewTransform.mat[0] + hcsy * _modelViewTransform.mat[4] + _modelViewTransform.mat[12];
float y = hcsx * _modelViewTransform.mat[1] + hcsy * _modelViewTransform.mat[5] + _modelViewTransform.mat[13];
// center of screen is (0,0)
x -= screen_half.width;
y -= screen_half.height;
// convert content size to world coordinates
float wchw = hcsx * std::max(fabsf(_modelViewTransform.mat[0] + _modelViewTransform.mat[4]), fabsf(_modelViewTransform.mat[0] - _modelViewTransform.mat[4]));
float wchh = hcsy * std::max(fabsf(_modelViewTransform.mat[1] + _modelViewTransform.mat[5]), fabsf(_modelViewTransform.mat[1] - _modelViewTransform.mat[5]));
// compare if it in the positive quadrant of the screen
float tmpx = (fabsf(x)-wchw);
float tmpy = (fabsf(y)-wchh);
return (tmpx < screen_half.width && tmpy < screen_half.height);
}
// Node overrides
void Sprite::addChild(Node *child, int zOrder, int tag)
{

View File

@ -426,8 +426,6 @@ public:
virtual void setOpacityModifyRGB(bool modify) override;
virtual bool isOpacityModifyRGB(void) const override;
/// @}
//set culling enabled
void setCullingEnabled(bool enabled);
CC_CONSTRUCTOR_ACCESS:
@ -529,8 +527,6 @@ protected:
virtual void setReorderChildDirtyRecursively(void);
virtual void setDirtyRecursively(bool bValue);
bool isInsideBounds() const;
//
// Data used when the sprite is rendered using a SpriteSheet
//
@ -576,7 +572,6 @@ protected:
bool _flippedY; /// Whether the sprite is flipped vertically or not
bool _insideBounds; /// whether or not the sprite was inside bounds the previous frame
bool _cullingEnabled;
private:
CC_DISALLOW_COPY_AND_ASSIGN(Sprite);
};

View File

@ -23,6 +23,9 @@
****************************************************************************/
#include "renderer/CCRenderer.h"
#include <algorithm>
#include "renderer/CCQuadCommand.h"
#include "renderer/CCBatchCommand.h"
#include "renderer/CCCustomCommand.h"
@ -34,15 +37,19 @@
#include "CCEventDispatcher.h"
#include "CCEventListenerCustom.h"
#include "CCEventType.h"
#include <algorithm>
#include "kazmath/kazmath.h"
NS_CC_BEGIN
// helper
bool compareRenderCommand(RenderCommand* a, RenderCommand* b)
{
return a->getGlobalOrder() < b->getGlobalOrder();
}
// queue
void RenderQueue::push_back(RenderCommand* command)
{
float z = command->getGlobalOrder();
@ -92,12 +99,14 @@ void RenderQueue::clear()
_queuePosZ.clear();
}
//
//
//
static const int DEFAULT_RENDER_QUEUE = 0;
//
// constructors, destructors, init
//
//
#define DEFAULT_RENDER_QUEUE 0
Renderer::Renderer()
:_lastMaterialID(0)
,_numQuads(0)
@ -497,4 +506,36 @@ void Renderer::flush()
_lastMaterialID = 0;
}
// helpers
bool Renderer::checkVisibility(const kmMat4 &transform, const Size &size)
{
// half size of the screen
Size screen_half = Director::getInstance()->getWinSize();
screen_half.width /= 2;
screen_half.height /= 2;
float hSizeX = size.width/2;
float hSizeY = size.height/2;
kmVec4 v4world, v4local;
kmVec4Fill(&v4local, hSizeX, hSizeY, 0, 1);
kmVec4MultiplyMat4(&v4world, &v4local, &transform);
// center of screen is (0,0)
v4world.x -= screen_half.width;
v4world.y -= screen_half.height;
// convert content size to world coordinates
float wshw = std::max(fabsf(hSizeX * transform.mat[0] + hSizeY * transform.mat[4]), fabsf(hSizeX * transform.mat[0] - hSizeY * transform.mat[4]));
float wshh = std::max(fabsf(hSizeX * transform.mat[1] + hSizeY * transform.mat[5]), fabsf(hSizeX * transform.mat[1] - hSizeY * transform.mat[5]));
// compare if it in the positive quadrant of the screen
float tmpx = (fabsf(v4world.x)-wshw);
float tmpy = (fabsf(v4world.y)-wshh);
bool ret = (tmpx < screen_half.width && tmpy < screen_half.height);
return ret;
}
NS_CC_END

View File

@ -114,6 +114,9 @@ public:
inline GroupCommandManager* getGroupCommandManager() const { return _groupCommandManager; };
/** returns whether or not a rectangle is visible or not */
bool checkVisibility(const kmMat4& transform, const Size& size);
protected:
void setupIndices();

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "mat3.h"
#include "mat4.h"
#include "utility.h"

View File

@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "vec4.h"
#include "mat4.h"
#include "neon_matrix_impl.h"
kmVec4* kmVec4Fill(kmVec4* pOut, kmScalar x, kmScalar y, kmScalar z, kmScalar w)
{
@ -137,10 +138,14 @@ kmVec4* kmVec4Div( kmVec4* pOut,const kmVec4* pV1, const kmVec4* pV2 ) {
/// Multiplies a 4D vector by a matrix, the result is stored in pOut, and pOut is returned.
kmVec4* kmVec4MultiplyMat4(kmVec4* pOut, const kmVec4* pV, const struct kmMat4* pM) {
#if defined(__ARM_NEON__) && !defined(__arm64__)
NEON_Matrix4Vector4Mul(&pM->mat[0], (const float*)pV, (float*)pOut);
#else
pOut->x = pV->x * pM->mat[0] + pV->y * pM->mat[4] + pV->z * pM->mat[8] + pV->w * pM->mat[12];
pOut->y = pV->x * pM->mat[1] + pV->y * pM->mat[5] + pV->z * pM->mat[9] + pV->w * pM->mat[13];
pOut->z = pV->x * pM->mat[2] + pV->y * pM->mat[6] + pV->z * pM->mat[10] + pV->w * pM->mat[14];
pOut->w = pV->x * pM->mat[3] + pV->y * pM->mat[7] + pV->z * pM->mat[11] + pV->w * pM->mat[15];
#endif
return pOut;
}

View File

@ -474,9 +474,8 @@ NewCullingTest::NewCullingTest()
{
Size size = Director::getInstance()->getWinSize();
auto sprite = Sprite::create("Images/btn-about-normal-vertical.png");
sprite->setRotation(-85);
sprite->setRotation(5);
sprite->setPosition(Point(size.width/2,size.height/3));
sprite->setCullingEnabled(true);
sprite->setScale(2);
addChild(sprite);
@ -484,7 +483,6 @@ NewCullingTest::NewCullingTest()
sprite2->setRotation(-85);
sprite2->setPosition(Point(size.width/2,size.height * 2/3));
sprite2->setScale(2);
sprite2->setCullingEnabled(false);
addChild(sprite2);
auto listener = EventListenerTouchOneByOne::create();