diff --git a/cocos/editor-support/cocostudio/CCArmature.cpp b/cocos/editor-support/cocostudio/CCArmature.cpp index ac04de1af5..baa56ddfb7 100644 --- a/cocos/editor-support/cocostudio/CCArmature.cpp +++ b/cocos/editor-support/cocostudio/CCArmature.cpp @@ -728,6 +728,16 @@ Bone *Armature::getParentBone() return _parentBone; } +void CCArmature::setColliderFilter(ColliderFilter *filter) +{ + DictElement *element = NULL; + CCDICT_FOREACH(_boneDic, element) + { + Bone *bone = static_cast(element->getObject()); + bone->setColliderFilter(filter); + } +} + #if ENABLE_PHYSICS_BOX2D_DETECT b2Body *Armature::getBody() { diff --git a/cocos/editor-support/cocostudio/CCArmature.h b/cocos/editor-support/cocostudio/CCArmature.h index 15abe96079..bf11841f7e 100644 --- a/cocos/editor-support/cocostudio/CCArmature.h +++ b/cocos/editor-support/cocostudio/CCArmature.h @@ -175,6 +175,8 @@ public: virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture); + virtual void setColliderFilter(ColliderFilter *filter); + #if ENABLE_PHYSICS_BOX2D_DETECT virtual b2Fixture *getShapeList(); #elif ENABLE_PHYSICS_CHIPMUNK_DETECT diff --git a/cocos/editor-support/cocostudio/CCBone.cpp b/cocos/editor-support/cocostudio/CCBone.cpp index 804ea5d65a..3132acec79 100644 --- a/cocos/editor-support/cocostudio/CCBone.cpp +++ b/cocos/editor-support/cocostudio/CCBone.cpp @@ -441,4 +441,31 @@ Array *Bone::getColliderBodyList() } + +void Bone::setColliderFilter(ColliderFilter *filter) +{ + Array *array = _displayManager->getDecorativeDisplayList(); + Object *object = NULL; + CCARRAY_FOREACH(array, object) + { + DecorativeDisplay *decoDisplay = static_cast(object); + if (ColliderDetector *detector = decoDisplay->getColliderDetector()) + { + detector->setColliderFilter(filter); + } + } +} +ColliderFilter *Bone::getColliderFilter() +{ + if (DecorativeDisplay *decoDisplay = _displayManager->getCurrentDecorativeDisplay()) + { + if (ColliderDetector *detector = decoDisplay->getColliderDetector()) + { + return detector->getColliderFilter(); + } + } + return NULL; +} + + } diff --git a/cocos/editor-support/cocostudio/CCBone.h b/cocos/editor-support/cocostudio/CCBone.h index 1a1d3c26d6..6edd3fe8cb 100644 --- a/cocos/editor-support/cocostudio/CCBone.h +++ b/cocos/editor-support/cocostudio/CCBone.h @@ -159,6 +159,8 @@ public: */ virtual cocos2d::Array *getColliderBodyList(); + virtual void setColliderFilter(ColliderFilter *filter); + virtual ColliderFilter *getColliderFilter(); public: /* * The origin state of the Bone. Display's state is effected by _boneData, m_pNode, _tweenData diff --git a/cocos/editor-support/cocostudio/CCColliderDetector.cpp b/cocos/editor-support/cocostudio/CCColliderDetector.cpp index 8857832c99..cceb1a9b72 100644 --- a/cocos/editor-support/cocostudio/CCColliderDetector.cpp +++ b/cocos/editor-support/cocostudio/CCColliderDetector.cpp @@ -37,13 +37,44 @@ using namespace cocos2d; namespace cocostudio { +#if ENABLE_PHYSICS_BOX2D_DETECT +ColliderFilter::ColliderFilter(unsigned short categoryBits, unsigned short maskBits, signed short groupIndex) + : _categoryBits(categoryBits) + , _maskBits(maskBits) + , _groupIndex(groupIndex) +{ +} + +void ColliderFilter::updateShape(b2Fixture *fixture) +{ + b2Filter filter; + filter.categoryBits = _categoryBits; + filter.groupIndex = _groupIndex; + filter.maskBits = _maskBits; + + fixture->SetFilterData(filter); +} + +#elif ENABLE_PHYSICS_CHIPMUNK_DETECT +ColliderFilter::ColliderFilter(cpCollisionType collisionType, cpGroup group) + : _collisionType(collisionType) + , _group(group) +{ +} +void ColliderFilter::updateShape(cpShape *shape) +{ + shape->collision_type = _collisionType; + shape->group = _group; +} +#endif + #if ENABLE_PHYSICS_BOX2D_DETECT ColliderBody::ColliderBody(ContourData *contourData) : _fixture(NULL) - , _filter(NULL) , _contourData(contourData) { CC_SAFE_RETAIN(_contourData); + _filter = new ColliderFilter(); #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX _calculatedVertexList = Array::create(); @@ -57,6 +88,7 @@ ColliderBody::ColliderBody(ContourData *contourData) , _contourData(contourData) { CC_SAFE_RETAIN(_contourData); + _filter = new ColliderFilter(); #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX _calculatedVertexList = Array::create(); @@ -68,14 +100,20 @@ ColliderBody::ColliderBody(ContourData *contourData) ColliderBody::~ColliderBody() { CC_SAFE_RELEASE(_contourData); + CC_SAFE_DELETE(_filter); #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX CC_SAFE_RELEASE(_calculatedVertexList); #endif +} -#if ENABLE_PHYSICS_BOX2D_DETECT - CC_SAFE_DELETE(_filter); -#endif +void ColliderBody::setColliderFilter(ColliderFilter *filter) +{ + *_filter = *filter; +} +ColliderFilter *ColliderBody::getColliderFilter() +{ + return _filter; } @@ -106,6 +144,7 @@ ColliderDetector *ColliderDetector::create(Bone *bone) ColliderDetector::ColliderDetector() : _colliderBodyList(NULL) + , _filter(NULL) , _active(false) { _body = NULL; @@ -115,6 +154,7 @@ ColliderDetector::~ColliderDetector() { _colliderBodyList->removeAllObjects(); CC_SAFE_DELETE(_colliderBodyList); + CC_SAFE_DELETE(_filter); } bool ColliderDetector::init() @@ -123,6 +163,8 @@ bool ColliderDetector::init() CCASSERT(_colliderBodyList, "create _colliderBodyList failed!"); _colliderBodyList->retain(); + _filter = new ColliderFilter(); + return true; } @@ -206,9 +248,6 @@ void ColliderDetector::setActive(bool active) ColliderBody *colliderBody = (ColliderBody *)object; b2Fixture *fixture = colliderBody->getB2Fixture(); - b2Filter *filter = colliderBody->getB2Filter(); - *filter = fixture->GetFilterData(); - _body->DestroyFixture(fixture); colliderBody->setB2Fixture(NULL); } @@ -256,6 +295,34 @@ Array *ColliderDetector::getColliderBodyList() return _colliderBodyList; } +void ColliderDetector::setColliderFilter(ColliderFilter *filter) +{ + *_filter = *filter; + + Object *object = NULL; + CCARRAY_FOREACH(_colliderBodyList, object) + { + ColliderBody *colliderBody = (ColliderBody *)object; + colliderBody->setColliderFilter(filter); + +#if ENABLE_PHYSICS_BOX2D_DETECT + if (colliderBody->getB2Fixture()) + { + colliderBody->getColliderFilter()->updateShape(colliderBody->getB2Fixture()); + } +#elif ENABLE_PHYSICS_CHIPMUNK_DETECT + if (colliderBody->getShape()) + { + colliderBody->getColliderFilter()->updateShape(colliderBody->getShape()); + } +#endif + } +} +ColliderFilter *ColliderDetector::getColliderFilter() +{ + return _filter; +} + Point helpPoint; @@ -378,15 +445,7 @@ void ColliderDetector::setBody(b2Body *pBody) } colliderBody->setB2Fixture(fixture); - if (colliderBody->getB2Filter() == NULL) - { - b2Filter *filter = new b2Filter; - colliderBody->setB2Filter(filter); - } - else - { - fixture->SetFilterData(*colliderBody->getB2Filter()); - } + colliderBody->getColliderFilter()->updateShape(fixture); } } @@ -420,9 +479,14 @@ void ColliderDetector::setBody(cpBody *pBody) shape->sensor = true; shape->data = _bone; - cpSpaceAddShape(_body->space_private, shape); + + if (_active) + { + cpSpaceAddShape(_body->space_private, shape); + } colliderBody->setShape(shape); + colliderBody->getColliderFilter()->updateShape(shape); delete []verts; } diff --git a/cocos/editor-support/cocostudio/CCColliderDetector.h b/cocos/editor-support/cocostudio/CCColliderDetector.h index 9e8b7246c6..e2da724c80 100644 --- a/cocos/editor-support/cocostudio/CCColliderDetector.h +++ b/cocos/editor-support/cocostudio/CCColliderDetector.h @@ -33,24 +33,48 @@ THE SOFTWARE. #endif +#if ENABLE_PHYSICS_CHIPMUNK_DETECT +#include "chipmunk.h" +struct cpBody; +struct cpShape; +#elif ENABLE_PHYSICS_BOX2D_DETECT class b2Body; class b2Fixture; struct b2Filter; - -struct cpBody; -struct cpShape; +#endif namespace cocostudio { class Bone; + +class ColliderFilter +{ +public: + ~ColliderFilter() { } +#if ENABLE_PHYSICS_BOX2D_DETECT +public: + ColliderFilter(unsigned short categoryBits = 0x0001, unsigned short maskBits = 0xFFFF, signed short groupIndex = 0); + void updateShape(b2Fixture *fixture); +protected: + CC_SYNTHESIZE(unsigned short, _categoryBits, CategoryBits); + CC_SYNTHESIZE(unsigned short, _maskBits, MaskBits); + CC_SYNTHESIZE(signed short, _groupIndex, GroupIndex); +#elif ENABLE_PHYSICS_CHIPMUNK_DETECT +public: + ColliderFilter(cpCollisionType collisionType = 0, cpGroup group = 0); + void updateShape(cpShape *shape); +protected: + CC_SYNTHESIZE(cpCollisionType, _collisionType, CollisionType); + CC_SYNTHESIZE(cpGroup, _group, Group); +#endif +}; + class ColliderBody : public cocos2d::Object { public: #if ENABLE_PHYSICS_BOX2D_DETECT CC_SYNTHESIZE(b2Fixture *, _fixture, B2Fixture) - CC_SYNTHESIZE(b2Filter *, _filter, B2Filter) - #elif ENABLE_PHYSICS_CHIPMUNK_DETECT CC_SYNTHESIZE(cpShape *, _shape, Shape) #endif @@ -59,12 +83,13 @@ public: ColliderBody(ContourData *contourData); ~ColliderBody(); - inline ContourData *getContourData() - { - return _contourData; - } + inline ContourData *getContourData() { return _contourData; } + + void setColliderFilter(ColliderFilter *filter); + ColliderFilter *getColliderFilter(); private: ContourData *_contourData; + ColliderFilter *_filter; #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX CC_SYNTHESIZE_READONLY(CCArray *, _calculatedVertexList, CalculatedVertexList); @@ -106,8 +131,12 @@ public: cocos2d::Array *getColliderBodyList(); + virtual void setColliderFilter(ColliderFilter *filter); + virtual ColliderFilter *getColliderFilter(); protected: cocos2d::Array *_colliderBodyList; + ColliderFilter *_filter; + CC_SYNTHESIZE(Bone *, _bone, Bone); #if ENABLE_PHYSICS_BOX2D_DETECT diff --git a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp index 35db4c129b..a6dfd04092 100644 --- a/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp +++ b/samples/Cpp/TestCpp/Classes/ExtensionsTest/CocoStudioArmatureTest/ArmatureScene.cpp @@ -1008,13 +1008,7 @@ void TestColliderDetector::initWorld() cpSpaceAddBody(space, body); armature2->setBody(body); - shape = armature2->getShapeList(); - while(shape) - { - cpShape *next = shape->next_private; - shape->collision_type = eEnemyTag; - shape = next; - } + armature2->setColliderFilter(&ColliderFilter(eEnemyTag)); cpSpaceAddCollisionHandler(space, eEnemyTag, eBulletTag, beginHit, NULL, NULL, endHit, NULL); }