mirror of https://github.com/axmolengine/axmol.git
Merge pull request #6281 from ricardoquesada/autoculling_working_ok
Culling working again
This commit is contained in:
commit
582a597d78
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue