add physics component

This commit is contained in:
minggo 2015-09-08 09:54:01 +08:00
parent 75882e64a0
commit 8326ed6535
34 changed files with 2581 additions and 1875 deletions

View File

@ -1363,6 +1363,14 @@
46C02E0818E91123004B7456 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 46C02E0518E91123004B7456 /* xxhash.c */; };
46C02E0918E91123004B7456 /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C02E0618E91123004B7456 /* xxhash.h */; };
46C02E0A18E91123004B7456 /* xxhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C02E0618E91123004B7456 /* xxhash.h */; };
46EE47511B817EFD00100730 /* CCComponentPhysics2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46EE474D1B817EFD00100730 /* CCComponentPhysics2d.cpp */; };
46EE47521B817EFD00100730 /* CCComponentPhysics2d.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46EE474D1B817EFD00100730 /* CCComponentPhysics2d.cpp */; };
46EE47531B817EFD00100730 /* CCComponentPhysics2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EE474E1B817EFD00100730 /* CCComponentPhysics2d.h */; };
46EE47541B817EFD00100730 /* CCComponentPhysics2d.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EE474E1B817EFD00100730 /* CCComponentPhysics2d.h */; };
46EE47551B817EFD00100730 /* CCPhysicsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46EE474F1B817EFD00100730 /* CCPhysicsManager.cpp */; };
46EE47561B817EFD00100730 /* CCPhysicsManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46EE474F1B817EFD00100730 /* CCPhysicsManager.cpp */; };
46EE47571B817EFD00100730 /* CCPhysicsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EE47501B817EFD00100730 /* CCPhysicsManager.h */; };
46EE47581B817EFD00100730 /* CCPhysicsManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 46EE47501B817EFD00100730 /* CCPhysicsManager.h */; };
4D76BE3A1A4AAF0A00102962 /* CCActionTimelineNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */; };
4D76BE3B1A4AAF0A00102962 /* CCActionTimelineNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */; };
4D76BE3C1A4AAF0A00102962 /* CCActionTimelineNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D76BE391A4AAF0A00102962 /* CCActionTimelineNode.h */; };
@ -4354,6 +4362,10 @@
46A170781807CE7A005B8026 /* CCPhysicsWorld.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CCPhysicsWorld.h; sourceTree = "<group>"; };
46C02E0518E91123004B7456 /* xxhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xxhash.c; sourceTree = "<group>"; };
46C02E0618E91123004B7456 /* xxhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xxhash.h; sourceTree = "<group>"; };
46EE474D1B817EFD00100730 /* CCComponentPhysics2d.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCComponentPhysics2d.cpp; sourceTree = "<group>"; };
46EE474E1B817EFD00100730 /* CCComponentPhysics2d.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCComponentPhysics2d.h; sourceTree = "<group>"; };
46EE474F1B817EFD00100730 /* CCPhysicsManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPhysicsManager.cpp; sourceTree = "<group>"; };
46EE47501B817EFD00100730 /* CCPhysicsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPhysicsManager.h; sourceTree = "<group>"; };
4D76BE381A4AAF0A00102962 /* CCActionTimelineNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCActionTimelineNode.cpp; sourceTree = "<group>"; };
4D76BE391A4AAF0A00102962 /* CCActionTimelineNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCActionTimelineNode.h; sourceTree = "<group>"; };
5012168C1AC47380009A4BEA /* CCRenderState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCRenderState.cpp; sourceTree = "<group>"; };
@ -7368,6 +7380,10 @@
46A170611807CE7A005B8026 /* physics */ = {
isa = PBXGroup;
children = (
46EE474D1B817EFD00100730 /* CCComponentPhysics2d.cpp */,
46EE474E1B817EFD00100730 /* CCComponentPhysics2d.h */,
46EE474F1B817EFD00100730 /* CCPhysicsManager.cpp */,
46EE47501B817EFD00100730 /* CCPhysicsManager.h */,
ED74D7681A5B8A2600157FD4 /* CCPhysicsHelper.h */,
46A1706E1807CE7A005B8026 /* CCPhysicsBody.cpp */,
46A1706F1807CE7A005B8026 /* CCPhysicsBody.h */,
@ -9662,6 +9678,7 @@
B6CAB3351AF9AA1A00B9B856 /* btGImpactShape.h in Headers */,
15AE1A6F19AAD40300C27E9E /* b2CircleContact.h in Headers */,
B6CAB3431AF9AA1A00B9B856 /* gim_box_collision.h in Headers */,
46EE47531B817EFD00100730 /* CCComponentPhysics2d.h in Headers */,
B6CAB39B1AF9AA1A00B9B856 /* btVoronoiSimplexSolver.h in Headers */,
B6CAB1EB1AF9AA1A00B9B856 /* btBroadphaseInterface.h in Headers */,
B665E3E81AA80A6600DDB1C5 /* CCPUSineForceAffectorTranslator.h in Headers */,
@ -9733,6 +9750,7 @@
5034CA35191D591100CE6051 /* ccShader_PositionTexture.frag in Headers */,
15AE1BB219AADFEF00C27E9E /* HttpClient.h in Headers */,
B6CAB3FD1AF9AA1A00B9B856 /* btMultiBodyConstraint.h in Headers */,
46EE47571B817EFD00100730 /* CCPhysicsManager.h in Headers */,
B6DD2FF31B04825B00E47F5F /* DetourTileCacheBuilder.h in Headers */,
15AE197619AAD35700C27E9E /* CCTimelineMacro.h in Headers */,
50ABBE6F1925AB6F00A911A9 /* CCEventListenerKeyboard.h in Headers */,
@ -10179,6 +10197,7 @@
1A570084180BC5A10088DEC7 /* CCActionManager.h in Headers */,
B665E3151AA80A6500DDB1C5 /* CCPUObserverManager.h in Headers */,
15AE18C619AAD33D00C27E9E /* CCLayerLoader.h in Headers */,
46EE47541B817EFD00100730 /* CCComponentPhysics2d.h in Headers */,
B6CAB4A41AF9AA1A00B9B856 /* PpuAddressSpace.h in Headers */,
B6CAB2041AF9AA1A00B9B856 /* btMultiSapBroadphase.h in Headers */,
B665E2C51AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h in Headers */,
@ -10952,6 +10971,7 @@
B6CAB3E01AF9AA1A00B9B856 /* btTypedConstraint.h in Headers */,
50ABBDAA1925AB4100A911A9 /* CCRenderCommand.h in Headers */,
B29A7DF019EE1B7700872B35 /* SkeletonBounds.h in Headers */,
46EE47581B817EFD00100730 /* CCPhysicsManager.h in Headers */,
B6CAB3361AF9AA1A00B9B856 /* btGImpactShape.h in Headers */,
15AE1BE919AAE01E00C27E9E /* CCControl.h in Headers */,
15AE193719AAD35100C27E9E /* CCArmature.h in Headers */,
@ -11292,6 +11312,7 @@
38B8E2E119E671D2002D7CE7 /* UILayoutComponent.cpp in Sources */,
B665E3F61AA80A6600DDB1C5 /* CCPUSlaveEmitterTranslator.cpp in Sources */,
1A57019D180BCB590088DEC7 /* CCFont.cpp in Sources */,
46EE47551B817EFD00100730 /* CCPhysicsManager.cpp in Sources */,
B6CAB2D51AF9AA1A00B9B856 /* btOptimizedBvh.cpp in Sources */,
50CB247B19D9C5A100687767 /* AudioEngine-inl.mm in Sources */,
1A5701A1180BCB590088DEC7 /* CCFontAtlas.cpp in Sources */,
@ -11514,6 +11535,7 @@
B6CAB3631AF9AA1A00B9B856 /* btContinuousConvexCollision.cpp in Sources */,
B665E3021AA80A6500DDB1C5 /* CCPUMeshSurfaceEmitter.cpp in Sources */,
B665E3721AA80A6500DDB1C5 /* CCPUParticleFollower.cpp in Sources */,
46EE47511B817EFD00100730 /* CCComponentPhysics2d.cpp in Sources */,
B6CAB22B1AF9AA1A00B9B856 /* btCollisionObject.cpp in Sources */,
1A5702C8180BCE370088DEC7 /* CCTextFieldTTF.cpp in Sources */,
B665E2861AA80A6500DDB1C5 /* CCPUDoStopSystemEventHandlerTranslator.cpp in Sources */,
@ -11977,6 +11999,7 @@
1A57006E180BC5A10088DEC7 /* CCActionEase.cpp in Sources */,
50ABBD8C1925AB4100A911A9 /* CCGLProgram.cpp in Sources */,
B665E2671AA80A6500DDB1C5 /* CCPUDoExpireEventHandlerTranslator.cpp in Sources */,
46EE47561B817EFD00100730 /* CCPhysicsManager.cpp in Sources */,
B6CAB4AA1AF9AA1A00B9B856 /* SpuCollisionObjectWrapper.cpp in Sources */,
B6CAAFFF1AF9A9E100B9B856 /* CCPhysicsSprite3D.cpp in Sources */,
15AE196119AAD35100C27E9E /* CCSSceneReader.cpp in Sources */,
@ -12159,6 +12182,7 @@
B6CAB2201AF9AA1A00B9B856 /* btBoxBoxDetector.cpp in Sources */,
5E9F612B1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */,
1A57019E180BCB590088DEC7 /* CCFont.cpp in Sources */,
46EE47521B817EFD00100730 /* CCComponentPhysics2d.cpp in Sources */,
15AE1ACC19AAD40300C27E9E /* b2PrismaticJoint.cpp in Sources */,
15AE195F19AAD35100C27E9E /* CCSpriteFrameCacheHelper.cpp in Sources */,
15AE193019AAD35100C27E9E /* CCActionManagerEx.cpp in Sources */,

View File

@ -49,6 +49,22 @@ public:
* @lua NA
*/
virtual ~ComponentContainer(void);
template<typename T>
T* getComponent() const
{
if (_components)
{
for (const auto &iter : *_components)
{
if (dynamic_cast<T*>(iter.second) != nullptr)
return static_cast<T*>(iter.second);
}
}
return nullptr;
}
/**
* @js getComponent
*/

View File

@ -44,10 +44,6 @@ THE SOFTWARE.
#include "deprecated/CCString.h"
#if CC_USE_PHYSICS
#include "physics/CCPhysicsBody.h"
#endif
NS_CC_BEGIN
// Layer

View File

@ -41,19 +41,12 @@ THE SOFTWARE.
#include "2d/CCActionManager.h"
#include "2d/CCScene.h"
#include "2d/CCComponent.h"
#include "2d/CCComponentContainer.h"
#include "renderer/CCGLProgram.h"
#include "renderer/CCGLProgramState.h"
#include "renderer/CCMaterial.h"
#include "math/TransformUtils.h"
#include "deprecated/CCString.h"
#if CC_USE_PHYSICS
#include "physics/CCPhysicsBody.h"
#include "physics/CCPhysicsWorld.h"
#endif
#if CC_NODE_RENDER_SUBPIXEL
#define RENDER_IN_SUBPIXEL
@ -118,17 +111,6 @@ Node::Node(void)
, _updateScriptHandler(0)
#endif
, _componentContainer(nullptr)
#if CC_USE_PHYSICS
, _physicsBody(nullptr)
, _physicsScaleStartX(1.0f)
, _physicsScaleStartY(1.0f)
, _physicsRotation(0.0f)
, _physicsTransformDirty(true)
, _updateTransformFromPhysics(true)
, _physicsWorld(nullptr)
, _physicsBodyAssociatedWith(0)
, _physicsRotationOffset(0.0f)
#endif
, _displayedOpacity(255)
, _realOpacity(255)
, _displayedColor(Color3B::WHITE)
@ -194,11 +176,6 @@ Node::~Node()
CC_SAFE_DELETE(_componentContainer);
#if CC_USE_PHYSICS
setPhysicsBody(nullptr);
#endif
stopAllActions();
unscheduleAllCallbacks();
CC_SAFE_RELEASE_NULL(_actionManager);
@ -259,13 +236,6 @@ void Node::setSkewX(float skewX)
if (_skewX == skewX)
return;
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setSkewX");
}
#endif
_skewX = skewX;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -280,13 +250,6 @@ void Node::setSkewY(float skewY)
if (_skewY == skewY)
return;
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setSkewY");
}
#endif
_skewY = skewY;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -336,12 +299,6 @@ void Node::setRotation(float rotation)
_rotationZ_X = _rotationZ_Y = rotation;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
updateRotationQuat();
}
@ -367,13 +324,6 @@ void Node::setRotation3D(const Vec3& rotation)
_rotationZ_Y = _rotationZ_X = rotation.z;
updateRotationQuat();
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setRotation3D");
}
#endif
}
Vec3 Node::getRotation3D() const
@ -429,13 +379,6 @@ void Node::setRotationSkewX(float rotationX)
if (_rotationZ_X == rotationX)
return;
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setRotationSkewX");
}
#endif
_rotationZ_X = rotationX;
_transformUpdated = _transformDirty = _inverseDirty = true;
@ -452,13 +395,6 @@ void Node::setRotationSkewY(float rotationY)
if (_rotationZ_Y == rotationY)
return;
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setRotationSkewY");
}
#endif
_rotationZ_Y = rotationY;
_transformUpdated = _transformDirty = _inverseDirty = true;
@ -480,12 +416,6 @@ void Node::setScale(float scale)
_scaleX = _scaleY = _scaleZ = scale;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
/// scaleX getter
@ -503,12 +433,6 @@ void Node::setScale(float scaleX,float scaleY)
_scaleX = scaleX;
_scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
/// scaleX setter
@ -519,12 +443,6 @@ void Node::setScaleX(float scaleX)
_scaleX = scaleX;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
/// scaleY getter
@ -539,13 +457,6 @@ void Node::setScaleZ(float scaleZ)
if (_scaleZ == scaleZ)
return;
#if CC_USE_PHYSICS
if (_physicsBody != nullptr)
{
CCLOG("Node WARNING: PhysicsBody doesn't support setScaleZ");
}
#endif
_scaleZ = scaleZ;
_transformUpdated = _transformDirty = _inverseDirty = true;
}
@ -564,12 +475,6 @@ void Node::setScaleY(float scaleY)
_scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
@ -601,12 +506,6 @@ void Node::setPosition(float x, float y)
_transformUpdated = _transformDirty = _inverseDirty = true;
_usingNormalizedPosition = false;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
void Node::setPosition3D(const Vec3& position)
@ -671,12 +570,6 @@ void Node::setNormalizedPosition(const Vec2& position)
_usingNormalizedPosition = true;
_normalizedPositionDirty = true;
_transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsBodyAssociatedWith > 0)
{
_physicsWorld->_updateBodyTransform = true;
}
#endif
}
ssize_t Node::getChildrenCount() const
@ -1059,24 +952,6 @@ void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::stri
child->setParent(this);
child->setOrderOfArrival(s_globalOrderOfArrival++);
#if CC_USE_PHYSICS
_physicsBodyAssociatedWith += child->_physicsBodyAssociatedWith;
auto parentNode = this;
while (parentNode->_parent)
{
parentNode = parentNode->_parent;
parentNode->_physicsBodyAssociatedWith += child->_physicsBodyAssociatedWith;
}
auto scene = dynamic_cast<Scene*>(parentNode);
// Recursive add children with which have physics body.
if (scene && scene->getPhysicsWorld())
{
scene->addChildToPhysicsWorld(child);
}
#endif
if( _running )
{
child->onEnter();
@ -1177,21 +1052,6 @@ void Node::removeAllChildren()
this->removeAllChildrenWithCleanup(true);
}
#if CC_USE_PHYSICS
void Node::removeFromPhysicsWorld()
{
if (_physicsBody != nullptr)
{
_physicsBody->removeFromWorld();
}
for (auto child : _children)
{
child->removeFromPhysicsWorld();
}
}
#endif
void Node::removeAllChildrenWithCleanup(bool cleanup)
{
// not using detachChild improves speed here
@ -1206,10 +1066,6 @@ void Node::removeAllChildrenWithCleanup(bool cleanup)
child->onExit();
}
#if CC_USE_PHYSICS
child->removeFromPhysicsWorld();
#endif
if (cleanup)
{
child->cleanup();
@ -1231,10 +1087,6 @@ void Node::detachChild(Node *child, ssize_t childIndex, bool doCleanup)
child->onExitTransitionDidStart();
child->onExit();
}
#if CC_USE_PHYSICS
child->removeFromPhysicsWorld();
#endif
// If you don't do cleanup, the child's actions will not get removed and the
// its scheduledSelectors_ dict will not get released!
@ -1297,12 +1149,6 @@ void Node::visit()
uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags)
{
#if CC_USE_PHYSICS
if (_physicsBody && _updateTransformFromPhysics)
{
updateTransformFromPhysics(parentTransform, parentFlags);
}
#endif
if(_usingNormalizedPosition)
{
CCASSERT(_parent, "setNormalizedPosition() doesn't work with orphan nodes");
@ -1330,15 +1176,8 @@ uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFl
if(flags & FLAGS_DIRTY_MASK)
_modelViewTransform = this->transform(parentTransform);
#if CC_USE_PHYSICS
if (_updateTransformFromPhysics) {
_transformUpdated = false;
_contentSizeDirty = false;
}
#else
_transformUpdated = false;
_contentSizeDirty = false;
#endif
return flags;
}
@ -2065,120 +1904,6 @@ void Node::removeAllComponents()
_componentContainer->removeAll();
}
#if CC_USE_PHYSICS
// MARK: Physics
void Node::setPhysicsBody(PhysicsBody* body)
{
if (_physicsBody == body)
{
return;
}
if (_physicsBody)
{
_physicsBody->removeFromWorld();
_physicsBody->_node = nullptr;
_physicsBody->release();
_physicsBody = nullptr;
_physicsBodyAssociatedWith--;
auto parentNode = this;
while (parentNode->_parent)
{
parentNode = parentNode->_parent;
parentNode->_physicsBodyAssociatedWith--;
}
}
if (body)
{
if (body->getNode())
{
body->getNode()->setPhysicsBody(nullptr);
}
body->_node = this;
body->retain();
_physicsBody = body;
_physicsScaleStartX = _scaleX;
_physicsScaleStartY = _scaleY;
_physicsRotationOffset = _rotationZ_X;
_physicsBodyAssociatedWith++;
auto parentNode = this;
while (parentNode->_parent)
{
parentNode = parentNode->_parent;
parentNode->_physicsBodyAssociatedWith++;
}
auto scene = dynamic_cast<Scene*>(parentNode);
if (scene && scene->getPhysicsWorld())
{
_physicsTransformDirty = true;
scene->getPhysicsWorld()->addBody(body);
}
}
}
void Node::updatePhysicsBodyTransform(const Mat4& parentTransform, uint32_t parentFlags, float parentScaleX, float parentScaleY)
{
_updateTransformFromPhysics = false;
auto flags = processParentFlags(parentTransform, parentFlags);
_updateTransformFromPhysics = true;
auto scaleX = parentScaleX * _scaleX;
auto scaleY = parentScaleY * _scaleY;
if (_parent)
{
_physicsRotation = _parent->_physicsRotation + _rotationZ_X;
}
if (_physicsBody && ((flags & FLAGS_DIRTY_MASK) || _physicsTransformDirty))
{
_physicsTransformDirty = false;
Vec3 vec3(_contentSize.width * 0.5f, _contentSize.height * 0.5f, 0);
Vec3 ret;
_modelViewTransform.transformPoint(vec3, &ret);
_physicsBody->setPosition(Vec2(ret.x, ret.y));
parentTransform.getInversed().transformPoint(&ret);
_offsetX = ret.x - _position.x;
_offsetY = ret.y - _position.y;
_physicsBody->setScale(scaleX / _physicsScaleStartX, scaleY / _physicsScaleStartY);
_physicsBody->setRotation(_physicsRotation - _physicsRotationOffset);
}
for (auto node : _children)
{
node->updatePhysicsBodyTransform(_modelViewTransform, flags, scaleX, scaleY);
}
}
void Node::updateTransformFromPhysics(const Mat4& parentTransform, uint32_t parentFlags)
{
auto& newPosition = _physicsBody->getPosition();
auto& recordedPosition = _physicsBody->_recordedPosition;
auto updateBodyTransform = _physicsWorld->_updateBodyTransform;
if (parentFlags || recordedPosition.x != newPosition.x || recordedPosition.y != newPosition.y)
{
recordedPosition = newPosition;
Vec3 vec3(newPosition.x, newPosition.y, 0);
Vec3 ret;
parentTransform.getInversed().transformPoint(vec3, &ret);
setPosition(ret.x - _offsetX, ret.y - _offsetY);
}
_physicsRotation = _physicsBody->getRotation();
setRotation(_physicsRotation - _parent->_physicsRotation + _physicsRotationOffset);
_physicsWorld->_updateBodyTransform = updateBodyTransform;
}
#endif //CC_USE_PHYSICS
// MARK: Opacity and Color
GLubyte Node::getOpacity(void) const

View File

@ -35,6 +35,7 @@
#include "base/CCScriptSupport.h"
#include "math/CCAffineTransform.h"
#include "math/CCMath.h"
#include "2d/CCComponentContainer.h"
NS_CC_BEGIN
@ -53,10 +54,6 @@ class Director;
class GLProgram;
class GLProgramState;
class Material;
#if CC_USE_PHYSICS
class PhysicsBody;
class PhysicsWorld;
#endif
class Camera;
/**
@ -1560,7 +1557,6 @@ public:
virtual Mat4 getWorldToNodeTransform() const;
virtual AffineTransform getWorldToNodeAffineTransform() const;
/** @deprecated Use getWorldToNodeTransform() instead */
CC_DEPRECATED_ATTRIBUTE inline virtual AffineTransform worldToNodeTransform() const { return getWorldToNodeAffineTransform(); }
@ -1644,6 +1640,22 @@ public:
* @return The Component by name.
*/
Component* getComponent(const std::string& name);
/**
* Get a component by the type T.
* @lua NA
* @js NA
*
* @return The component that match the type T.
*/
template<typename T>
T* getComponent() const
{
if (_componentContainer)
return _componentContainer->getComponent<T>();
else
return nullptr;
}
/**
* Adds a component.
@ -1673,39 +1685,6 @@ public:
*/
virtual void removeAllComponents();
/// @} end of component functions
#if CC_USE_PHYSICS
/**
* Set the PhysicsBody that let the sprite effect with physics.
* @note This method will set anchor point to Vec2::ANCHOR_MIDDLE if body not null, and you cann't change anchor point if node has a physics body.
*
* @param body A given physics body.
*/
void setPhysicsBody(PhysicsBody* body);
/**
* Get the PhysicsBody the sprite have.
*
* @return The PhysicsBody the sprite have.
*/
PhysicsBody* getPhysicsBody() const { return _physicsBody; }
/**
* Remove this node from physics world. it will remove all the physics bodies in it's children too.
*/
void removeFromPhysicsWorld();
/**
* Update the transform matrix from physics.
*/
void updateTransformFromPhysics(const Mat4& parentTransform, uint32_t parentFlags);
/**
* Update physics body transform matrix.
*/
virtual void updatePhysicsBodyTransform(const Mat4& parentTransform, uint32_t parentFlags, float parentScaleX, float parentScaleY);
#endif
// overrides
virtual GLubyte getOpacity() const;
@ -1863,22 +1842,6 @@ protected:
#endif
ComponentContainer *_componentContainer; ///< Dictionary of components
#if CC_USE_PHYSICS
PhysicsBody* _physicsBody; ///< the physicsBody the node have
float _physicsScaleStartX; ///< the scale x value when setPhysicsBody
float _physicsScaleStartY; ///< the scale y value when setPhysicsBody
float _physicsRotation;
bool _physicsTransformDirty;
bool _updateTransformFromPhysics;
PhysicsWorld* _physicsWorld; /** The PhysicsWorld associated with the node.*/
int _physicsBodyAssociatedWith; /** The count of PhysicsBody associated with the node and children.*/
float _physicsRotationOffset; /** Record the rotation value when invoke Node::setPhysicsBody.*/
float _offsetX;
float _offsetY;
#endif
// opacity controls
GLubyte _displayedOpacity;
@ -1900,10 +1863,6 @@ protected:
private:
CC_DISALLOW_COPY_AND_ASSIGN(Node);
#if CC_USE_PHYSICS
friend class Scene;
#endif //CC_USTPS
};

View File

@ -29,10 +29,6 @@
#include "CCProtectedNode.h"
#include "base/CCDirector.h"
#if CC_USE_PHYSICS
#include "physics/CCPhysicsBody.h"
#endif
#include "2d/CCScene.h"
NS_CC_BEGIN
@ -108,19 +104,6 @@ void ProtectedNode::addProtectedChild(Node *child, int zOrder, int tag)
child->setParent(this);
child->setOrderOfArrival(s_globalOrderOfArrival++);
#if CC_USE_PHYSICS
// Recursive add children with which have physics body.
for (Node* node = this; node != nullptr; node = node->getParent())
{
Scene* scene = dynamic_cast<Scene*>(node);
if (scene != nullptr && scene->getPhysicsWorld() != nullptr)
{
scene->addChildToPhysicsWorld(child);
break;
}
}
#endif
if( _running )
{
child->onEnter();
@ -178,13 +161,6 @@ void ProtectedNode::removeProtectedChild(cocos2d::Node *child, bool cleanup)
child->onExit();
}
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->removeFromWorld();
}
#endif
// If you don't do cleanup, the child's actions will not get removed and the
// its scheduledSelectors_ dict will not get released!
if (cleanup)
@ -218,13 +194,6 @@ void ProtectedNode::removeAllProtectedChildrenWithCleanup(bool cleanup)
child->onExit();
}
#if CC_USE_PHYSICS
if (child->getPhysicsBody() != nullptr)
{
child->getPhysicsBody()->removeFromWorld();
}
#endif
if (cleanup)
{
child->cleanup();

View File

@ -35,7 +35,7 @@ THE SOFTWARE.
#include "deprecated/CCString.h"
#if CC_USE_PHYSICS
#include "physics/CCPhysicsWorld.h"
#include "physics/CCPhysicsManager.h"
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
@ -50,9 +50,6 @@ THE SOFTWARE.
NS_CC_BEGIN
Scene::Scene()
#if CC_USE_PHYSICS
: _physicsWorld(nullptr)
#endif
{
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
_physics3DWorld = nullptr;
@ -61,6 +58,9 @@ Scene::Scene()
#if CC_USE_NAVMESH
_navMesh = nullptr;
_navMeshDebugCamera = nullptr;
#endif
#if CC_USE_PHYSICS
_physicsManager = nullptr;
#endif
_ignoreAnchorPointForPosition = true;
setAnchorPoint(Vec2(0.5f, 0.5f));
@ -79,9 +79,6 @@ Scene::Scene()
Scene::~Scene()
{
#if CC_USE_PHYSICS
CC_SAFE_DELETE(_physicsWorld);
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
CC_SAFE_RELEASE(_physics3DWorld);
CC_SAFE_RELEASE(_physics3dDebugCamera);
@ -91,6 +88,10 @@ Scene::~Scene()
#endif
Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
CC_SAFE_RELEASE(_event);
#if CC_USE_PHYSICS
delete _physicsManager;
#endif
}
#if CC_USE_NAVMESH
@ -260,21 +261,6 @@ void Scene::setNavMeshDebugCamera(Camera *camera)
#endif
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION))
void Scene::addChild(Node* child, int zOrder, int tag)
{
Node::addChild(child, zOrder, tag);
#if CC_USE_PHYSICS
addChildToPhysicsWorld(child);
#endif
}
void Scene::addChild(Node* child, int zOrder, const std::string &name)
{
Node::addChild(child, zOrder, name);
#if CC_USE_PHYSICS
addChildToPhysicsWorld(child);
#endif
}
Scene* Scene::createWithPhysics()
{
@ -293,6 +279,9 @@ Scene* Scene::createWithPhysics()
bool Scene::initWithPhysics()
{
_physicsManager = new (std::nothrow) PhysicsManager(this);
_physicsWorld = _physicsManager->getPhysicsWorld();
bool ret = false;
do
{
@ -300,9 +289,6 @@ bool Scene::initWithPhysics()
CC_BREAK_IF( ! (director = Director::getInstance()) );
this->setContentSize(director->getWinSize());
#if CC_USE_PHYSICS
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
Physics3DWorldDes info;
@ -316,43 +302,16 @@ bool Scene::initWithPhysics()
return ret;
}
void Scene::addChildToPhysicsWorld(Node* child)
{
#if CC_USE_PHYSICS
if (_physicsWorld)
{
std::function<void(Node*)> addToPhysicsWorldFunc = nullptr;
addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Node* node) -> void
{
node->_physicsWorld = _physicsWorld;
if (node->getPhysicsBody())
{
_physicsWorld->addBody(node->getPhysicsBody());
}
auto& children = node->getChildren();
for( const auto &n : children) {
addToPhysicsWorldFunc(n);
}
};
addToPhysicsWorldFunc(child);
}
#endif
}
#endif
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
void Scene::stepPhysicsAndNavigation(float deltaTime)
{
#if CC_USE_PHYSICS
if (_physicsWorld && _physicsWorld->isAutoStep())
{
_physicsWorld->update(deltaTime, false);
}
if (_physicsManager)
_physicsManager->update(deltaTime);
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
if (_physics3DWorld)
{

View File

@ -40,6 +40,7 @@ class EventListenerCustom;
class EventCustom;
#if CC_USE_PHYSICS
class PhysicsWorld;
class PhysicsManager;
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
class Physics3DWorld;
@ -145,15 +146,21 @@ private:
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION))
public:
virtual void addChild(Node* child, int zOrder, int tag) override;
virtual void addChild(Node* child, int zOrder, const std::string &name) override;
#if CC_USE_PHYSICS
/** Get the physics world of the scene.
* @return The physics world of the scene.
* @js NA
*/
inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; }
inline PhysicsWorld* getPhysicsWorld() const { return _physicsWorld; }
/**
* Get the `PhysicsManager` belongs to this `Scene`.
*
* @return PhysicsManager of the scene.
* @js NA
*/
PhysicsManager* getPhysicsManager() const { return _physicsManager; }
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
@ -183,6 +190,7 @@ protected:
#if CC_USE_PHYSICS
PhysicsWorld* _physicsWorld;
PhysicsManager* _physicsManager;
#endif
#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION
@ -203,8 +211,8 @@ public:
void setNavMeshDebugCamera(Camera *camera);
protected:
NavMesh* _navMesh;
Camera * _navMeshDebugCamera;
NavMesh* _navMesh;
Camera * _navMeshDebugCamera;
#endif
#if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)

View File

@ -367,13 +367,6 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
for (const auto &child : _children)
{
#if CC_USE_PHYSICS
auto physicsBody = child->getPhysicsBody();
if (physicsBody)
{
child->updateTransformFromPhysics(transform, flags);
}
#endif
child->updateTransform();
}

View File

@ -587,9 +587,11 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClCompile Include="..\physics3d\CCPhysics3DShape.cpp" />
<ClCompile Include="..\physics3d\CCPhysics3DWorld.cpp" />
<ClCompile Include="..\physics3d\CCPhysicsSprite3D.cpp" />
<ClCompile Include="..\physics\CCComponentPhysics2d.cpp" />
<ClCompile Include="..\physics\CCPhysicsBody.cpp" />
<ClCompile Include="..\physics\CCPhysicsContact.cpp" />
<ClCompile Include="..\physics\CCPhysicsJoint.cpp" />
<ClCompile Include="..\physics\CCPhysicsManager.cpp" />
<ClCompile Include="..\physics\CCPhysicsShape.cpp" />
<ClCompile Include="..\physics\CCPhysicsWorld.cpp" />
<ClCompile Include="..\platform\CCFileUtils.cpp" />
@ -1195,10 +1197,12 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClInclude Include="..\physics3d\CCPhysics3DShape.h" />
<ClInclude Include="..\physics3d\CCPhysics3DWorld.h" />
<ClInclude Include="..\physics3d\CCPhysicsSprite3D.h" />
<ClInclude Include="..\physics\CCComponentPhysics2d.h" />
<ClInclude Include="..\physics\CCPhysicsBody.h" />
<ClInclude Include="..\physics\CCPhysicsContact.h" />
<ClInclude Include="..\physics\CCPhysicsHelper.h" />
<ClInclude Include="..\physics\CCPhysicsJoint.h" />
<ClInclude Include="..\physics\CCPhysicsManager.h" />
<ClInclude Include="..\physics\CCPhysicsShape.h" />
<ClInclude Include="..\physics\CCPhysicsWorld.h" />
<ClInclude Include="..\platform\CCApplicationProtocol.h" />

View File

@ -285,6 +285,9 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\physics\CCComponentPhysics2d.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\physics\CCPhysicsBody.cpp">
<Filter>physics</Filter>
</ClCompile>
@ -294,6 +297,9 @@
<ClCompile Include="..\physics\CCPhysicsJoint.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\physics\CCPhysicsManager.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\physics\CCPhysicsShape.cpp">
<Filter>physics</Filter>
</ClCompile>
@ -1936,6 +1942,9 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\physics\CCComponentPhysics2d.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\physics\CCPhysicsBody.h">
<Filter>physics</Filter>
</ClInclude>
@ -1945,6 +1954,9 @@
<ClInclude Include="..\physics\CCPhysicsJoint.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\physics\CCPhysicsManager.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\physics\CCPhysicsShape.h">
<Filter>physics</Filter>
</ClInclude>

View File

@ -468,10 +468,12 @@
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCComponentPhysics2d.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsBody.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsContact.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsHelper.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsJoint.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsManager.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsShape.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsWorld.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\platform\CCApplication.h" />
@ -1071,9 +1073,11 @@
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DShape.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysics3DWorld.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics3d\CCPhysicsSprite3D.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCComponentPhysics2d.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsBody.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsContact.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsJoint.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsManager.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsShape.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsWorld.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\platform\CCFileUtils.cpp" />

View File

@ -210,6 +210,12 @@
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsWorld.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCComponentPhysics2d.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsManager.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\editor-support\cocostudio\CocosStudioExport.h">
<Filter>cocostudio</Filter>
</ClInclude>
@ -2054,6 +2060,12 @@
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsWorld.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCComponentPhysics2d.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\physics\CCPhysicsManager.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\editor-support\cocostudio\CCActionFrame.cpp">
<Filter>cocostudio\action</Filter>
</ClCompile>

View File

@ -565,9 +565,11 @@
<ClCompile Include="..\..\physics3d\CCPhysics3DShape.cpp" />
<ClCompile Include="..\..\physics3d\CCPhysics3DWorld.cpp" />
<ClCompile Include="..\..\physics3d\CCPhysicsSprite3D.cpp" />
<ClCompile Include="..\..\physics\CCComponentPhysics2d.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsBody.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsContact.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsJoint.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsManager.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsShape.cpp" />
<ClCompile Include="..\..\physics\CCPhysicsWorld.cpp" />
<ClCompile Include="..\..\platform\CCFileUtils.cpp" />
@ -1179,10 +1181,12 @@
<ClInclude Include="..\..\physics3d\CCPhysics3DShape.h" />
<ClInclude Include="..\..\physics3d\CCPhysics3DWorld.h" />
<ClInclude Include="..\..\physics3d\CCPhysicsSprite3D.h" />
<ClInclude Include="..\..\physics\CCComponentPhysics2d.h" />
<ClInclude Include="..\..\physics\CCPhysicsBody.h" />
<ClInclude Include="..\..\physics\CCPhysicsContact.h" />
<ClInclude Include="..\..\physics\CCPhysicsHelper.h" />
<ClInclude Include="..\..\physics\CCPhysicsJoint.h" />
<ClInclude Include="..\..\physics\CCPhysicsManager.h" />
<ClInclude Include="..\..\physics\CCPhysicsShape.h" />
<ClInclude Include="..\..\physics\CCPhysicsWorld.h" />
<ClInclude Include="..\..\platform\CCApplication.h" />

View File

@ -1578,6 +1578,9 @@
<ClCompile Include="..\..\network\WebSocket.cpp">
<Filter>network</Filter>
</ClCompile>
<ClCompile Include="..\..\physics\CCComponentPhysics2d.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\..\physics\CCPhysicsBody.cpp">
<Filter>physics</Filter>
</ClCompile>
@ -1587,6 +1590,9 @@
<ClCompile Include="..\..\physics\CCPhysicsJoint.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\..\physics\CCPhysicsManager.cpp">
<Filter>physics</Filter>
</ClCompile>
<ClCompile Include="..\..\physics\CCPhysicsShape.cpp">
<Filter>physics</Filter>
</ClCompile>
@ -3389,6 +3395,9 @@
<ClInclude Include="..\..\network\WebSocket.h">
<Filter>network</Filter>
</ClInclude>
<ClInclude Include="..\..\physics\CCComponentPhysics2d.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\..\physics\CCPhysicsBody.h">
<Filter>physics</Filter>
</ClInclude>
@ -3401,6 +3410,9 @@
<ClInclude Include="..\..\physics\CCPhysicsJoint.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\..\physics\CCPhysicsManager.h">
<Filter>physics</Filter>
</ClInclude>
<ClInclude Include="..\..\physics\CCPhysicsShape.h">
<Filter>physics</Filter>
</ClInclude>

View File

@ -200,6 +200,8 @@ physics/CCPhysicsContact.cpp \
physics/CCPhysicsJoint.cpp \
physics/CCPhysicsShape.cpp \
physics/CCPhysicsWorld.cpp \
physics/CCComponentPhysics2d.cpp \
physics/CCPhysicsManager.cpp \
physics3d/CCPhysics3D.cpp \
physics3d/CCPhysics3DWorld.cpp \
physics3d/CCPhysics3DComponent.cpp \

View File

@ -61,7 +61,6 @@ THE SOFTWARE.
#include "base/CCConfiguration.h"
#include "base/CCAsyncTaskPool.h"
#include "platform/CCApplication.h"
//#include "platform/CCGLViewImpl.h"
#if CC_ENABLE_SCRIPT_BINDING
#include "CCScriptSupport.h"

View File

@ -186,6 +186,8 @@ THE SOFTWARE.
#include "physics/CCPhysicsJoint.h"
#include "physics/CCPhysicsShape.h"
#include "physics/CCPhysicsWorld.h"
#include "physics/CCComponentPhysics2d.h"
#include "physics/CCPhysicsManager.h"
// platform
#include "platform/CCCommon.h"

View File

@ -0,0 +1,263 @@
/****************************************************************************
Copyright (c) 2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h" // to include defination of CC_USE_PHYSICS
#if CC_USE_PHYSICS
#include "physics/CCComponentPhysics2d.h"
#include "physics/CCPhysicsBody.h"
#include "physics/CCPhysicsManager.h"
#include "2d/CCNode.h"
#include "base/CCDirector.h"
NS_CC_BEGIN
const std::string ComponentPhysics2d::COMPONENT_NAME = "physics2d";
ComponentPhysics2d* ComponentPhysics2d::create()
{
return create(nullptr);
}
ComponentPhysics2d* ComponentPhysics2d::create(PhysicsBody *physicsBody)
{
auto ret = new (std::nothrow) ComponentPhysics2d(physicsBody);
if (ret)
ret->autorelease();
return ret;
}
ComponentPhysics2d::ComponentPhysics2d()
: _physicsBody(nullptr)
, _physicsRotation(0.0f)
, _ownerOriginRotation(0.0f)
{
_name = COMPONENT_NAME;
}
ComponentPhysics2d::ComponentPhysics2d(PhysicsBody* physicsBody)
: _physicsRotation(0.0f)
, _ownerOriginRotation(0.0f)
, _physicsBody(nullptr) // should set to null to invoke setPhysicsBody()
{
_name = COMPONENT_NAME;
setPhysicsBody(physicsBody);
}
ComponentPhysics2d::~ComponentPhysics2d()
{
removePhysicsBody();
}
// true if two Vec3 equals, false else
bool ComponentPhysics2d::isVec3Equal(const cocos2d::Vec3 &v1, const cocos2d::Vec3 &v2) const
{
return fabs(v1.x - v2.x) < FLT_EPSILON &&
fabs(v1.x - v2.y) < FLT_EPSILON;
}
void ComponentPhysics2d::beforeSimulation()
{
if (nullptr == _physicsBody)
return;
_nodeToWorldTransform = _owner->getNodeToWorldTransform();
// set scale
_nodeToWorldTransform.getScale(&_scale);
if (! isVec3Equal(_scale, _recordScale))
{
_physicsBody->setScale(_scale.x, _scale.y);
_recordScale = _scale;
}
// set rotation
if (_owner->getParent())
{
_physicsRotation = getPhysicsRotation(_owner->getParent()) + _owner->getRotation();
}
_physicsBody->setRotation(_physicsRotation - _ownerOriginRotation);
// set position
auto worldPosition = _ownerCenterOffset;
_nodeToWorldTransform.transformPoint(&worldPosition);
_physicsBody->setPosition(Vec2(worldPosition.x, worldPosition.y));
getParentToWorldTransform().getInversed().transformPoint(&worldPosition);
_offset.x = worldPosition.x - _owner->getPosition().x;
_offset.y = worldPosition.y - _owner->getPosition().y;
}
void ComponentPhysics2d::afterSimulation()
{
if (nullptr == _physicsBody)
return;
// set Node position
auto worldPosition = _physicsBody->getPosition();
Vec3 positionInParent(worldPosition.x, worldPosition.y, 0);
getParentToWorldTransform().getInversed().transformPoint(&positionInParent);
_owner->setPosition(positionInParent.x - _offset.x, positionInParent.y - _offset.y);
// set Node rotation
_physicsRotation = _physicsBody->getRotation();
_owner->setRotation(_physicsRotation - getPhysicsRotation(_owner->getParent()) + _ownerOriginRotation);
}
void ComponentPhysics2d::setPhysicsBody(PhysicsBody *physicsBody)
{
removeFromPhysicsManager();
if (physicsBody != _physicsBody)
{
if (nullptr != _physicsBody)
{
_physicsBody->release();
_physicsBody->_componentBelongsTo = nullptr;
}
// two components should not share the same physics body
if (physicsBody && physicsBody->_componentBelongsTo != nullptr)
physicsBody->_componentBelongsTo->_physicsBody = nullptr;
_physicsBody = physicsBody;
if (nullptr != _physicsBody)
{
_physicsBody->retain();
_physicsBody->_componentBelongsTo = this;
}
}
addToPhysicsManager();
}
PhysicsBody* ComponentPhysics2d::getPhysicsBody() const
{
return _physicsBody;
}
void ComponentPhysics2d::setEnabled(bool value)
{
Component::setEnabled(value);
if (value)
addToPhysicsManager();
else
removeFromPhysicsManager();
}
void ComponentPhysics2d::onEnter()
{
addToPhysicsManager();
}
void ComponentPhysics2d::onExit()
{
removeFromPhysicsManager();
}
void ComponentPhysics2d::onAdd()
{
auto contentSize = _owner->getContentSize();
_ownerCenterOffset.x = 0.5 * contentSize.width;
_ownerCenterOffset.y = 0.5 * contentSize.height;
_ownerOriginRotation = _owner->getRotation();
// component may be added after onEnter() has been invoked, so we should add
// this line to make sure physics body is added to physics world
addToPhysicsManager();
}
void ComponentPhysics2d::onRemove()
{
removePhysicsBody();
}
void ComponentPhysics2d::removePhysicsBody()
{
removeFromPhysicsManager();
if (_physicsBody)
{
_physicsBody->_componentBelongsTo = nullptr;
_physicsBody->release();
_physicsBody = nullptr;
}
}
void ComponentPhysics2d::addToPhysicsManager()
{
if (_owner)
{
auto scene = _owner->getScene();
if (scene)
scene->getPhysicsManager()->addPhysicsComponent(this);
}
}
void ComponentPhysics2d::removeFromPhysicsManager()
{
if (_owner)
{
auto scene = _owner->getScene();
if (scene)
scene->getPhysicsManager()->removePhysicsComponent(this);
}
}
Mat4 ComponentPhysics2d::getParentToWorldTransform() const
{
if (_owner->getParent())
return _owner->getParent()->getNodeToWorldTransform();
else
return _owner->getNodeToWorldTransform();
}
float ComponentPhysics2d::getPhysicsRotation(Node *node) const
{
if (!node)
return 0.0f;
auto physicsComponent = node->getComponent<ComponentPhysics2d>();
if (physicsComponent)
{
return physicsComponent->_physicsRotation;
}
else
{
auto parent = node->getParent();
if (parent)
return getPhysicsRotation(parent) + node->getRotation();
else
return 0.0f;
}
}
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -0,0 +1,140 @@
/****************************************************************************
Copyright (c) 2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/ccConfig.h" // to include defination of CC_USE_PHYSICS
#if CC_USE_PHYSICS
#include "platform/CCPlatformMacros.h"
#include "2d/CCComponent.h"
NS_CC_BEGIN
/**
* @addtogroup physics
* @{
* @addtogroup physics_2d
* @{
*/
class PhysicsBody;
class CC_DLL ComponentPhysics2d : public Component
{
public:
/**
* Create a physics component without physics body. Can set phyiscs body later with setPhysicsBody().
* I am not sure if we need this function, because i think physics body is needed when creating a
* physics component. But i think it is needed by editor, so i keep this function.
*
* @return A pointer of `ComponentPhysics2d` that is autoreleased.
*/
static ComponentPhysics2d* create();
/**
* Create a physics component with physics body.
*
* @param physicsBody The physics body that belongs to this component.
* @return A pointer of `ComponentPhysics2d` that is autoreleased.
*/
static ComponentPhysics2d* create(PhysicsBody *physicsBody);
virtual ~ComponentPhysics2d();
/// @cond DO_NOT_SHOW
/**
* Synchronize Node's status(position, rotation, scale) to phyiscs body.
* It is invoked before physics simulation.
*
* @warning Don't invoke this funciton by yourself.
*/
void beforeSimulation();
/**
* Synchronize physics body's status(position, rotation) to phyiscs body.
* It is invoked after physics simulation.
*
* @warning Don't invoke this funciton by yourself.
*/
void afterSimulation();
/// @endcond DO_NOT_SHOW
/**
* Set physics body of this physics component. If the physics body is set to
* another physics component before, will set another physics component's physics
* body to null.
*
* @param physicsBody The physics body belongs to this component.
*/
void setPhysicsBody(PhysicsBody *physicsBody);
/**
* Get the physics body of this component.
*
* @return The physics body of this component.
*/
PhysicsBody* getPhysicsBody() const;
virtual void setEnabled(bool value) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void onAdd() override;
virtual void onRemove() override;
public:
const static std::string COMPONENT_NAME;
CC_CONSTRUCTOR_ACCESS:
ComponentPhysics2d();
ComponentPhysics2d(PhysicsBody *phsicsBody);
private:
void removePhysicsBody();
void addToPhysicsManager();
void removeFromPhysicsManager();
Mat4 getParentToWorldTransform() const;
float getPhysicsRotation(Node *node) const;
bool isVec3Equal(const Vec3 &v1, const Vec3 &v2) const;
private:
// this physic body of this component
PhysicsBody *_physicsBody;
// offset between owner's center point and down left point
Vec3 _ownerCenterOffset;
Mat4 _nodeToWorldTransform;
// offset of owner's center point and anchor point in parent coordinate
Vec2 _offset;
float _physicsRotation;
// the rotation of owner when the component is added to, the value will not change
float _ownerOriginRotation;
Vec3 _recordScale;
Vec3 _scale;
};
/** @} */
/** @} */
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -31,10 +31,11 @@
#include "chipmunk.h"
#include "2d/CCScene.h"
#include "CCPhysicsShape.h"
#include "CCPhysicsJoint.h"
#include "CCPhysicsWorld.h"
#include "CCPhysicsHelper.h"
#include "physics/CCPhysicsShape.h"
#include "physics/CCPhysicsJoint.h"
#include "physics/CCPhysicsWorld.h"
#include "physics/CCPhysicsHelper.h"
#include "physics/CCComponentPhysics2d.h"
static inline void cpBodyUpdateVelocityWithoutGravity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
@ -51,8 +52,7 @@ namespace
}
PhysicsBody::PhysicsBody()
: _node(nullptr)
, _world(nullptr)
: _world(nullptr)
, _cpBody(nullptr)
, _dynamic(true)
, _enabled(true)
@ -68,10 +68,12 @@ PhysicsBody::PhysicsBody()
, _linearDamping(0.0f)
, _angularDamping(0.0f)
, _tag(0)
, _positionInitDirty(true)
, _rotationOffset(0)
, _recordedRotation(0.0f)
, _recordedAngle(0.0)
, _componentBelongsTo(nullptr)
, _massSetByUser(false)
, _momentSetByUser(false)
{
}
@ -334,8 +336,6 @@ void PhysicsBody::setGravityEnable(bool enable)
void PhysicsBody::setPosition(const Vec2& position)
{
_positionInitDirty = false;
_recordedPosition = position;
cpBodySetPos(_cpBody, PhysicsHelper::point2cpv(position + _positionOffset));
}
@ -350,25 +350,25 @@ void PhysicsBody::setScale(float scaleX, float scaleY)
{
for (auto shape : _shapes)
{
_area -= shape->getArea();
if (!_massSetByUser)
addMass(-shape->getMass());
if (!_momentSetByUser)
addMoment(-shape->getMoment());
shape->setScale(scaleX, scaleY);
_area += shape->getArea();
if (!_massSetByUser)
addMass(shape->getMass());
if (!_momentSetByUser)
addMoment(shape->getMoment());
}
}
const Vec2& PhysicsBody::getPosition()
Vec2 PhysicsBody::getPosition() const
{
if (_positionInitDirty) {
if (_node) {
if (_node->getParent()) {
_latestPosition = _node->getParent()->convertToWorldSpace(_node->getPosition());
} else {
_latestPosition = _node->getPosition();
}
}
} else {
_latestPosition.x = _cpBody->p.x - _positionOffset.x;
_latestPosition.y = _cpBody->p.y - _positionOffset.y;
}
return _latestPosition;
return Vec2(_cpBody->p.x - _positionOffset.x, _cpBody->p.y - _positionOffset.y);
}
float PhysicsBody::getRotation()
@ -450,6 +450,7 @@ void PhysicsBody::setMass(float mass)
}
_mass = mass;
_massDefault = false;
_massSetByUser = true;
// update density
if (_mass == PHYSICS_INFINITY)
@ -628,6 +629,7 @@ void PhysicsBody::setMoment(float moment)
{
_moment = moment;
_momentDefault = false;
_momentSetByUser = true;
// the static body's mass and moment is always infinity
if (_rotationEnabled && _dynamic)
@ -723,6 +725,14 @@ void PhysicsBody::removeFromWorld()
}
}
Node* PhysicsBody::getNode() const
{
if (_componentBelongsTo)
return _componentBelongsTo->getOwner();
else
return nullptr;
}
void PhysicsBody::setEnable(bool enable)
{
if (_enabled != enable)
@ -760,15 +770,12 @@ void PhysicsBody::setResting(bool rest) const
void PhysicsBody::update(float delta)
{
if (_node)
// damping compute
if (_isDamping && _dynamic && !isResting())
{
// damping compute
if (_isDamping && _dynamic && !isResting())
{
_cpBody->v.x *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
_cpBody->v.y *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
_cpBody->w *= cpfclamp(1.0f - delta * _angularDamping, 0.0f, 1.0f);
}
_cpBody->v.x *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
_cpBody->v.y *= cpfclamp(1.0f - delta * _linearDamping, 0.0f, 1.0f);
_cpBody->w *= cpfclamp(1.0f - delta * _angularDamping, 0.0f, 1.0f);
}
}

View File

@ -41,6 +41,7 @@ class Node;
class Sprite;
class PhysicsWorld;
class PhysicsJoint;
class ComponentPhysics2d;
typedef Vec2 Vect;
@ -305,7 +306,7 @@ public:
inline const std::vector<PhysicsJoint*>& getJoints() const { return _joints; }
/** get the sprite the body set to. */
inline Node* getNode() const { return _node; }
Node* getNode() const;
/**
* A mask that defines which categories this physics body belongs to.
@ -368,7 +369,7 @@ public:
int getGroup() const;
/** get the body position. */
const Vec2& getPosition();
Vec2 getPosition() const;
/** get the body rotation. */
float getRotation();
@ -505,7 +506,7 @@ public:
Vec2 local2World(const Vec2& point);
/** Get the rigid body of chipmunk. */
cpBody* getCPBody() { return _cpBody; }
cpBody* getCPBody() const { return _cpBody; }
protected:
@ -525,10 +526,11 @@ protected:
virtual ~PhysicsBody();
protected:
Node* _node;
std::vector<PhysicsJoint*> _joints;
Vector<PhysicsShape*> _shapes;
PhysicsWorld* _world;
// weak reference
ComponentPhysics2d *_componentBelongsTo;
cpBody* _cpBody;
bool _dynamic;
bool _enabled;
@ -545,9 +547,11 @@ protected:
float _angularDamping;
int _tag;
bool _positionInitDirty;
Vec2 _recordedPosition;
Vec2 _latestPosition;
// when setMass() is invoked, it means body's mass is not calculated by shapes
bool _massSetByUser;
// when setMoment() is invoked, it means body's moment is not calculated by shapes
bool _momentSetByUser;
Vec2 _positionOffset;
float _rotationOffset;
float _recordedRotation;
@ -559,6 +563,7 @@ protected:
friend class Node;
friend class Layer;
friend class ProtectedNode;
friend class ComponentPhysics2d;
};
/** @} */

View File

@ -0,0 +1,133 @@
/****************************************************************************
Copyright (c) 2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "base/ccConfig.h" // to include defination of CC_USE_PHYSICS
#if CC_USE_PHYSICS
#include "physics/CCPhysicsManager.h"
#include "physics/CCComponentPhysics2d.h"
#include "physics/CCPhysicsWorld.h"
#include "2d/CCScene.h"
NS_CC_BEGIN
PhysicsManager::PhysicsManager(Scene *scene)
: _scene(scene)
{
_physicsWorld = PhysicsWorld::construct();
}
PhysicsManager::~PhysicsManager()
{
delete _physicsWorld;
}
void PhysicsManager::update(float dt)
{
// Update physics position, should loop as the same sequence as node tree.
// ComponentPhysics2d::beforeSimulation() will depend on the sequence.
beforeSimulation(_scene);
// do simulation
_physicsWorld->update(dt, false);
// Update physics position, should loop as the same sequence as node tree.
// ComponentPhysics2d::afterSimulation() will depend on the sequence.
afterSimulation(_scene);
}
void PhysicsManager::beforeSimulation(Node *node)
{
auto iter = _owners.find(node);
if (iter != _owners.end())
{
auto component = iter->second;
component->beforeSimulation();
}
for (auto child : node->getChildren())
beforeSimulation(child);
}
void PhysicsManager::afterSimulation(Node *node)
{
auto iter = _owners.find(node);
if (iter != _owners.end())
{
auto component = iter->second;
component->afterSimulation();
}
for (auto child : node->getChildren())
afterSimulation(child);
}
void PhysicsManager::addPhysicsComponent(ComponentPhysics2d* componentPhsics2d)
{
// don't add component again
if (std::find(_components.begin(), _components.end(), componentPhsics2d) != _components.end())
return;
_components.push_back(componentPhsics2d);
// Node::getComponent<>() is a time comsuming operation, so record data to avoid invoking it.
std::pair<Node*, ComponentPhysics2d*> element(componentPhsics2d->getOwner(), componentPhsics2d);
_owners.insert(element);
if (nullptr != componentPhsics2d->getPhysicsBody())
_physicsWorld->addBody(componentPhsics2d->getPhysicsBody());
}
void PhysicsManager::removePhysicsComponent(ComponentPhysics2d* componentPhsics2d)
{
auto iter = std::find(_components.begin(), _components.end(), componentPhsics2d);
if (iter != _components.end())
{
removeElementFromMap(*iter);
_components.erase(iter);
if (componentPhsics2d->getPhysicsBody())
_physicsWorld->removeBody(componentPhsics2d->getPhysicsBody());
}
}
void PhysicsManager::removeElementFromMap(ComponentPhysics2d* component)
{
for (auto element : _owners)
{
if (element.second == component)
{
_owners.erase(element.first);
break;
}
}
}
PhysicsWorld* PhysicsManager::getPhysicsWorld() const
{
return _physicsWorld;
}
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -0,0 +1,124 @@
/****************************************************************************
Copyright (c) 2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#include "base/ccConfig.h" // to include defination of CC_USE_PHYSICS
#if CC_USE_PHYSICS
#include <vector>
#include <unordered_map>
#include "platform/CCPlatformMacros.h"
NS_CC_BEGIN
class ComponentPhysics2d;
class PhysicsWorld;
class Scene;
class Node;
/**
* @addtogroup physics
* @{
* @addtogroup physics_2d
* @{
*/
/**
* Now `PhysicsManager` belongs to a `Scene`. `Scene` will create `PhysicsManager` automatically.
* The reason to design like this are:
* - PhysicsManager keeps physics world, it is reasonale that a scene has its own physics world.
* It is useful that when a scene is active again, you don't have to create physics world and
* do all related things again.
* - Keep compatibility
*/
class CC_DLL PhysicsManager
{
public:
/// @cond DO_NOT_SHOW
/**
* Create a PhysicsManager with `Scene`. `Scene` will create it automatically,
* so don't create it yourself.
*
* @scene The scene this `PhysicsManager` belongs to.
*/
PhysicsManager(Scene *scene);
/**
* Destructor.
*/
~PhysicsManager();
/**
* Do physics simulation. It will do the following things:
* - synchronize Node's status(position, rotation, scale) to corresponding physics body
* - do physics simulation
* - synchronize physics body's status(position, rotation) to correspondind Node
*
* It is invoked by `Scene`, don't invoke it yourself.
*/
void update(float dt);
/// @endcond DO_NOT_SHOW
/**
* Get the physics world.
*
* @return Physics world managed by this `PhysicsManager`.
*/
PhysicsWorld* getPhysicsWorld() const;
/**
* Add a physics component to be managed by the `PhysicsManager`. Will register physics
* component's physics body to physics world managed by this `PhysicsManager`.
*
* @param componentPhsics2d The physics component to be managed by this `PhysicsManager`.
*/
void addPhysicsComponent(ComponentPhysics2d* componentPhsics2d);
/**
* Remove a physics component from `PhysiscsManager`. Will remove physics component's physics
* body from the physics world managed by this `PhysicsManager`.
*/
void removePhysicsComponent(ComponentPhysics2d* componentPhsics2d);
private:
void beforeSimulation(Node *node);
void afterSimulation(Node* node);
void removeElementFromMap(ComponentPhysics2d* component);
private:
std::vector<ComponentPhysics2d*> _components;
// record the owners of components for performance
std::unordered_map<Node*, ComponentPhysics2d*> _owners;
PhysicsWorld *_physicsWorld;
Scene *_scene;
};
/** @} */
/** @} */
NS_CC_END
#endif // CC_USE_PHYSICS

View File

@ -114,7 +114,7 @@ void PhysicsShape::setMaterial(const PhysicsMaterial& material)
void PhysicsShape::setScale(float scaleX, float scaleY)
{
if (_scaleX != scaleX || _scaleY != scaleY)
if (fabs(_scaleX - scaleX) > FLT_EPSILON || fabs(_scaleY - scaleY) > FLT_EPSILON)
{
if (_type == Type::CIRCLE && scaleX != scaleY)
{
@ -123,7 +123,13 @@ void PhysicsShape::setScale(float scaleX, float scaleY)
}
_newScaleX = scaleX;
_newScaleY = scaleY;
updateScale();
// re-calculate area and mass
_area = calculateArea();
_mass = _material.density * _area;
_moment = calculateDefaultMoment();
}
}
@ -649,10 +655,14 @@ void PhysicsShapePolygon::updateScale()
for (int i = 0; i < count; ++i)
{
cpVect n = cpvnormalize(cpvperp(cpvsub(vects[i], vects[(i + 1) % count])));
planes[i].n = n;
planes[i].d = cpvdot(n, vects[i]);
// cpVect n = cpvnormalize(cpvperp(cpvsub(vects[i], vects[(i + 1) % count])));
//
// planes[i].n = n;
// planes[i].d = cpvdot(n, vects[i]);
// FIXED ME: if update 'planes[i]' as the above codes, then can not query polygon shape by PhysicsWorld::getShapes().
// But modified like this, then ray test can not work correctly on some cases.
planes[i].d = cpvdot(planes[i].n, vects[i]);
}
PhysicsShape::updateScale();

View File

@ -281,7 +281,7 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact)
{
contact.setEventCode(PhysicsContact::EventCode::BEGIN);
contact.setWorld(this);
_scene->getEventDispatcher()->dispatchEvent(&contact);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&contact);
}
return ret ? contact.resetResult() : false;
@ -296,7 +296,7 @@ int PhysicsWorld::collisionPreSolveCallback(PhysicsContact& contact)
contact.setEventCode(PhysicsContact::EventCode::PRESOLVE);
contact.setWorld(this);
_scene->getEventDispatcher()->dispatchEvent(&contact);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&contact);
return contact.resetResult();
}
@ -310,7 +310,7 @@ void PhysicsWorld::collisionPostSolveCallback(PhysicsContact& contact)
contact.setEventCode(PhysicsContact::EventCode::POSTSOLVE);
contact.setWorld(this);
_scene->getEventDispatcher()->dispatchEvent(&contact);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&contact);
}
void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact)
@ -322,7 +322,7 @@ void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact)
contact.setEventCode(PhysicsContact::EventCode::SEPARATE);
contact.setWorld(this);
_scene->getEventDispatcher()->dispatchEvent(&contact);
Director::getInstance()->getEventDispatcher()->dispatchEvent(&contact);
}
void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Vec2& point1, const Vec2& point2, void* data)
@ -333,7 +333,6 @@ void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Vec2& point1,
{
if (!_delayAddBodies.empty() || !_delayRemoveBodies.empty())
{
_scene->updatePhysicsBodyTransform(_scene->getNodeToParentTransform(), 0, 1.0f, 1.0f);
updateBodies();
}
RayCastCallbackInfo info = { this, func, point1, point2, data };
@ -357,7 +356,6 @@ void PhysicsWorld::queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect
{
if (!_delayAddBodies.empty() || !_delayRemoveBodies.empty())
{
_scene->updatePhysicsBodyTransform(_scene->getNodeToParentTransform(), 0, 1.0f, 1.0f);
updateBodies();
}
RectQueryCallbackInfo info = {this, func, data};
@ -380,7 +378,6 @@ void PhysicsWorld::queryPoint(PhysicsQueryPointCallbackFunc func, const Vec2& po
{
if (!_delayAddBodies.empty() || !_delayRemoveBodies.empty())
{
_scene->updatePhysicsBodyTransform(_scene->getNodeToParentTransform(), 0, 1.0f, 1.0f);
updateBodies();
}
PointQueryCallbackInfo info = {this, func, data};
@ -422,10 +419,10 @@ PhysicsShape* PhysicsWorld::getShape(const Vec2& point) const
return shape == nullptr ? nullptr : s_physicsShapeMap.find(shape)->second;
}
PhysicsWorld* PhysicsWorld::construct(Scene& scene)
PhysicsWorld* PhysicsWorld::construct()
{
PhysicsWorld * world = new (std::nothrow) PhysicsWorld();
if(world && world->init(scene))
if(world && world->init())
{
return world;
}
@ -434,15 +431,13 @@ PhysicsWorld* PhysicsWorld::construct(Scene& scene)
return nullptr;
}
bool PhysicsWorld::init(Scene& scene)
bool PhysicsWorld::init()
{
do
{
_cpSpace = cpSpaceNew();
CC_BREAK_IF(_cpSpace == nullptr);
_scene = &scene;
cpSpaceSetGravity(_cpSpace, PhysicsHelper::point2cpv(_gravity));
cpSpaceSetDefaultCollisionHandler(_cpSpace,
@ -817,11 +812,9 @@ void PhysicsWorld::step(float delta)
void PhysicsWorld::update(float delta, bool userCall/* = false*/)
{
if(_updateBodyTransform || !_delayAddBodies.empty())
if(!_delayAddBodies.empty())
{
_scene->updatePhysicsBodyTransform(_scene->getNodeToParentTransform(), 0, 1.0f, 1.0f);
updateBodies();
_updateBodyTransform = false;
}
else if (!_delayRemoveBodies.empty())
{
@ -904,7 +897,7 @@ PhysicsDebugDraw::PhysicsDebugDraw(PhysicsWorld& world)
, _world(world)
{
_drawNode = DrawNode::create();
_world.getScene().addChild(_drawNode);
Director::getInstance()->getRunningScene()->addChild(_drawNode);
}
PhysicsDebugDraw::~PhysicsDebugDraw()

View File

@ -329,8 +329,9 @@ public:
void step(float delta);
protected:
static PhysicsWorld* construct(Scene& scene);
bool init(Scene& scene);
static PhysicsWorld* construct();
bool init();
virtual void addBody(PhysicsBody* body);
virtual void addShape(PhysicsShape* shape);
@ -389,6 +390,7 @@ protected:
friend class PhysicsJoint;
friend class PhysicsWorldCallback;
friend class PhysicsDebugDraw;
friend class PhysicsManager;
};
/** A physics helper class. Draw physics shape, joint in debug mode.

View File

@ -6,5 +6,6 @@ set(COCOS_PHYSICS_SRC
physics/CCPhysicsJoint.cpp
physics/CCPhysicsShape.cpp
physics/CCPhysicsWorld.cpp
physics/CCComponentPhysics2d.cpp
physics/CCPhysicsManager.cpp
)

View File

@ -2379,157 +2379,6 @@ tolua_lerror:
return 0;
}
#if CC_USE_PHYSICS
int lua_cocos2dx_Node_setPhysicsBody(lua_State* tolua_S)
{
int argc = 0;
cocos2d::Node* cobj = nullptr;
bool ok = true;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif
#if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,1,"cc.Node",0,&tolua_err)) goto tolua_lerror;
#endif
cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,0);
#if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_setPhysicsBody'", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S)-1;
if (argc == 1)
{
cocos2d::PhysicsBody* arg0;
ok &= luaval_to_object<cocos2d::PhysicsBody>(tolua_S, 2, "cc.PhysicsBody",&arg0, "cc.Node:setPhysicsBody");
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_setPhysicsBody'", nullptr);
return 0;
}
cobj->setPhysicsBody(arg0);
lua_settop(tolua_S, 1);
return 1;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:setPhysicsBody",argc, 1);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Node_setPhysicsBody'.",&tolua_err);
#endif
return 0;
}
int lua_cocos2dx_Node_removeFromPhysicsWorld(lua_State* tolua_S)
{
int argc = 0;
cocos2d::Node* cobj = nullptr;
bool ok = true;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif
#if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,1,"cc.Node",0,&tolua_err)) goto tolua_lerror;
#endif
cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,0);
#if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_removeFromPhysicsWorld'", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S)-1;
if (argc == 0)
{
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_removeFromPhysicsWorld'", nullptr);
return 0;
}
cobj->removeFromPhysicsWorld();
lua_settop(tolua_S, 1);
return 1;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:removeFromPhysicsWorld",argc, 0);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Node_removeFromPhysicsWorld'.",&tolua_err);
#endif
return 0;
}
int lua_cocos2dx_Node_getPhysicsBody(lua_State* tolua_S)
{
int argc = 0;
cocos2d::Node* cobj = nullptr;
bool ok = true;
#if COCOS2D_DEBUG >= 1
tolua_Error tolua_err;
#endif
#if COCOS2D_DEBUG >= 1
if (!tolua_isusertype(tolua_S,1,"cc.Node",0,&tolua_err)) goto tolua_lerror;
#endif
cobj = (cocos2d::Node*)tolua_tousertype(tolua_S,1,0);
#if COCOS2D_DEBUG >= 1
if (!cobj)
{
tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_Node_getPhysicsBody'", nullptr);
return 0;
}
#endif
argc = lua_gettop(tolua_S)-1;
if (argc == 0)
{
if(!ok)
{
tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_Node_getPhysicsBody'", nullptr);
return 0;
}
cocos2d::PhysicsBody* ret = cobj->getPhysicsBody();
object_to_luaval<cocos2d::PhysicsBody>(tolua_S, "cc.PhysicsBody",(cocos2d::PhysicsBody*)ret);
return 1;
}
luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Node:getPhysicsBody",argc, 0);
return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_Node_getPhysicsBody'.",&tolua_err);
#endif
return 0;
}
#endif //CC_USE_PHYSICS
#if CC_USE_NAVMESH
#include "navmesh/CCNavMesh.h"
int lua_cocos2dx_Scene_setNavMeshDebugCamera(lua_State* tolua_S)
@ -5083,18 +4932,6 @@ static void extendNode(lua_State* tolua_S)
lua_pushstring(tolua_S, "setRotationQuat");
lua_pushcfunction(tolua_S, lua_cocos2dx_Node_setRotationQuat);
lua_rawset(tolua_S, -3);
#if CC_USE_PHYSICS
lua_pushstring(tolua_S, "setPhysicsBody");
lua_pushcfunction(tolua_S, lua_cocos2dx_Node_setPhysicsBody);
lua_rawset(tolua_S, -3);
lua_pushstring(tolua_S, "removeFromPhysicsWorld");
lua_pushcfunction(tolua_S, lua_cocos2dx_Node_removeFromPhysicsWorld);
lua_rawset(tolua_S, -3);
lua_pushstring(tolua_S, "getPhysicsBody");
lua_pushcfunction(tolua_S, lua_cocos2dx_Node_getPhysicsBody);
lua_rawset(tolua_S, -3);
#endif //CC_USE_PHYSICS
}
lua_pop(tolua_S, 1);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,13 @@
#ifndef _PHYSICS_TEST_H_
#define _PHYSICS_TEST_H_
#include "cocos2d.h"
#include "../BaseTest.h"
#pragma once
#include <map>
DEFINE_TEST_SUITE(PhysicsTests);
#include "../BaseTest.h"
#if CC_USE_PHYSICS == 0
class PhysicsDemoDisabled : public TestCase
{
public:
CREATE_FUNC(PhysicsDemoDisabled);
virtual void onEnter() override;
};
#else
#if CC_USE_PHYSICS
DEFINE_TEST_SUITE(PhysicsTests);
class PhysicsDemo : public TestCase
{
@ -38,20 +29,32 @@ public:
bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
void toggleDebug();
protected:
void addPhysicsComponent(cocos2d::Node *node, cocos2d::PhysicsBody *physicsBody);
cocos2d::Texture2D* _spriteTexture;
cocos2d::SpriteBatchNode* _ball;
std::unordered_map<int, cocos2d::Node*> _mouses;
bool _debugDraw;
};
class PhysicsDemoLogoSmash : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoLogoSmash);
void onEnter() override;
virtual std::string title() const override;
};
class PhysicsDemoClickAdd : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoClickAdd);
virtual ~PhysicsDemoClickAdd();
void onEnter() override;
virtual std::string subtitle() const override;
@ -60,20 +63,11 @@ public:
void onAcceleration(cocos2d::Acceleration* acc, cocos2d::Event* event);
};
class PhysicsDemoLogoSmash : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoLogoSmash);
void onEnter() override;
virtual std::string title() const override;
};
class PhysicsDemoPyramidStack : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoPyramidStack);
void onEnter() override;
void updateOnce(float delta);
virtual std::string title() const override;
@ -83,9 +77,9 @@ class PhysicsDemoRayCast : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoRayCast);
PhysicsDemoRayCast();
void onEnter() override;
virtual std::string title() const override;
void update(float delta) override;
@ -101,20 +95,20 @@ private:
int _mode;
};
class PhysicsDemoJoints : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoJoints);
void onEnter() override;
virtual std::string title() const override;
};
class PhysicsDemoActions : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoActions);
void onEnter() override;
virtual std::string title() const override;
};
class PhysicsDemoJoints : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoJoints);
void onEnter() override;
virtual std::string title() const override;
};
@ -123,7 +117,7 @@ class PhysicsDemoPump : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoPump);
void onEnter() override;
void update(float delta) override;
virtual std::string title() const override;
@ -142,7 +136,7 @@ class PhysicsDemoOneWayPlatform : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoOneWayPlatform);
void onEnter() override;
virtual std::string title() const override;
@ -153,7 +147,7 @@ class PhysicsDemoSlice : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoSlice);
void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
@ -171,7 +165,7 @@ class PhysicsDemoBug3988 : public PhysicsDemo
{
public:
CREATE_FUNC(PhysicsDemoBug3988);
void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
@ -218,10 +212,10 @@ public:
virtual std::string subtitle() const override;
};
class Bug5482 : public PhysicsDemo
class PhysicsDemoBug5482 : public PhysicsDemo
{
public:
CREATE_FUNC(Bug5482);
CREATE_FUNC(PhysicsDemoBug5482);
void onEnter() override;
void onExit() override;
@ -274,5 +268,4 @@ public:
virtual std::string subtitle() const override;
};
#endif
#endif
#endif // #if CC_USE_PHYSICS

View File

@ -71,7 +71,9 @@ public:
addTest("Node: Parallax", [](){return new ParallaxTests(); });
addTest("Node: Particles", [](){return new ParticleTests(); });
addTest("Node: Particle3D (PU)", [](){return new Particle3DTests(); });
#if CC_USE_PHYSICS
addTest("Node: Physics", []() { return new PhysicsTests(); });
#endif
addTest("Node: Physics3D", []() { return new Physics3DTests(); } );
addTest("Node: RenderTexture", [](){return new RenderTextureTests(); });
addTest("Node: Scene", [](){return new SceneTests(); });

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ headers = %(cocosdir)s/cocos/cocos2d.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = Event(.*(Physics).*) Physics.*
classes = Event(.*(Physics).*) Physics.* ComponentPhysics2d
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
@ -46,7 +46,9 @@ skip = PhysicsBody::[getJoints createPolygon createEdgeChain createEdgePolygon],
PhysicsShapeEdgePolygon::[create ^getPoints$],
PhysicsShapeEdgeChain::[create ^getPoints$],
PhysicsWorld::[getScene queryPoint queryRect rayCast],
PhysicsContact::[getData setData]
PhysicsContact::[getData setData],
PhysicsManager::[PhysicsManager update],
ComponentPhysics2d::[beforeSimulation afterSimulation]
rename_functions =