issue #1056: 1. Removed ChipmunkTest, added ChipmunkAccelTouchTest.

2. Added Box2DTest and Box2DTestBed.
Tested on win32.
This commit is contained in:
James Chen 2012-03-21 15:43:35 +08:00
parent 0c91539c95
commit 2ac2da9c97
41 changed files with 1115 additions and 4881 deletions

View File

@ -1,5 +1,5 @@
#include <math.h>
#include <stdint.h>
//#include <stdint.h>
#ifdef __APPLE__
#import "TargetConditionals.h"

View File

@ -179,10 +179,6 @@
RelativePath="..\include\chipmunk\cpArbiter.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpArray.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpBB.h"
>
@ -191,86 +187,78 @@
RelativePath="..\include\chipmunk\cpBody.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpCollision.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpConstraint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpDampedRotarySpring.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpDampedSpring.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpGearJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpGrooveJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpHashSet.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpPinJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpPivotJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpPolyShape.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpRatchetJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpRotaryLimitJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpShape.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpSimpleMotor.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpSlideJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpSpace.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpSpaceHash.h"
RelativePath="..\include\chipmunk\cpSpatialIndex.h"
>
</File>
<File
RelativePath="..\include\chipmunk\cpVect.h"
>
</File>
<File
RelativePath="..\src\prime.h"
<Filter
Name="constraints"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\util.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpConstraint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpDampedRotarySpring.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpDampedSpring.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpGearJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpGrooveJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpPinJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpPivotJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpRatchetJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpRotaryLimitJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpSimpleMotor.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\cpSlideJoint.h"
>
</File>
<File
RelativePath="..\include\chipmunk\constraints\util.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="src"
@ -293,6 +281,10 @@
RelativePath="..\src\cpBB.c"
>
</File>
<File
RelativePath="..\src\cpBBTree.c"
>
</File>
<File
RelativePath="..\src\cpBody.c"
>
@ -301,62 +293,18 @@
RelativePath="..\src\cpCollision.c"
>
</File>
<File
RelativePath="..\src\constraints\cpConstraint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpDampedRotarySpring.c"
>
</File>
<File
RelativePath="..\src\constraints\cpDampedSpring.c"
>
</File>
<File
RelativePath="..\src\constraints\cpGearJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpGrooveJoint.c"
>
</File>
<File
RelativePath="..\src\cpHashSet.c"
>
</File>
<File
RelativePath="..\src\constraints\cpPinJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpPivotJoint.c"
>
</File>
<File
RelativePath="..\src\cpPolyShape.c"
>
</File>
<File
RelativePath="..\src\constraints\cpRatchetJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpRotaryLimitJoint.c"
>
</File>
<File
RelativePath="..\src\cpShape.c"
>
</File>
<File
RelativePath="..\src\constraints\cpSimpleMotor.c"
>
</File>
<File
RelativePath="..\src\constraints\cpSlideJoint.c"
>
</File>
<File
RelativePath="..\src\cpSpace.c"
>
@ -377,10 +325,70 @@
RelativePath="..\src\cpSpaceStep.c"
>
</File>
<File
RelativePath="..\src\cpSpatialIndex.c"
>
</File>
<File
RelativePath="..\src\cpSweep1D.c"
>
</File>
<File
RelativePath="..\src\cpVect.c"
>
</File>
<File
RelativePath="..\src\prime.h"
>
</File>
<Filter
Name="constraints"
>
<File
RelativePath="..\src\constraints\cpConstraint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpDampedRotarySpring.c"
>
</File>
<File
RelativePath="..\src\constraints\cpDampedSpring.c"
>
</File>
<File
RelativePath="..\src\constraints\cpGearJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpGrooveJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpPinJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpPivotJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpRatchetJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpRotaryLimitJoint.c"
>
</File>
<File
RelativePath="..\src\constraints\cpSimpleMotor.c"
>
</File>
<File
RelativePath="..\src\constraints\cpSlideJoint.c"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>

View File

@ -572,23 +572,23 @@ while(false)
The matrix is in Pixels.
@since v0.7.1
*/
CCAffineTransform nodeToParentTransform(void);
virtual CCAffineTransform nodeToParentTransform(void);
/** Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates.
The matrix is in Pixels.
@since v0.7.1
*/
CCAffineTransform parentToNodeTransform(void);
virtual CCAffineTransform parentToNodeTransform(void);
/** Retrusn the world affine transform matrix. The matrix is in Pixels.
@since v0.7.1
*/
CCAffineTransform nodeToWorldTransform(void);
virtual CCAffineTransform nodeToWorldTransform(void);
/** Returns the inverse world affine transform matrix. The matrix is in Pixels.
@since v0.7.1
*/
CCAffineTransform worldToNodeTransform(void);
virtual CCAffineTransform worldToNodeTransform(void);
/** Converts a Point to node (local) space coordinates. The result is in Points.
@since v0.7.1

View File

@ -83,9 +83,9 @@ public:
// attributes
/** whether or not the Sprite needs to be updated in the Atlas */
inline bool isDirty(void) { return m_bDirty; }
inline virtual bool isDirty(void) { return m_bDirty; }
/** make the Sprite to be updated in the Atlas. */
inline void setDirty(bool bDirty) { m_bDirty = bDirty; }
inline virtual void setDirty(bool bDirty) { m_bDirty = bDirty; }
/** get the quad (tex coords, vertex coords and color) information */
inline ccV3F_C4B_T2F_Quad getQuad(void) { return m_sQuad; }

View File

@ -262,7 +262,7 @@ It should work same as apples CFSwapInt32LittleToHost(..)
Increments the GL Draws counts by one.
The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.
*/
extern unsigned int g_uNumberOfDraws;
extern CC_DLL unsigned int g_uNumberOfDraws;
#define CC_INCREMENT_GL_DRAWS(__n__) g_uNumberOfDraws += __n__
/*******************/
@ -271,6 +271,6 @@ extern unsigned int g_uNumberOfDraws;
/** @def CCAnimationFrameDisplayedNotification
Notification name when a CCSpriteFrame is displayed
*/
#define CCAnimationFrameDisplayedNotification @"CCAnimationFrameDisplayedNotification"
#define CCAnimationFrameDisplayedNotification "CCAnimationFrameDisplayedNotification"
#endif // __CCMACROS_H__

View File

@ -26,6 +26,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef KM_GL_MATRIX_H_INCLUDED
#define KM_GL_MATRIX_H_INCLUDED
#include "CCPlatformMacros.h"
#define KM_GL_MODELVIEW 0x1700
#define KM_GL_PROJECTION 0x1701
#define KM_GL_TEXTURE 0x1702
@ -39,17 +41,17 @@ typedef unsigned int kmGLEnum;
extern "C" {
#endif
void kmGLFreeAll(void);
void kmGLPushMatrix(void);
void kmGLPopMatrix(void);
void kmGLMatrixMode(kmGLEnum mode);
void kmGLLoadIdentity(void);
void kmGLLoadMatrix(const kmMat4* pIn);
void kmGLMultMatrix(const kmMat4* pIn);
void kmGLTranslatef(float x, float y, float z);
void kmGLRotatef(float angle, float x, float y, float z);
void kmGLScalef(float x, float y, float z);
void kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut);
void CC_DLL kmGLFreeAll(void);
void CC_DLL kmGLPushMatrix(void);
void CC_DLL kmGLPopMatrix(void);
void CC_DLL kmGLMatrixMode(kmGLEnum mode);
void CC_DLL kmGLLoadIdentity(void);
void CC_DLL kmGLLoadMatrix(const kmMat4* pIn);
void CC_DLL kmGLMultMatrix(const kmMat4* pIn);
void CC_DLL kmGLTranslatef(float x, float y, float z);
void CC_DLL kmGLRotatef(float angle, float x, float y, float z);
void CC_DLL kmGLScalef(float x, float y, float z);
void CC_DLL kmGLGetMatrix(kmGLEnum mode, kmMat4* pOut);
#ifdef __cplusplus
}

View File

@ -148,7 +148,8 @@ bool CCSprite::initWithTexture(CCTexture2D *pTexture, const CCRect& rect, bool r
// shader program
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
m_bDirty = m_bRecursiveDirty = false;
m_bRecursiveDirty = false;
setDirty(false);
m_bOpacityModifyRGB = true;
m_nOpacity = 255;
@ -327,7 +328,7 @@ void CCSprite::setTextureRect(const CCRect& rect, bool rotated, const CCSize& un
if (m_pobBatchNode)
{
// update dirty_, don't update recursiveDirty_
m_bDirty = true;
setDirty(true);
}
else
{
@ -441,7 +442,7 @@ void CCSprite::updateTransform(void)
CCAssert(m_pobBatchNode, "updateTransform is only valid when CCSprite is being rendered using an CCSpriteBatchNode");
// recaculate matrix only if it is dirty
if( m_bDirty ) {
if( isDirty() ) {
// If it is not visible, or one of its ancestors is not visible, then do nothing:
if( !m_bIsVisible || ( m_pParent && m_pParent != m_pobBatchNode && ((CCSprite*)m_pParent)->m_bShouldBeHidden) ) {
@ -498,7 +499,8 @@ void CCSprite::updateTransform(void)
}
m_pobTextureAtlas->updateQuad(&m_sQuad, m_uAtlasIndex);
m_bDirty = m_bRecursiveDirty = false;
m_bRecursiveDirty = false;
setDirty(false);
}
// recursively iterate over children
@ -729,7 +731,8 @@ void CCSprite::setReorderChildDirtyRecursively(void)
void CCSprite::setDirtyRecursively(bool bValue)
{
m_bDirty = m_bRecursiveDirty = bValue;
m_bRecursiveDirty = bValue;
setDirty(bValue);
// recursively set dirty
if (m_bHasChildren)
{
@ -748,9 +751,10 @@ void CCSprite::setDirtyRecursively(bool bValue)
// XXX HACK: optimization
#define SET_DIRTY_RECURSIVELY() { \
if (m_pobBatchNode && ! m_bRecursiveDirty) { \
m_bDirty = m_bRecursiveDirty = true; \
if ( m_bHasChildren) \
setDirtyRecursively(true); \
m_bRecursiveDirty = true; \
setDirty(true); \
if ( m_bHasChildren) \
setDirtyRecursively(true); \
} \
}
@ -872,7 +876,7 @@ void CCSprite::updateColor(void)
{
// no need to set it recursively
// update dirty_, don't update recursiveDirty_
m_bDirty = true;
setDirty(true);
}
}
@ -999,7 +1003,8 @@ void CCSprite::setBatchNode(CCSpriteBatchNode *pobSpriteBatchNode)
if( ! m_pobBatchNode ) {
m_uAtlasIndex = CCSpriteIndexNotInitialized;
setTextureAtlas(NULL);
m_bDirty = m_bRecursiveDirty = false;
m_bRecursiveDirty = false;
setDirty(false);
float x1 = m_obOffsetPosition.x;
float y1 = m_obOffsetPosition.y;

View File

@ -863,6 +863,246 @@
>
</File>
</Filter>
<Filter
Name="Box2DTest"
>
<File
RelativePath="..\tests\Box2DTest\Box2dTest.cpp"
>
</File>
<File
RelativePath="..\tests\Box2DTest\Box2dTest.h"
>
</File>
</Filter>
<Filter
Name="Box2DTestBed"
>
<File
RelativePath="..\tests\Box2DTestBed\Box2dView.cpp"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Box2dView.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\GLES-Render.cpp"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\GLES-Render.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Test.cpp"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Test.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\TestEntries.cpp"
>
</File>
<Filter
Name="Tests"
>
<File
RelativePath="..\tests\Box2DTestBed\Tests\AddPair.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\ApplyForce.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\BodyTypes.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Breakable.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Bridge.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\BulletTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Cantilever.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Car.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Chain.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\CharacterCollision.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\CollisionFiltering.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\CollisionProcessing.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\CompoundShapes.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Confined.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\ContinuousTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\DistanceTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Dominos.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\DumpShell.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\DynamicTreeTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\EdgeShapes.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\EdgeTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Gears.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\OneSidedPlatform.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Pinball.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\PolyCollision.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\PolyShapes.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Prismatic.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Pulleys.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Pyramid.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\RayCast.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Revolute.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Rope.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\RopeJoint.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\SensorTest.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\ShapeEditing.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\SliderCrank.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\SphereStack.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\TheoJansen.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Tiles.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\TimeOfImpact.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Tumbler.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\VaryingFriction.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\VaryingRestitution.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\VerticalStack.h"
>
</File>
<File
RelativePath="..\tests\Box2DTestBed\Tests\Web.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="ChipmunkAccelTouchTest"
>
<File
RelativePath="..\tests\ChipmunkAccelTouchTest\ChipmunkAccelTouchTest.cpp"
>
</File>
<File
RelativePath="..\tests\ChipmunkAccelTouchTest\ChipmunkAccelTouchTest.h"
>
</File>
</Filter>
</Filter>
</Filter>
</Files>

View File

@ -2,83 +2,92 @@
#include "../testResource.h"
#define PTM_RATIO 32
enum
{
kTagTileMap = 1,
kTagSpriteManager = 1,
kTagAnimation1 = 1,
};
enum {
kTagParentNode = 1,
};
PhysicsSprite::PhysicsSprite()
: m_pBody(NULL)
{
}
void PhysicsSprite::setPhysicsBody(b2Body * body)
{
m_pBody = body;
}
// this method will only get called if the sprite is batched.
// return YES if the physics values (angles, position ) changed
// If you return NO, then nodeToParentTransform won't be called.
bool PhysicsSprite::isDirty(void)
{
return true;
}
// returns the transform matrix according the Chipmunk Body values
CCAffineTransform PhysicsSprite::nodeToParentTransform(void)
{
b2Vec2 pos = m_pBody->GetPosition();
float x = pos.x * PTM_RATIO;
float y = pos.y * PTM_RATIO;
if ( !getIsRelativeAnchorPoint() ) {
x += m_tAnchorPointInPoints.x;
y += m_tAnchorPointInPoints.y;
}
// Make matrix
float radians = m_pBody->GetAngle();
float c = cosf(radians);
float s = sinf(radians);
if( ! CCPoint::CCPointEqualToPoint(m_tAnchorPointInPoints, CCPointZero) ){
x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y;
y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y;
}
// Rot, Translate Matrix
m_tTransform = CCAffineTransformMake( c, s,
-s, c,
x, y );
return m_tTransform;
}
Box2DTestLayer::Box2DTestLayer()
: m_pSpriteTexture(NULL)
{
setIsTouchEnabled( true );
setIsAccelerometerEnabled( true );
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
//UXLOG(L"Screen width %0.2f screen height %0.2f",screenSize.width,screenSize.height);
// Define the gravity vector.
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
// Do we want to let bodies sleep?
bool doSleep = true;
// Construct a world object, which will hold and simulate the rigid bodies.
world = new b2World(gravity);
world->SetAllowSleeping(doSleep);
world->SetContinuousPhysics(true);
/*
m_debugDraw = new GLESDebugDraw( PTM_RATIO );
world->SetDebugDraw(m_debugDraw);
uint flags = 0;
flags += b2DebugDraw::e_shapeBit;
flags += b2DebugDraw::e_jointBit;
flags += b2DebugDraw::e_aabbBit;
flags += b2DebugDraw::e_pairBit;
flags += b2DebugDraw::e_centerOfMassBit;
m_debugDraw->SetFlags(flags);
*/
// Define the ground body.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(screenSize.width/2/PTM_RATIO, screenSize.height/2/PTM_RATIO); // bottom-left corner
// Call the body factory which allocates memory for the ground body
// from a pool and creates the ground box shape (also from a pool).
// The body is also added to the world.
b2Body* groundBody = world->CreateBody(&groundBodyDef);
// Define the ground box shape.
b2PolygonShape groundBox;
// bottom
groundBox.SetAsBox(screenSize.width/2/PTM_RATIO, 0, b2Vec2(0, -screenSize.height/2/PTM_RATIO), 0);
groundBody->CreateFixture(&groundBox, 0);
// top
groundBox.SetAsBox(screenSize.width/2/PTM_RATIO, 0, b2Vec2(0, screenSize.height/2/PTM_RATIO), 0);
groundBody->CreateFixture(&groundBox, 0);
// left
groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(-screenSize.width/2/PTM_RATIO, 0), 0);
groundBody->CreateFixture(&groundBox, 0);
// right
groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(screenSize.width/2/PTM_RATIO, 0), 0);
groundBody->CreateFixture(&groundBox, 0);
CCSize s = CCDirector::sharedDirector()->getWinSize();
// init physics
this->initPhysics();
// create reset button
this->createResetButton();
//Set up sprite
CCSpriteBatchNode *mgr = CCSpriteBatchNode::batchNodeWithFile(s_pPathBlock, 150);
addChild(mgr, 0, kTagSpriteManager);
addNewSpriteWithCoords( CCPointMake(screenSize.width/2, screenSize.height/2) );
CCLabelTTF *label = CCLabelTTF::labelWithString("Tap screen", "Marker Felt", 32);
addChild(label, 0);
label->setColor( ccc3(0,0,255) );
label->setPosition( CCPointMake( screenSize.width/2, screenSize.height-50) );
#if 1
// Use batch node. Faster
CCSpriteBatchNode *parent = CCSpriteBatchNode::batchNodeWithFile("Images/blocks.png", 100);
m_pSpriteTexture = parent->getTexture();
#else
// doesn't use batch node. Slower
m_pSpriteTexture = CCTextureCache::sharedTextureCache()->addImage("Images/blocks.png");
CCNode *parent = CCNode::node();
#endif
addChild(parent, 0, kTagParentNode);
addNewSpriteAtPosition(ccp(s.width/2, s.height/2));
CCLabelTTF *label = CCLabelTTF::labelWithString("Tap screen", "Marker Felt", 32);
addChild(label, 0);
label->setColor(ccc3(0,0,255));
label->setPosition(ccp( s.width/2, s.height-50));
scheduleUpdate();
}
@ -91,34 +100,116 @@ Box2DTestLayer::~Box2DTestLayer()
//delete m_debugDraw;
}
void Box2DTestLayer::draw()
{
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//world->DrawDebugData();
// restore default GL states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
void Box2DTestLayer::initPhysics()
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
world = new b2World(gravity);
// Do we want to let bodies sleep?
world->SetAllowSleeping(true);
world->SetContinuousPhysics(true);
// m_debugDraw = new GLESDebugDraw( PTM_RATIO );
// world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
// flags += b2Draw::e_jointBit;
// flags += b2Draw::e_aabbBit;
// flags += b2Draw::e_pairBit;
// flags += b2Draw::e_centerOfMassBit;
//m_debugDraw->SetFlags(flags);
// Define the ground body.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0); // bottom-left corner
// Call the body factory which allocates memory for the ground body
// from a pool and creates the ground box shape (also from a pool).
// The body is also added to the world.
b2Body* groundBody = world->CreateBody(&groundBodyDef);
// Define the ground box shape.
b2EdgeShape groundBox;
// bottom
groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
// top
groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
groundBody->CreateFixture(&groundBox,0);
// left
groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
groundBody->CreateFixture(&groundBox,0);
// right
groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
groundBody->CreateFixture(&groundBox,0);
}
void Box2DTestLayer::addNewSpriteWithCoords(CCPoint p)
void Box2DTestLayer::createResetButton()
{
CCMenuItemImage *reset = CCMenuItemImage::itemWithNormalImage("Images/r1.png", "Images/r2.png", this, menu_selector(Box2DTestLayer::reset));
CCMenu *menu = CCMenu::menuWithItems(reset, NULL);
CCSize s = CCDirector::sharedDirector()->getWinSize();
menu->setPosition(ccp(s.width/2, 30));
this->addChild(menu, -1);
}
void Box2DTestLayer::reset(CCObject* sender)
{
//UXLOG(L"Add sprite %0.2f x %02.f",p.x,p.y);
CCSpriteBatchNode* batch = (CCSpriteBatchNode*)getChildByTag(kTagSpriteManager);
CCScene* s = CCScene::node();
Box2DTestLayer* child = new Box2DTestLayer();
s->addChild(child);
child->release();
CCDirector::sharedDirector()->replaceScene(s);
}
void Box2DTestLayer::draw()
{
//
// IMPORTANT:
// This is only for debug purposes
// It is recommend to disable it
//
CCLayer::draw();
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
world->DrawDebugData();
kmGLPopMatrix();
}
void Box2DTestLayer::addNewSpriteAtPosition(CCPoint p)
{
CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
CCNode* parent = getChildByTag(kTagParentNode);
//We have a 64x64 sprite sheet with 4 different 32x32 images. The following code is
//just randomly picking one of the images
int idx = (CCRANDOM_0_1() > .5 ? 0:1);
int idy = (CCRANDOM_0_1() > .5 ? 0:1);
CCSprite *sprite = CCSprite::spriteWithTexture(batch->getTexture(), CCRectMake(32 * idx,32 * idy,32,32));
batch->addChild(sprite);
PhysicsSprite *sprite = new PhysicsSprite();
sprite->initWithTexture(m_pSpriteTexture, CCRectMake(32 * idx,32 * idy,32,32));
sprite->autorelease();
parent->addChild(sprite);
sprite->setPosition( CCPointMake( p.x, p.y) );
@ -127,7 +218,7 @@ void Box2DTestLayer::addNewSpriteWithCoords(CCPoint p)
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
bodyDef.userData = sprite;
b2Body *body = world->CreateBody(&bodyDef);
// Define another box shape for our dynamic body.
@ -140,6 +231,8 @@ void Box2DTestLayer::addNewSpriteWithCoords(CCPoint p)
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);
sprite->setPhysicsBody(body);
}
@ -156,17 +249,6 @@ void Box2DTestLayer::update(ccTime dt)
// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
world->Step(dt, velocityIterations, positionIterations);
//Iterate over the bodies in the physics world
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite* myActor = (CCSprite*)b->GetUserData();
myActor->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
}
}
}
void Box2DTestLayer::ccTouchesEnded(CCSet* touches, CCEvent* event)
@ -186,7 +268,7 @@ void Box2DTestLayer::ccTouchesEnded(CCSet* touches, CCEvent* event)
location = CCDirector::sharedDirector()->convertToGL(location);
addNewSpriteWithCoords( location );
addNewSpriteAtPosition( location );
}
}

View File

@ -5,18 +5,33 @@
#include "Box2D/Box2D.h"
#include "../testBasic.h"
class PhysicsSprite : public CCSprite
{
public:
PhysicsSprite();
void setPhysicsBody(b2Body * body);
virtual bool isDirty(void);
virtual CCAffineTransform nodeToParentTransform(void);
private:
b2Body* m_pBody; // strong ref
};
class Box2DTestLayer : public CCLayer
{
CCTexture2D* m_pSpriteTexture; // weak ref
b2World* world;
//GLESDebugDraw *m_debugDraw;
// GLESDebugDraw* m_debugDraw;
public:
Box2DTestLayer();
~Box2DTestLayer();
void initPhysics();
void createResetButton();
void reset(CCObject* sender);
virtual void draw();
void addNewSpriteWithCoords(CCPoint p);
void addNewSpriteAtPosition(CCPoint p);
void update(ccTime dt);
virtual void ccTouchesEnded(CCSet* touches, CCEvent* event);

View File

@ -195,19 +195,15 @@ void Box2DView::draw()
{
CCLayer::draw();
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
m_test->m_world->DrawDebugData();
// restore default GL states
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
m_test->m_world->DrawDebugData();
kmGLPopMatrix();
CHECK_GL_ERROR_DEBUG();
}
Box2DView::~Box2DView()

View File

@ -1,21 +1,56 @@
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "GLES-Render.h"
#include "CCGL.h"
#include "CCGLProgram.h"
#include "CCShaderCache.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
USING_NS_CC;
GLESDebugDraw::GLESDebugDraw()
: mRatio( 1.0f )
{
this->initShader();
}
GLESDebugDraw::GLESDebugDraw( float32 ratio )
: mRatio( ratio )
{
this->initShader();
}
void GLESDebugDraw::initShader( void )
{
mShaderProgram = CCShaderCache::sharedShaderCache()->programForKey(kCCShader_Position_uColor);
mColorLocation = glGetUniformLocation( mShaderProgram->getProgram(), "u_color");
}
void GLESDebugDraw::DrawPolygon(const b2Vec2* old_vertices, int vertexCount, const b2Color& color)
{
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
b2Vec2* vertices = new b2Vec2[vertexCount];
for( int i=0;i<vertexCount;i++)
{
@ -23,35 +58,50 @@ void GLESDebugDraw::DrawPolygon(const b2Vec2* old_vertices, int vertexCount, con
vertices[i] *= mRatio;
}
glColor4f(color.r, color.g, color.b,1);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
delete[] vertices;
}
void GLESDebugDraw::DrawSolidPolygon(const b2Vec2* old_vertices, int vertexCount, const b2Color& color)
{
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
b2Vec2* vertices = new b2Vec2[vertexCount];
for( int i=0;i<vertexCount;i++) {
vertices[i] = old_vertices[i];
vertices[i] *= mRatio;
}
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColor4f(color.r, color.g, color.b,0.5f);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
glColor4f(color.r, color.g, color.b,1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r*0.5f, color.g*0.5f, color.b*0.5f, 0.5f);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
CC_INCREMENT_GL_DRAWS(2);
CHECK_GL_ERROR_DEBUG();
delete[] vertices;
}
void GLESDebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color)
{
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
const float32 k_segments = 16.0f;
int vertexCount=16;
const float32 k_increment = 2.0f * b2_pi / k_segments;
@ -66,17 +116,23 @@ void GLESDebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Col
theta += k_increment;
}
glColor4f(color.r, color.g, color.b,1);
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, glVertices);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
delete[] glVertices;
}
void GLESDebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color)
{
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
const float32 k_segments = 16.0f;
int vertexCount=16;
const float32 k_increment = 2.0f * b2_pi / k_segments;
@ -91,52 +147,77 @@ void GLESDebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const
theta += k_increment;
}
glColor4f(color.r, color.g, color.b,0.5f);
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
glColor4f(color.r, color.g, color.b,1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
// Draw the axis line
DrawSegment(center,center+radius*axis,color);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r*0.5f, color.g*0.5f, color.b*0.5f, 0.5f);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, glVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
// Draw the axis line
DrawSegment(center,center+radius*axis,color);
CC_INCREMENT_GL_DRAWS(2);
CHECK_GL_ERROR_DEBUG();
delete[] glVertices;
}
void GLESDebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
{
glColor4f(color.r, color.g, color.b,1);
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
GLfloat glVertices[] =
{
p1.x * mRatio, p1.y * mRatio,
p2.x * mRatio, p2.y * mRatio
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_LINES, 0, 2);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, glVertices);
glDrawArrays(GL_LINES, 0, 2);
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
}
void GLESDebugDraw::DrawTransform(const b2Transform& xf)
{
b2Vec2 p1 = xf.p, p2;
const float32 k_axisScale = 0.4f;
p2 = p1 + k_axisScale * xf.q.GetXAxis();
DrawSegment(p1,p2,b2Color(1,0,0));
p2 = p1 + k_axisScale * xf.q.GetYAxis();
b2Vec2 p1 = xf.p, p2;
const float32 k_axisScale = 0.4f;
p2 = p1 + k_axisScale * xf.q.GetXAxis();
DrawSegment(p1, p2, b2Color(1,0,0));
p2 = p1 + k_axisScale * xf.q.GetYAxis();
DrawSegment(p1,p2,b2Color(0,1,0));
}
void GLESDebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color)
{
glColor4f(color.r, color.g, color.b,1);
glPointSize(size);
GLfloat glVertices[] = {
p.x * mRatio, p.y * mRatio
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_POINTS, 0, 1);
glPointSize(1.0f);
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
// glPointSize(size);
GLfloat glVertices[] = {
p.x * mRatio, p.y * mRatio
};
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, glVertices);
glDrawArrays(GL_POINTS, 0, 1);
// glPointSize(1.0f);
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
}
void GLESDebugDraw::DrawString(int x, int y, const char *string, ...)
@ -146,17 +227,25 @@ void GLESDebugDraw::DrawString(int x, int y, const char *string, ...)
/* Unsupported as yet. Could replace with bitmap font renderer at a later date */
}
void GLESDebugDraw::DrawAABB(b2AABB* aabb, const b2Color& c)
void GLESDebugDraw::DrawAABB(b2AABB* aabb, const b2Color& color)
{
glColor4f(c.r, c.g, c.b,1);
GLfloat glVertices[] = {
aabb->lowerBound.x * mRatio, aabb->lowerBound.y * mRatio,
aabb->upperBound.x * mRatio, aabb->lowerBound.y * mRatio,
aabb->upperBound.x * mRatio, aabb->upperBound.y * mRatio,
aabb->lowerBound.x * mRatio, aabb->upperBound.y * mRatio
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_LINE_LOOP, 0, 8);
mShaderProgram->use();
mShaderProgram->setUniformForModelViewProjectionMatrix();
mShaderProgram->setUniformLocationWith4f(mColorLocation, color.r, color.g, color.b, 1);
GLfloat glVertices[] = {
aabb->lowerBound.x * mRatio, aabb->lowerBound.y * mRatio,
aabb->upperBound.x * mRatio, aabb->lowerBound.y * mRatio,
aabb->upperBound.x * mRatio, aabb->upperBound.y * mRatio,
aabb->lowerBound.x * mRatio, aabb->upperBound.y * mRatio
};
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, glVertices);
glDrawArrays(GL_LINE_LOOP, 0, 8);
CC_INCREMENT_GL_DRAWS(1);
CHECK_GL_ERROR_DEBUG();
}

View File

@ -1,12 +1,28 @@
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef RENDER_H
#define RENDER_H
//#import <UIKit/UIKit.h>
//#import <OpenGLES/EAGL.h>
//#import <OpenGLES/ES1/gl.h>
//#import <OpenGLES/ES1/glext.h>
#include "Box2D/Box2D.h"
#include "cocos2d.h"
struct b2AABB;
@ -15,6 +31,10 @@ struct b2AABB;
class GLESDebugDraw : public b2Draw
{
float32 mRatio;
cocos2d::CCGLProgram* mShaderProgram;
GLint mColorLocation;
void initShader( void );
public:
GLESDebugDraw();

View File

@ -0,0 +1,276 @@
//
// Accelerometer + Chipmunk physics + multi touches example
// a cocos2d example
// http://www.cocos2d-x.org
//
#include "ChipmunkAccelTouchTest.h"
enum {
kTagParentNode = 1,
};
// callback to remove Shapes from the Space
void removeShape( cpBody *body, cpShape *shape, void *data )
{
cpShapeFree( shape );
}
ChipmunkPhysicsSprite::ChipmunkPhysicsSprite()
: body_(NULL)
{
}
ChipmunkPhysicsSprite::~ChipmunkPhysicsSprite()
{
cpBodyEachShape(body_, removeShape, NULL);
cpBodyFree( body_ );
}
void ChipmunkPhysicsSprite::setPhysicsBody(cpBody * body)
{
body_ = body;
}
// this method will only get called if the sprite is batched.
// return YES if the physics values (angles, position ) changed
// If you return NO, then nodeToParentTransform won't be called.
bool ChipmunkPhysicsSprite::isDirty(void)
{
return true;
}
CCAffineTransform ChipmunkPhysicsSprite::nodeToParentTransform(void)
{
CGFloat x = body_->p.x;
CGFloat y = body_->p.y;
if ( !getIsRelativeAnchorPoint() ) {
x += m_tAnchorPointInPoints.x;
y += m_tAnchorPointInPoints.y;
}
// Make matrix
CGFloat c = body_->rot.x;
CGFloat s = body_->rot.y;
if( ! CCPoint::CCPointEqualToPoint(m_tAnchorPointInPoints, CCPointZero) ){
x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y;
y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y;
}
// Rot, Translate Matrix
m_tTransform = CCAffineTransformMake( c, s,
-s, c,
x, y );
return m_tTransform;
}
ChipmunkAccelTouchTestLayer::ChipmunkAccelTouchTestLayer()
{
// enable events
setIsTouchEnabled(true);
setIsAccelerometerEnabled(true);
CCSize s = CCDirector::sharedDirector()->getWinSize();
// title
CCLabelTTF *label = CCLabelTTF::labelWithString("Multi touch the screen", "Marker Felt", 36);
label->setPosition(ccp( s.width / 2, s.height - 30));
this->addChild(label, -1);
// reset button
createResetButton();
// init physics
initPhysics();
#if 1
// Use batch node. Faster
CCSpriteBatchNode *parent = CCSpriteBatchNode::batchNodeWithFile("Images/grossini_dance_atlas.png", 100);
spriteTexture_ = parent->getTexture();
#else
// doesn't use batch node. Slower
spriteTexture_ = CCTextureCache::sharedTextureCache()->addImage("Images/grossini_dance_atlas.png");
CCNode *parent = CCNode::node();
#endif
addChild(parent, 0, kTagParentNode);
addNewSpriteAtPosition(ccp(200,200));
scheduleUpdate();
}
ChipmunkAccelTouchTestLayer::~ChipmunkAccelTouchTestLayer()
{
// manually Free rogue shapes
for( int i=0;i<4;i++) {
cpShapeFree( walls_[i] );
}
cpSpaceFree( space_ );
}
void ChipmunkAccelTouchTestLayer::initPhysics()
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
// init chipmunk
cpInitChipmunk();
space_ = cpSpaceNew();
space_->gravity = cpv(0, -100);
//
// rogue shapes
// We have to free them manually
//
// bottom
walls_[0] = cpSegmentShapeNew( space_->staticBody, cpv(0,0), cpv(s.width,0), 0.0f);
// top
walls_[1] = cpSegmentShapeNew( space_->staticBody, cpv(0,s.height), cpv(s.width,s.height), 0.0f);
// left
walls_[2] = cpSegmentShapeNew( space_->staticBody, cpv(0,0), cpv(0,s.height), 0.0f);
// right
walls_[3] = cpSegmentShapeNew( space_->staticBody, cpv(s.width,0), cpv(s.width,s.height), 0.0f);
for( int i=0;i<4;i++) {
walls_[i]->e = 1.0f;
walls_[i]->u = 1.0f;
cpSpaceAddStaticShape(space_, walls_[i] );
}
}
void ChipmunkAccelTouchTestLayer::update(ccTime delta)
{
// Should use a fixed size step based on the animation interval.
int steps = 2;
CGFloat dt = CCDirector::sharedDirector()->getAnimationInterval()/(CGFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space_, dt);
}
}
void ChipmunkAccelTouchTestLayer::createResetButton()
{
CCMenuItemImage *reset = CCMenuItemImage::itemWithNormalImage("Images/r1.png", "Images/r2.png", this, menu_selector(ChipmunkAccelTouchTestLayer::reset));
CCMenu *menu = CCMenu::menuWithItems(reset, NULL);
CCSize s = CCDirector::sharedDirector()->getWinSize();
menu->setPosition(ccp(s.width/2, 30));
this->addChild(menu, -1);
}
void ChipmunkAccelTouchTestLayer::reset(CCObject* sender)
{
CCScene* s = CCScene::node();
ChipmunkAccelTouchTestLayer* child = new ChipmunkAccelTouchTestLayer();
s->addChild(child);
child->release();
CCDirector::sharedDirector()->replaceScene(s);
}
void ChipmunkAccelTouchTestLayer::addNewSpriteAtPosition(CCPoint pos)
{
int posx, posy;
CCNode *parent = getChildByTag(kTagParentNode);
posx = CCRANDOM_0_1() * 200.0f;
posy = CCRANDOM_0_1() * 200.0f;
posx = (posx % 4) * 85;
posy = (posy % 3) * 121;
ChipmunkPhysicsSprite *sprite = new ChipmunkPhysicsSprite();
sprite->initWithTexture(spriteTexture_, CCRectMake(posx, posy, 85, 121));
sprite->autorelease();
parent->addChild(sprite);
sprite->setPosition(pos);
int num = 4;
cpVect verts[] = {
cpv(-24,-54),
cpv(-24, 54),
cpv( 24, 54),
cpv( 24,-54),
};
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero));
body->p = cpv(pos.x, pos.y);
cpSpaceAddBody(space_, body);
cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero);
shape->e = 0.5f; shape->u = 0.5f;
cpSpaceAddShape(space_, shape);
sprite->setPhysicsBody(body);
}
void ChipmunkAccelTouchTestLayer::onEnter()
{
CCLayer::onEnter();
// CCAccelerometer::sharedAccelerometer()->setUpdateInterval:(1.0 / 60)];
}
void ChipmunkAccelTouchTestLayer::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
//Add a new body/atlas sprite at the touched location
CCSetIterator it;
CCTouch* touch;
for( it = touches->begin(); it != touches->end(); it++)
{
touch = (CCTouch*)(*it);
if(!touch)
break;
CCPoint location = touch->locationInView();
location = CCDirector::sharedDirector()->convertToGL(location);
addNewSpriteAtPosition( location );
}
}
void ChipmunkAccelTouchTestLayer::didAccelerate(CCAcceleration* pAccelerationValue)
{
static float prevX=0, prevY=0;
#define kFilterFactor 0.05f
float accelX = (float) pAccelerationValue->x * kFilterFactor + (1- kFilterFactor)*prevX;
float accelY = (float) pAccelerationValue->y * kFilterFactor + (1- kFilterFactor)*prevY;
prevX = accelX;
prevY = accelY;
CCPoint v = ccp( accelX, accelY);
v = ccpMult(v, 200);
space_->gravity = cpv(v.x, v.y);
}
void ChipmunkAccelTouchTestScene::runThisTest()
{
CCLayer* pLayer = new ChipmunkAccelTouchTestLayer();
addChild(pLayer);
pLayer->release();
CCDirector::sharedDirector()->replaceScene(this);
}

View File

@ -0,0 +1,50 @@
//
// cocos2d
//
#ifndef __CHIPMUNKACCELTOUCHTEST_H__
#define __CHIPMUNKACCELTOUCHTEST_H__
#include "cocos2d.h"
#include "chipmunk.h"
#include "../testBasic.h"
class ChipmunkAccelTouchTestLayer : public CCLayer
{
public:
ChipmunkAccelTouchTestLayer();
~ChipmunkAccelTouchTestLayer();
void onEnter();
void initPhysics();
void createResetButton();
void reset(CCObject* sender);
void addNewSpriteAtPosition(CCPoint p);
void update(ccTime dt);
virtual void ccTouchesEnded(CCSet* touches, CCEvent* event);
virtual void didAccelerate(CCAcceleration* pAccelerationValue);
CCTexture2D *spriteTexture_; // weak ref
cpSpace *space_; // strong ref
cpShape *walls_[4];
};
class ChipmunkPhysicsSprite : public CCSprite
{
public:
ChipmunkPhysicsSprite();
virtual ~ChipmunkPhysicsSprite();
void setPhysicsBody(cpBody* body);
virtual bool isDirty(void);
virtual CCAffineTransform nodeToParentTransform(void);
private:
cpBody *body_; // strong ref
};
class ChipmunkAccelTouchTestScene : public TestScene
{
public:
virtual void runThisTest();
};
#endif /* __CHIPMUNKACCELTOUCHTEST_H__ */

View File

@ -1,121 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static void
update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static void
add_box()
{
const cpFloat size = 10.0f;
const cpFloat mass = 1.0f;
cpVect verts[] = {
cpv(-size,-size),
cpv(-size, size),
cpv( size, size),
cpv( size,-size),
};
cpFloat radius = cpvlength(cpv(size, size));
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts, cpvzero)));
body->p = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
body->v = cpvmult(cpv(2*frand() - 1, 2*frand() - 1), 200);
cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 4, verts, cpvzero));
shape->e = 1.0f; shape->u = 0.0f;
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 30.0f, 1000);
space->iterations = 10;
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
for(int i=0; i<10; i++)
add_box();
body = cpSpaceAddBody(space, cpBodyNew(100.0f, 10000.0f));
shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, cpv(-75,0), cpv(75,0), 5.0f));
shape->e = 1.0f; shape->u = 1.0f;
cpSpaceAddConstraint(space, cpPivotJointNew2(body, staticBody, cpvzero, cpvzero));
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Bounce = {
"Bounce",
NULL,
init,
update,
destroy,
};

View File

@ -1,48 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
struct chipmunkDemo;
typedef cpSpace *(*demoInitFunc)(void);
typedef void (*demoUpdateFunc)(int ticks);
typedef void (*demoDestroyFunc)(void);
typedef struct chipmunkDemo {
const char *name;
drawSpaceOptions *drawOptions;
demoInitFunc initFunc;
demoUpdateFunc updateFunc;
demoDestroyFunc destroyFunc;
} chipmunkDemo;
static inline cpFloat
frand(void)
{
return (cpFloat)rand()/(cpFloat)RAND_MAX;
}
extern cpVect arrowDirection;
extern char messageString[1024];
#define GRABABLE_MASK_BIT (1<<31)
#define NOT_GRABABLE_MASK (~GRABABLE_MASK_BIT)

View File

@ -1,294 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpBody *
addBall(cpVect pos, cpVect boxOffset)
{
cpFloat radius = 15.0f;
cpFloat mass = 1.0f;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
body->p = cpvadd(pos, boxOffset);
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
return body;
}
static cpBody *
addLever(cpVect pos, cpVect boxOffset)
{
cpFloat mass = 1.0f;
cpVect a = cpv(0, 15);
cpVect b = cpv(0, -15);
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
body->p = cpvadd(pos, cpvadd(boxOffset, cpv(0, -15)));
cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 5.0f));
shape->e = 0.0f; shape->u = 0.7f;
return body;
}
static cpBody *
addBar(cpVect pos, cpVect boxOffset)
{
cpFloat mass = 2.0f;
cpVect a = cpv(0, 30);
cpVect b = cpv(0, -30);
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
body->p = cpvadd(pos, boxOffset);
cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 5.0f));
shape->e = 0.0f; shape->u = 0.7f;
return body;
}
static cpBody *
addWheel(cpVect pos, cpVect boxOffset)
{
cpFloat radius = 15.0f;
cpFloat mass = 1.0f;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
body->p = cpvadd(pos, boxOffset);
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
shape->group = 1; // use a group to keep the car parts from colliding
return body;
}
static cpBody *
addChassis(cpVect pos, cpVect boxOffset)
{
int num = 4;
cpVect verts[] = {
cpv(-40,-15),
cpv(-40, 15),
cpv( 40, 15),
cpv( 40,-15),
};
cpFloat mass = 5.0f;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, num, verts, cpvzero)));
body->p = cpvadd(pos, boxOffset);
cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
shape->group = 1; // use a group to keep the car parts from colliding
return body;
}
static cpSpace *
init(void)
{
space = cpSpaceNew();
space->iterations = 10;
space->gravity = cpv(0, -100);
space->sleepTimeThreshold = 0.5f;
cpBody *staticBody = &space->staticBody;
cpShape *shape;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,120), cpv(320,120), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,0), cpv(320,0), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-120), cpv(320,-120), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-240), cpv(-160,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(0,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(160,-240), cpv(160,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
cpVect boxOffset;
cpBody *body1, *body2;
cpVect posA = cpv( 50, 60);
cpVect posB = cpv(110, 60);
#define POS_A cpvadd(boxOffset, posA)
#define POS_B cpvadd(boxOffset, posB)
// Pin Joints - Link shapes with a solid bar or pin.
// Keeps the anchor points the same distance apart from when the joint was created.
boxOffset = cpv(-320, -240);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
cpSpaceAddConstraint(space, cpPinJointNew(body1, body2, cpv(15,0), cpv(-15,0)));
// Slide Joints - Like pin joints but with a min/max distance.
// Can be used for a cheap approximation of a rope.
boxOffset = cpv(-160, -240);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
cpSpaceAddConstraint(space, cpSlideJointNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 40.0f));
// Pivot Joints - Holds the two anchor points together. Like a swivel.
boxOffset = cpv(0, -240);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
cpSpaceAddConstraint(space, cpPivotJointNew(body1, body2, cpvadd(boxOffset, cpv(80,60))));
// cpPivotJointNew() takes it's anchor parameter in world coordinates. The anchors are calculated from that
// cpPivotJointNew2() lets you specify the two anchor points explicitly
// Groove Joints - Like a pivot joint, but one of the anchors is a line segment that the pivot can slide in
boxOffset = cpv(160, -240);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
cpSpaceAddConstraint(space, cpGrooveJointNew(body1, body2, cpv(30,30), cpv(30,-30), cpv(-30,0)));
// Damped Springs
boxOffset = cpv(-320, -120);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
cpSpaceAddConstraint(space, cpDampedSpringNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 5.0f, 0.3f));
// Damped Rotary Springs
boxOffset = cpv(-160, -120);
body1 = addBar(posA, boxOffset);
body2 = addBar(posB, boxOffset);
// Add some pin joints to hold the circles in place.
cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A));
cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B));
cpSpaceAddConstraint(space, cpDampedRotarySpringNew(body1, body2, 0.0f, 3000.0f, 60.0f));
// Rotary Limit Joint
boxOffset = cpv(0, -120);
body1 = addLever(posA, boxOffset);
body2 = addLever(posB, boxOffset);
// Add some pin joints to hold the circles in place.
cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A));
cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B));
// Hold their rotation within 90 degrees of each other.
cpSpaceAddConstraint(space, cpRotaryLimitJointNew(body1, body2, (cpFloat)-M_PI_2, (cpFloat)M_PI_2));
// Ratchet Joint - A rotary ratchet, like a socket wrench
boxOffset = cpv(160, -120);
body1 = addLever(posA, boxOffset);
body2 = addLever(posB, boxOffset);
// Add some pin joints to hold the circles in place.
cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A));
cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B));
// Ratchet every 90 degrees
cpSpaceAddConstraint(space, cpRatchetJointNew(body1, body2, 0.0f, (cpFloat)M_PI_2));
// Gear Joint - Maintain a specific angular velocity ratio
boxOffset = cpv(-320, 0);
body1 = addBar(posA, boxOffset);
body2 = addBar(posB, boxOffset);
// Add some pin joints to hold the circles in place.
cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A));
cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B));
// Force one to sping 2x as fast as the other
cpSpaceAddConstraint(space, cpGearJointNew(body1, body2, 0.0f, 2.0f));
// Simple Motor - Maintain a specific angular relative velocity
boxOffset = cpv(-160, 0);
body1 = addBar(posA, boxOffset);
body2 = addBar(posB, boxOffset);
// Add some pin joints to hold the circles in place.
cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A));
cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B));
// Make them spin at 1/2 revolution per second in relation to each other.
cpSpaceAddConstraint(space, cpSimpleMotorNew(body1, body2, (cpFloat)M_PI));
// Make a car with some nice soft suspension
boxOffset = cpv(0, 0);
cpBody *wheel1 = addWheel(posA, boxOffset);
cpBody *wheel2 = addWheel(posB, boxOffset);
cpBody *chassis = addChassis(cpv(80, 100), boxOffset);
cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel1, cpv(-30, -10), cpv(-30, -40), cpvzero));
cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel2, cpv( 30, -10), cpv( 30, -40), cpvzero));
cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel1, cpv(-30, 0), cpvzero, 50.0f, 20.0f, 1.5f));
cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel2, cpv( 30, 0), cpvzero, 50.0f, 20.0f, 1.5f));
return space;
}
static void
update(int ticks)
{
cpSpaceStep(space, 1.0f/60.0f);
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Joints = {
"Joints and Constraints",
NULL,
init,
update,
destroy,
};

View File

@ -1,153 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static const int image_width = 188;
static const int image_height = 35;
static const int image_row_length = 24;
static const unsigned char image_bitmap[] = {
15,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-64,15,63,-32,-2,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,31,-64,15,127,-125,-1,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,127,-64,15,127,15,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-2,
31,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,0,-4,63,-1,-32,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-8,127,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,-1,-64,0,-8,-15,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-31,-1,-64,15,-8,-32,
-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-15,-1,-64,9,-15,-32,-1,-32,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,31,-15,-1,-64,0,-15,-32,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,63,-7,-1,-64,9,-29,-32,127,-61,-16,63,15,-61,-1,-8,31,-16,15,-8,126,7,-31,
-8,31,-65,-7,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13,
-4,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13,
-2,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
-2,63,-33,-1,-1,-32,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
-1,63,-33,-1,-1,-16,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13,
-1,63,-49,-1,-1,-8,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
-1,-65,-49,-1,-1,-4,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
-1,-65,-57,-1,-1,-2,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13,
-1,-1,-57,-1,-1,-1,9,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
-1,-61,-1,-1,-1,-119,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
-1,-61,-1,-1,-1,-55,-49,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1,
-1,-63,-1,-1,-1,-23,-49,-32,127,-57,-1,-1,-97,-25,-1,-1,63,-1,-1,-4,-1,15,-13,
-1,-1,-63,-1,-1,-1,-16,-49,-32,-1,-25,-1,-1,-97,-25,-1,-1,63,-33,-5,-4,-1,15,
-13,-1,-1,-64,-1,-9,-1,-7,-49,-32,-1,-25,-8,127,-97,-25,-1,-1,63,-33,-5,-4,-1,
15,-13,-1,-1,-64,-1,-13,-1,-32,-49,-32,-1,-25,-8,127,-97,-25,-1,-2,63,-49,-13,
-4,-1,15,-13,-1,-1,-64,127,-7,-1,-119,-17,-15,-1,-25,-8,127,-97,-25,-1,-2,63,
-49,-13,-4,-1,15,-13,-3,-1,-64,127,-8,-2,15,-17,-1,-1,-25,-8,127,-97,-25,-1,
-8,63,-49,-13,-4,-1,15,-13,-3,-1,-64,63,-4,120,0,-17,-1,-1,-25,-8,127,-97,-25,
-8,0,63,-57,-29,-4,-1,15,-13,-4,-1,-64,63,-4,0,15,-17,-1,-1,-25,-8,127,-97,
-25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,-1,-64,31,-2,0,0,103,-1,-1,-57,-8,127,-97,
-25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,127,-64,31,-2,0,15,103,-1,-1,-57,-8,127,
-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,127,-64,15,-8,0,0,55,-1,-1,-121,-8,
127,-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,63,-64,15,-32,0,0,23,-1,-2,3,-16,
63,15,-61,-16,0,31,-127,-127,-8,31,-1,-127,-8,31,-128,7,-128,0,0
};
static inline int
get_pixel(int x, int y)
{
return (image_bitmap[(x>>3) + y*image_row_length]>>(~x&0x7)) & 1;
}
static cpSpace *space;
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpShape *
make_ball(cpFloat x, cpFloat y)
{
cpBody *body = cpBodyNew(1.0f, INFINITY);
body->p = cpv(x, y);
cpShape *shape = cpCircleShapeNew(body, 0.95f, cpvzero);
shape->e = 0.0f; shape->u = 0.0f;
return shape;
}
static cpSpace *
init(void)
{
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 2.0f, 10000);
cpSpaceResizeStaticHash(space, 2.0f, 10000);
space->iterations = 1;
cpBody *body;
cpShape *shape;
for(int y=0; y<image_height; y++){
for(int x=0; x<image_width; x++){
if(!get_pixel(x, y)) continue;
cpFloat x_jitter = 0.05f*frand();
cpFloat y_jitter = 0.05f*frand();
shape = make_ball(2*(x - image_width/2 + x_jitter), 2*(image_height/2 - y + y_jitter));
cpSpaceAddBody(space, shape->body);
cpSpaceAddShape(space, shape);
}
}
body = cpSpaceAddBody(space, cpBodyNew(INFINITY, INFINITY));
body->p = cpv(-1000.0f, -10.0f);
body->v = cpv(400.0f, 0.0f);
shape = cpSpaceAddShape(space, cpCircleShapeNew(body, 8.0f, cpvzero));
shape->e = 0.0f; shape->u = 0.0f;
shape->layers = NOT_GRABABLE_MASK;
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
drawSpaceOptions draw_options = {
0, 0, 0, 2.0f, 3.0f, 0.0f,
};
chipmunkDemo LogoSmash = {
"Logo Smash",
&draw_options,
init,
update,
destroy,
};

View File

@ -1,503 +0,0 @@
// This Demo was written by Juan Pablo Carbajal. Nov 2008.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
#include "CCCommon.h"
#define WIDTH 600
#define HEIGHT 400
#define SINGMAX 10 // Maximum number of singularities per body
#define NMAG 10 // Number of magnets
#define NCHG 10 // Number of charged bodies
#define NMIX 10 // Number of charged magnets
#define COU_MKS 8.987551787e9 // Some physical constants
#define MAG_MKS 1e-7
// Prototypes
struct DataforForce;
typedef void (*SingForceFunc)(struct DataforForce* data);
void make_mix(cpVect p, cpFloat ang, cpFloat mag,cpFloat chg);
// Structures
// Singularities
typedef struct ActorSingularity{
// Number of singularities
int Nsing;
// Value of the singularities
cpFloat value[SINGMAX];
// Type of the singularities
char type[SINGMAX][100];
// Global position of the singularities
cpVect Gpos[SINGMAX];
// Local position of the singularities
cpVect position[SINGMAX];
// Angle of the singularities measured in the body axes
cpFloat angle[SINGMAX];
// Angle of the singularities measured from x
cpFloat Gangle[SINGMAX];
// Force function
SingForceFunc force_func[SINGMAX];
// Force function
SingForceFunc torque_func[SINGMAX];
}Sing;
// Data for the force functions
typedef struct DataforForce{
//Everything in global coordinates
// Position of the source
cpVect p0;
// Observed position
cpVect p;
// Relative position source-observed
cpVect relp;
// distance, disntace^2, ditance ^3
cpFloat r[3];
// angle of the source
cpFloat ang0;
// angle of the observed singularity
cpFloat ang;
// Foce value
cpVect F;
// Torque value
cpFloat T;
}ForceData;
// Global Varibales
static cpSpace *space;
// **** Forces ****** //
// Calculate the forces between two bodies. all this functions requieres
// a pointer to an structure with the necessary fields.
// forces between charges
static void
CoulombForce(ForceData* data){
data->F=cpvmult(cpvnormalize(data->relp),(cpFloat)COU_MKS/data->r[1]);
}
// forces between magnets
static void
MagDipoleForce(ForceData* data){
static cpFloat phi,alpha,beta,Fr,Fphi;
// Angle of the relative position vector
phi=cpvtoangle(data->relp);
alpha=data->ang0;
beta=data->ang;
alpha =phi - alpha;
beta = phi - beta;
// Components in polar coordinates
Fr=(2.0e0f*cosf(alpha)*cosf(beta) - sinf(alpha)*sinf(beta));
Fphi=sinf(alpha+beta);
// printf("%g %g %g %g %g\n",phi,alpha,beta,Fphi);
// Cartesian coordinates
data->F=cpv(Fr*cosf(phi)-Fphi*sinf(phi),Fr*sinf(phi)+Fphi*cosf(phi));
data->F=cpvmult(data->F,-3.e0f*(cpFloat)MAG_MKS/(data->r[1]*data->r[1]));
}
static void
MagDipoleTorque(ForceData* data){
static cpFloat phi,alpha,beta;
phi=cpvtoangle(data->relp);
alpha=data->ang0;
beta=data->ang;
alpha =phi - alpha;
beta = phi - beta;
// Torque. Though we could use a component of F to save some space,
// we use another variables for the sake of clarity.
data->T=((cpFloat)MAG_MKS/data->r[2])*(3.0e0f*cosf(alpha)*sinf(beta) + sinf(alpha-beta));
}
// ******* //
// This function fills the data structure for the force functions
// The structure Sing has the information about the singularity (charge or magnet)
static void
FillForceData(Sing* source,int inds, Sing* obs,int indo, ForceData* data)
{
// Global Position and orientation of the source singularity
data->p0=source->Gpos[inds];
data->ang0=source->Gangle[inds];
// Global Position and orientation of the observed singularity
data->p=obs->Gpos[indo];
data->ang=obs->Gangle[indo];
// Derived magnitudes
data->relp=cpvsub(data->p,data->p0); //Relative position
data->r[0]=cpvlength(data->relp); // Distance
data->r[1]=cpvlengthsq(data->relp); // Square Distance
data->r[2]=data->r[0]*data->r[1]; // Cubic distance
source->force_func[inds](data); // The value of the force
data->F= cpvmult(data->F,source->value[inds]*obs->value[indo]);
}
// Calculation of the interaction
static void
LRangeForceApply(cpBody *a, cpBody *b){
Sing* aux = (Sing*)a->data;
Sing* aux2 = (Sing*)b->data;
cpVect delta;
// General data needed to calculate interaction
static ForceData fdata;
fdata.F=cpvzero;
// Calculate the forces between the charges of different bodies
for (int i=0; i<aux->Nsing; i++)
{
for (int j=0; j<aux2->Nsing; j++)
{
if(!strcmp(aux->type[i],aux2->type[j]))
{
//printf("%s %s\n",aux->type[i],aux2->type[j]);
FillForceData (aux2,j,aux,i,&fdata);
//Force applied to body A
delta=cpvsub(aux->Gpos[i], a->p);
cpBodyApplyForce(a,fdata.F, delta);
if(aux->torque_func[i] != NULL)
{
//Torque on A
aux->torque_func[i](&fdata);
a->t += aux->value[i]*aux2->value[j]*fdata.T;
}
}
}
}
}
// function for the integration of the positions
// The following functions are variations to the starndrd integration in Chipmunk
// you can go ack to the standard ones by doing the appropiate changes.
static void
ChargedBodyUpdatePositionVerlet(cpBody *body, cpFloat dt)
{
// Long range interaction
cpArray *bodies = space->bodies;
static cpBody* B;
Sing* aux=(Sing*)body->data;
Sing* aux2;
// General data needed to calculate interaction
static ForceData fdata;
fdata.F=cpvzero;
for(int i=0; i< bodies->num; i++)
{
B=(cpBody*)bodies->arr[i];
aux2=(Sing*)B->data;
if(B != body)
{
// Calculate the forces between the singularities of different bodies
LRangeForceApply(body, B);
}
}
cpVect dp = cpvmult(cpvadd(body->v, body->v_bias), dt);
dp = cpvadd(dp,cpvmult(cpvmult(body->f, body->m_inv), 0.5e0f*dt*dt));
body->p = cpvadd(body->p, dp);
cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt
+ 0.5f*body->t*body->i_inv*dt*dt);
// Update position of the singularities
aux = (Sing*)body->data;
for (int i=0; i<aux->Nsing; i++)
{
aux->Gpos[i]=cpvadd(body->p,cpvrotate(cpv(aux->position[i].x,
aux->position[i].y), body->rot));
aux->Gangle[i]= aux->angle[i] + body->a;
}
body->v_bias = cpvzero;
body->w_bias = 0.0f;
}
// function for the integration of the velocities
static void
ChargedBodyUpdateVelocityVerlet(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
body->v = cpvadd(body->v, cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), 0.5e0f*dt));
body->w = body->w + body->t*body->i_inv*0.5e0f*dt;
body->f = cpvzero;
body->t = 0.0e0f;
// Long range interaction
cpArray *bodies = space->bodies;
static cpBody* B;
// General data needed to calculate interaction
static ForceData fdata;
fdata.F=cpvzero;
for(int i=0; i< bodies->num; i++)
{
B=(cpBody*)bodies->arr[i];
if(B != body)
{
// Calculate the forces between the singularities of different bodies
LRangeForceApply(body, B);
}
}
body->v = cpvadd(cpvmult(body->v,damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), 0.5e0f*dt));
body->w = body->w*damping + body->t*body->i_inv*0.5e0f*dt;
}
static void
update(int ticks)
{
int steps = 10;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
cpArray *bodies = space->bodies;
for(int i=0; i< bodies->num; i++)
cpBodyResetForces((cpBody*)bodies->arr[i]);
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static void
make_mag(cpVect p, cpFloat ang, cpFloat mag)
{
int nverts=6;
cpVect verts[] = {
cpv(-10,-10),
cpv(-10, 10),
cpv( 10, 10),
cpv( 15, 5),
cpv( 15, -5),
cpv( 10,-10)
};
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, nverts, verts, cpvzero));
body->p = p;
body->v = cpvzero;
cpBodySetAngle(body, ang);
body->w = 0.0e0f;
// Load the singularities
Sing *magnet=(Sing*)cpmalloc(sizeof(Sing));
magnet->Nsing=1;
magnet->value[0]=mag;
sprintf(magnet->type[0],"magdipole");
// The position and angle could be different form the one of the body
magnet->position[0]=cpvzero;
magnet->Gpos[0]=cpvadd(p,magnet->position[0]);
magnet->angle[0]=0.0f;
magnet->Gangle[0]=ang;
magnet->force_func[0]=MagDipoleForce;
magnet->torque_func[0]=MagDipoleTorque;
body->data=magnet;
body->position_func=ChargedBodyUpdatePositionVerlet;
body->velocity_func=ChargedBodyUpdateVelocityVerlet;
cpSpaceAddBody(space, body);
cpShape *shape = cpPolyShapeNew(body, nverts, verts, cpvzero);
shape->e = 0.0f; shape->u = 0.7f;
cpSpaceAddShape(space, shape);
}
static void
make_charged(cpVect p, cpFloat chg)
{
int nverts=4;
cpVect verts[] = {
cpv(-10,-10),
cpv(-10, 10),
cpv( 10, 10),
cpv( 10,-10)
};
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, nverts, verts, cpvzero));
body->p = p;
body->v = cpvzero;
cpBodySetAngle(body, 0);
body->w = 0.0e0f;
// Load the singularities
Sing *charge=(Sing*)cpmalloc(sizeof(Sing));;
charge->Nsing=1;
charge->value[0]=chg;
sprintf(charge->type[0],"electrical");
// The position and angle could be different form the one of the body
charge->position[0]=cpvzero;
charge->Gpos[0]=cpvadd(p,charge->position[0]);
charge->Gangle[0]=0;
charge->force_func[0]=CoulombForce;
charge->torque_func[0]=NULL;
body->data=charge;
body->position_func=ChargedBodyUpdatePositionVerlet;
body->velocity_func=ChargedBodyUpdateVelocityVerlet;
cpSpaceAddBody(space, body);
cpShape *shape = cpPolyShapeNew(body, nverts, verts, cpvzero);
shape->e = 0.0f; shape->u = 0.7f;
cpSpaceAddShape(space, shape);
}
void
make_mix(cpVect p, cpFloat ang, cpFloat mag,cpFloat chg)
{
int nverts=5;
cpVect verts[] = {
cpv(-10,-10),
cpv(-10, 10),
cpv( 10, 10),
cpv( 20, 0),
cpv( 10,-10)
};
cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, nverts, verts, cpvzero));
body->p = p;
body->v = cpvzero;
cpBodySetAngle(body, ang);
body->w = 0.0e0f;
// Load the singularities
Sing *mix=(Sing*)cpmalloc(sizeof(Sing));;
mix->Nsing=2;
mix->value[0]=mag;
mix->value[1]=chg;
sprintf(mix->type[0],"magdipole");
sprintf(mix->type[1],"electrical");
// The position and angle could be different form the one of the body
mix->position[0]=cpvzero;
mix->Gpos[0]=cpvadd(p,mix->position[0]);
mix->position[1]=cpvzero;
mix->Gpos[1]=cpvadd(p,mix->position[1]);
mix->Gangle[0]=ang;
mix->Gangle[1]=ang;
mix->force_func[0]=MagDipoleForce;
mix->force_func[1]=CoulombForce;
mix->torque_func[0]=MagDipoleTorque;
mix->torque_func[1]=NULL;
body->data=mix;
body->position_func=ChargedBodyUpdatePositionVerlet;
body->velocity_func=ChargedBodyUpdateVelocityVerlet;
cpSpaceAddBody(space, body);
cpShape *shape = cpPolyShapeNew(body, nverts, verts, cpvzero);
shape->e = 0.0f; shape->u = 0.7f;
cpSpaceAddShape(space, shape);
}
static cpSpace*
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 5;
space->gravity = cpvzero; //cpv(0,-100);
cpSpaceResizeActiveHash(space, 30.0f, 2999);
// Screen border
/* shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f);
shape->e = 1.0; shape->u = 1.0;
cpSpaceAddShape(space, shape);
// Reference line
// Does not collide with other objects, we just want to draw it.
shape = cpSegmentShapeNew(staticBody, cpv(-320,0), cpv(320,0), 0.0f);
shape->collision_type = 1;
cpSpaceAddShape(space, shape);
// Add a collision pair function to filter collisions
cpSpaceAddCollisionPairFunc(space, 0, 1, NULL, NULL);
*/
srand((unsigned int) time(NULL));
cpVect p;
cpFloat ang;
// Create magnets
for(int i=0; i<NMAG; i++)
{
p.x=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*WIDTH/2.0f;
p.y=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*HEIGHT/2.0f;
ang=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*3.1415f;
make_mag(p, ang,1.0e7f);
}
// Create charged objects
for(int i=0; i<NCHG; i++)
{
p.x=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*WIDTH/2.0f;
p.y=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*HEIGHT/2.0f;
ang=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*3.1415f;
make_charged(p, (float)(1.0e-3) *powf(-1.0f,i%2));
}
// Create charged magnets objects
for(int i=0; i<NMIX; i++)
{
p.x=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*WIDTH/2.0f;
p.y=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*HEIGHT/2.0f;
ang=(2.0e0f*rand()/((cpFloat)RAND_MAX) - 1.0e0f)*3.1415f;
make_mix(p, ang,1.0e7f*powf(-1.0f,i%2), (float)(1.0e-3) *powf(-1.0f,i%2));
}
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo MagnetsElectric = {
"Magnets and Electric Charges (By: Juan Pablo Carbajal)",
NULL,
init,
update,
destroy,
};

View File

@ -1,131 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
typedef struct OneWayPlatform {
cpVect n; // direction objects may pass through
cpArray *passThruList; // list of objects passing through
} OneWayPlatform;
static OneWayPlatform platformInstance;
static cpBool
preSolve(cpArbiter *arb, cpSpace *space, void *ignore)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
OneWayPlatform *platform = (OneWayPlatform *)a->data;
if(cpvdot(cpArbiterGetNormal(arb, 0), platform->n) < 0){
cpArbiterIgnore(arb);
return cpFalse;
}
return cpTrue;
}
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 10;
space->gravity = cpv(0, -100);
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
// Add our one way segment
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-100), cpv(160,-100), 10.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->collision_type = 1;
shape->layers = NOT_GRABABLE_MASK;
// We'll use the data pointer for the OneWayPlatform struct
platformInstance.n = cpv(0, 1); // let objects pass upwards
platformInstance.passThruList = cpArrayNew(0);
shape->data = &platformInstance;
// Add a ball to make things more interesting
cpFloat radius = 15.0f;
body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
body->p = cpv(0, -200);
body->v = cpv(0, 170);
shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
shape->e = 0.0f; shape->u = 0.9f;
shape->collision_type = 2;
cpSpaceAddCollisionHandler(space, 1, 2, NULL, preSolve, NULL, NULL, NULL);
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
cpArrayFree(platformInstance.passThruList);
}
chipmunkDemo OneWay = {
"One Way Platforms",
NULL,
init,
update,
destroy,
};

View File

@ -1,143 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpBody *planetBody;
static cpFloat gravityStrength = 5.0e6f;
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
// Update the static body spin so that it looks like it's rotating.
cpBodyUpdatePosition(planetBody, dt);
}
}
static void
planetGravityVelocityFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
// Gravitational acceleration is proportional to the inverse square of
// distance, and directed toward the origin. The central planet is assumed
// to be massive enough that it affects the satellites but not vice versa.
cpVect p = body->p;
cpFloat sqdist = cpvlengthsq(p);
cpVect g = cpvmult(p, -gravityStrength / (sqdist * cpfsqrt(sqdist)));
cpBodyUpdateVelocity(body, g, damping, dt);
}
static cpVect
rand_pos(cpFloat radius)
{
cpVect v;
do {
v = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
} while(cpvlength(v) < 85.0f);
return v;
}
static void
add_box()
{
const cpFloat size = 10.0f;
const cpFloat mass = 1.0f;
cpVect verts[] = {
cpv(-size,-size),
cpv(-size, size),
cpv( size, size),
cpv( size,-size),
};
cpFloat radius = cpvlength(cpv(size, size));
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts, cpvzero)));
body->velocity_func = planetGravityVelocityFunc;
body->p = rand_pos(radius);
// Set the box's velocity to put it into a circular orbit from its
// starting position.
cpFloat r = cpvlength(body->p);
cpFloat v = cpfsqrt(gravityStrength / r) / r;
body->v = cpvmult(cpvperp(body->p), v);
// Set the box's angular velocity to match its orbital period and
// align its initial angle with its position.
body->w = v;
cpBodySetAngle(body, cpfatan2(body->p.y, body->p.x));
cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 4, verts, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
}
static cpSpace *
init(void)
{
planetBody = cpBodyNew(INFINITY, INFINITY);
planetBody->w = 0.2f;
cpResetShapeIdCounter();
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 30.0f, 10000);
space->iterations = 20;
for(int i=0; i<30; i++)
add_box();
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(planetBody, 70.0f, cpvzero));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
return space;
}
static void
destroy(void)
{
cpBodyFree(planetBody);
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Planet = {
"Planet",
NULL,
init,
update,
destroy,
};

View File

@ -1,225 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
typedef struct PlayerStruct {
cpFloat u;
cpShape *shape;
cpVect groundNormal;
cpArray *groundShapes;
} PlayerStruct;
PlayerStruct playerInstance;
static cpBool
begin(cpArbiter *arb, cpSpace *space, void *ignore)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
PlayerStruct *player = (PlayerStruct *)a->data;
cpVect n = cpvneg(cpArbiterGetNormal(arb, 0));
if(n.y > 0.0f){
cpArrayPush(player->groundShapes, b);
}
return cpTrue;
}
static cpBool
preSolve(cpArbiter *arb, cpSpace *space, void *ignore)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
PlayerStruct *player = (PlayerStruct *)a->data;
if(cpArbiterIsFirstContact(arb)){
a->u = player->u;
// pick the most upright jump normal each frame
cpVect n = cpvneg(cpArbiterGetNormal(arb, 0));
if(n.y >= player->groundNormal.y){
player->groundNormal = n;
}
}
return cpTrue;
}
static void
separate(cpArbiter *arb, cpSpace *space, void *ignore)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
PlayerStruct *player = (PlayerStruct *)a->data;
cpArrayDeleteObj(player->groundShapes, b);
if(player->groundShapes->num == 0){
a->u = 0.0f;
player->groundNormal = cpvzero;
}
}
static void
playerUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
cpBodyUpdateVelocity(body, gravity, damping, dt);
body->v.y = cpfmax(body->v.y, -700);
body->v.x = cpfclamp(body->v.x, -400, 400);
}
static void
update(int ticks)
{
static int lastJumpState = 0;
int jumpState = (arrowDirection.y > 0.0f);
cpBody *body = playerInstance.shape->body;
cpVect groundNormal = playerInstance.groundNormal;
if(groundNormal.y > 0.0f){
playerInstance.shape->surface_v = cpvmult(cpvperp(groundNormal), 400.0f*arrowDirection.x);
if(arrowDirection.x) cpBodyActivate(body);
} else {
playerInstance.shape->surface_v = cpvzero;
}
// apply jump
if(jumpState && !lastJumpState && cpvlengthsq(groundNormal)){
// body->v = cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.5f), 500.0f);
body->v = cpvadd(body->v, cpvmult(cpvslerp(groundNormal, cpv(0.0f, 1.0f), 0.75f), 500.0f));
cpBodyActivate(body);
}
if(playerInstance.groundShapes->num == 0){
cpFloat air_accel = body->v.x + arrowDirection.x*(2000.0f);
body->f.x = body->m*air_accel;
// body->v.x = cpflerpconst(body->v.x, 400.0f*arrowDirection.x, 2000.0f/60.0f);
}
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
lastJumpState = jumpState;
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 10;
space->gravity = cpv(0, -1500);
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
// add some other segments to play with
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-200), cpv(-220,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(320,-200), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(200,-240), cpv(320,-100), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-80), cpv(200,-80), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape->collision_type = 2;
// Set up the player
cpFloat radius = 15.0f;
body = cpSpaceAddBody(space, cpBodyNew(10.0f, INFINITY));
body->p = cpv(0, -220);
body->velocity_func = playerUpdateVelocity;
shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
shape->e = 0.0f; shape->u = 2.0f;
shape->collision_type = 1;
playerInstance.u = shape->u;
playerInstance.shape = shape;
playerInstance.groundShapes = cpArrayNew(0);
shape->data = &playerInstance;
cpSpaceAddCollisionHandler(space, 1, 2, begin, preSolve, NULL, separate, NULL);
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
cpArrayFree(playerInstance.groundShapes);
}
chipmunkDemo Player = {
"Player",
NULL,
init,
update,
destroy,
};

View File

@ -1,122 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
// Iterate over all of the bodies and reset the ones that have fallen offscreen.
static void
eachBody(cpBody *body, void *unused)
{
if(body->p.y < -260 || cpfabs(body->p.x) > 340){
cpFloat x = rand()/(cpFloat)RAND_MAX*640 - 320;
body->p = cpv(x, 260);
}
}
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
cpSpaceEachBody(space, &eachBody, NULL);
}
}
#define NUM_VERTS 5
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 5;
space->gravity = cpv(0, -100);
cpSpaceResizeStaticHash(space, 40.0f, 999);
cpSpaceResizeActiveHash(space, 30.0f, 2999);
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
// Create vertexes for a pentagon shape.
cpVect verts[NUM_VERTS];
for(int i=0; i<NUM_VERTS; i++){
cpFloat angle = -2*(cpFloat)M_PI*i/((cpFloat) NUM_VERTS);
verts[i] = cpv(10*cosf(angle), 10*sinf(angle));
}
// Vertexes for a triangle shape.
cpVect tris[] = {
cpv(-15,-15),
cpv( 0, 10),
cpv( 15,-15),
};
// Create the static triangles.
for(int i=0; i<9; i++){
for(int j=0; j<6; j++){
cpFloat stagger = (j%2)*40;
cpVect offset = cpv(i*80 - 320 + stagger, j*70 - 240);
shape = cpSpaceAddShape(space, cpPolyShapeNew(staticBody, 3, tris, offset));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
}
}
// Add lots of pentagons.
for(int i=0; i<300; i++){
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, NUM_VERTS, verts, cpvzero)));
cpFloat x = rand()/(cpFloat)RAND_MAX*640 - 320;
body->p = cpv(x, 350);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, NUM_VERTS, verts, cpvzero));
shape->e = 0.0f; shape->u = 0.4f;
}
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Plink = {
"Plink",
NULL,
init,
update,
destroy,
};

View File

@ -1,186 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpConstraint *motor;
#define numBalls 5
static cpBody *balls[numBalls];
static void
update(int ticks)
{
cpFloat coef = (2.0f + arrowDirection.y)/3.0f;
cpFloat rate = arrowDirection.x*30.0f*coef;
cpSimpleMotorSetRate(motor, rate);
motor->maxForce = (rate ? 1000000.0f : 0.0f);
int steps = 2;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
for(int i=0; i<numBalls; i++){
cpBody *ball = balls[i];
if(ball->p.x > 320.0f){
ball->v = cpvzero;
ball->p = cpv(-224.0f, 200.0f);
}
}
}
}
static cpBody *
add_ball(cpVect pos)
{
cpBody *body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 30, 0, cpvzero)));
body->p = pos;
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, 30, cpvzero));
shape->e = 0.0f; shape->u = 0.5f;
return body;
}
static cpSpace *
init(void)
{
space = cpSpaceNew();
space->gravity = cpv(0, -600);
cpBody *staticBody = &space->staticBody;
cpShape *shape;
// beveling all of the line segments slightly helps prevent things from getting stuck on cracks
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-256,300), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-192,0), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,0), cpv(-192, -64), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,-64), cpv(-128,144), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,80), cpv(-192,176), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,176), cpv(-128,240), 2.0f));
shape->e = 0.0f; shape->u = 0.0f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,144), cpv(192,64), 2.0f));
shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
shape->layers = NOT_GRABABLE_MASK;
cpVect verts[] = {
cpv(-30,-80),
cpv(-30, 80),
cpv( 30, 64),
cpv( 30,-80),
};
cpBody *plunger = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
plunger->p = cpv(-160,-80);
shape = cpSpaceAddShape(space, cpPolyShapeNew(plunger, 4, verts, cpvzero));
shape->e = 1.0f; shape->u = 0.5f; shape->layers = 1;
// add balls to hopper
for(int i=0; i<numBalls; i++)
balls[i] = add_ball(cpv(-224 + i,80 + 64*i));
// add small gear
cpBody *smallGear = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 80, 0, cpvzero)));
smallGear->p = cpv(-160,-160);
cpBodySetAngle(smallGear, (cpFloat)-M_PI_2);
shape = cpSpaceAddShape(space, cpCircleShapeNew(smallGear, 80.0f, cpvzero));
shape->layers = 0;
cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, smallGear, cpv(-160,-160), cpvzero));
// add big gear
cpBody *bigGear = cpSpaceAddBody(space, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 160, 0, cpvzero)));
bigGear->p = cpv(80,-160);
cpBodySetAngle(bigGear, (cpFloat)M_PI_2);
shape = cpSpaceAddShape(space, cpCircleShapeNew(bigGear, 160.0f, cpvzero));
shape->layers = 0;
cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, bigGear, cpv(80,-160), cpvzero));
// connect the plunger to the small gear.
cpSpaceAddConstraint(space, cpPinJointNew(smallGear, plunger, cpv(80,0), cpv(0,0)));
// connect the gears.
cpSpaceAddConstraint(space, cpGearJointNew(smallGear, bigGear, (cpFloat)-M_PI_2, -2.0f));
// feeder mechanism
cpFloat bottom = -300.0f;
cpFloat top = 32.0f;
cpBody *feeder = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForSegment(1.0f, cpv(-224.0f, bottom), cpv(-224.0f, top))));
feeder->p = cpv(-224, (bottom + top)/2.0f);
cpFloat len = top - bottom;
cpSpaceAddShape(space, cpSegmentShapeNew(feeder, cpv(0.0f, len/2.0f), cpv(0.0f, -len/2.0f), 20.0f));
cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, feeder, cpv(-224.0f, bottom), cpv(0.0f, -len/2.0f)));
cpVect anchr = cpBodyWorld2Local(feeder, cpv(-224.0f, -160.0f));
cpSpaceAddConstraint(space, cpPinJointNew(feeder, smallGear, anchr, cpv(0.0f, 80.0f)));
// motorize the second gear
motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(staticBody, bigGear, 3.0f));
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Pump = {
"Pump",
NULL,
init,
update,
destroy,
};

View File

@ -1,106 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static void
update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 30;
cpSpaceResizeStaticHash(space, 40.0f, 1000);
cpSpaceResizeActiveHash(space, 40.0f, 1000);
space->gravity = cpv(0, -100);
space->sleepTimeThreshold = 0.5f;
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
// Add lots of boxes.
for(int i=0; i<14; i++){
for(int j=0; j<=i; j++){
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForBox(1.0f, 30.0f, 30.0f)));
body->p = cpv(j*32 - i*16, 300 - i*32);
shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 30.0f, 30.0f));
shape->e = 0.0f; shape->u = 0.8f;
}
}
// Add a ball to make things more interesting
cpFloat radius = 15.0f;
body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
body->p = cpv(0, -240 + radius+5);
shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
shape->e = 0.0f; shape->u = 0.9f;
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo PyramidStack = {
"Pyramid Stack",
NULL,
init,
update,
destroy,
};

View File

@ -1,138 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static void
update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++)
cpSpaceStep(space, dt);
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 30;
cpSpaceResizeActiveHash(space, 30.0f, 2999);
cpSpaceResizeStaticHash(space, 30.0f, 999);
space->gravity = cpv(0, -300);
space->sleepTimeThreshold = 0.5f;
cpBody *body;
cpShape *shape;
// Vertexes for the dominos.
int num = 4;
cpVect verts[] = {
cpv(-3,-20),
cpv(-3, 20),
cpv( 3, 20),
cpv( 3,-20),
};
// Add a floor.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(&space->staticBody, cpv(-600,-240), cpv(600,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
// Shared friction constant.
cpFloat u = 0.6f;
// Add the dominoes. Skim over this. It doesn't do anything fancy, and it's hard to follow.
int n = 9;
for(int i=1; i<=n; i++){
cpVect offset = cpv(-i*60/2.0f, (n - i)*52);
for(int j=0; j<i; j++){
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpvadd(cpv(j*60, -220), offset);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = u;
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpvadd(cpv(j*60, -197), offset);
cpBodySetAngle(body, (cpFloat)M_PI/2.0f);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = u;
if(j == (i - 1)) continue;
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpvadd(cpv(j*60 + 30, -191), offset);
cpBodySetAngle(body, (cpFloat)M_PI/2.0f);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = u;
}
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpvadd(cpv(-17, -174), offset);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = u;
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpvadd(cpv((i - 1)*60 + 17, -174), offset);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = u;
}
// Give the last domino a little tap.
// body->w = -1;
// body->v = cpv(-body->w*20, 0);
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo PyramidTopple = {
"Pyramid Topple",
NULL,
init,
update,
destroy,
};

View File

@ -1,156 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "CCCommon.h"
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
#include "chipmunk_unsafe.h"
static cpSpace *space;
extern cpVect mousePoint;
static cpShape *querySeg = NULL;
static void
update(int ticks)
{
messageString[0] = '\0';
cpVect start = cpvzero;
cpVect end = /*cpv(0, 85);//*/mousePoint;
cpVect lineEnd = end;
{
char infoString[1024];
sprintf(infoString, "Query: Dist(%f) Point%s, ", cpvdist(start, end), cpvstr(end));
strcat(messageString, infoString);
}
cpSegmentQueryInfo info = {};
if(cpSpaceSegmentQueryFirst(space, start, end, CP_ALL_LAYERS, CP_NO_GROUP, &info)){
cpVect point = cpSegmentQueryHitPoint(start, end, info);
lineEnd = cpvadd(point, cpvzero);//cpvmult(info.n, 4.0f));
char infoString[1024];
sprintf(infoString, "Segment Query: Dist(%f) Normal%s", cpSegmentQueryHitDist(start, end, info), cpvstr(info.n));
strcat(messageString, infoString);
} else {
strcat(messageString, "Segment Query (None)");
}
cpSegmentShapeSetEndpoints(querySeg, start, lineEnd);
cpShapeCacheBB(querySeg); // force it to update it's collision detection data so it will draw
// normal other stuff.
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->elasticIterations = 0;
space->iterations = 5;
cpSpaceResizeStaticHash(space, 40.0f, 999);
cpSpaceResizeActiveHash(space, 30.0f, 2999);
cpBody *staticBody = &space->staticBody;
cpShape *shape;
// add a non-collidable segment as a quick and dirty way to draw the query line
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpvzero, cpv(100.0f, 0.0f), 4.0f));
shape->layers = 0;
querySeg = shape;
{ // add a fat segment
cpFloat mass = 1.0f;
cpFloat length = 100.0f;
cpVect a = cpv(-length/2.0f, 0.0f), b = cpv(length/2.0f, 0.0f);
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
body->p = cpv(0.0f, 100.0f);
cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 20.0f));
}
{ // add a static segment
cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0, 300), cpv(300, 0), 0.0f));
}
{ // add a pentagon
cpFloat mass = 1.0f;
const int NUM_VERTS = 5;
cpVect verts[NUM_VERTS];
for(int i=0; i<NUM_VERTS; i++){
cpFloat angle = -2*(cpFloat)M_PI*i/((cpFloat) NUM_VERTS);
verts[i] = cpv(30*cosf(angle), 30*sinf(angle));
}
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, NUM_VERTS, verts, cpvzero)));
body->p = cpv(50.0f, 50.0f);
cpSpaceAddShape(space, cpPolyShapeNew(body, NUM_VERTS, verts, cpvzero));
}
{ // add a circle
cpFloat mass = 1.0f;
cpFloat r = 20.0f;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, r, cpvzero)));
body->p = cpv(100.0f, 100.0f);
cpSpaceAddShape(space, cpCircleShapeNew(body, r, cpvzero));
}
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Query = {
"Segment Query",
NULL,
init,
update,
destroy,
};

View File

@ -1,165 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
enum CollisionTypes {
BALL_TYPE,
BLOCKING_SENSOR_TYPE,
CATCH_SENSOR_TYPE,
};
typedef struct Emitter {
int queue;
int blocked;
cpVect position;
} Emitter;
static Emitter emitterInstance;
static cpBool
blockerBegin(cpArbiter *arb, cpSpace *space, void *unused)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
Emitter *emitter = (Emitter *) a->data;
emitter->blocked++;
return cpFalse; // Return values from sensors callbacks are ignored,
}
static void
blockerSeparate(cpArbiter *arb, cpSpace *space, void *unused)
{
CP_ARBITER_GET_SHAPES(arb, a, b);
Emitter *emitter = (Emitter *) a->data;
emitter->blocked--;
}
static void
postStepRemove(cpSpace *space, cpShape *shape, void *unused)
{
// cocos2d-x: bring cpSpaceRemoveShape here to avoid
// the crash on win32 platform
cpSpaceRemoveShape(space, shape);
cpSpaceRemoveBody(space, shape->body);
cpBodyFree(shape->body);
cpShapeFree(shape);
}
static cpBool
catcherBarBegin(cpArbiter *arb, cpSpace *space, void *unused)
{
cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
Emitter *emitter = (Emitter *) a->data;
emitter->queue++;
cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, b, NULL);
return cpFalse;
}
static cpFloat frand_unit(){return 2.0f*((cpFloat)rand()/(cpFloat)RAND_MAX) - 1.0f;}
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
if(!emitterInstance.blocked && emitterInstance.queue){
emitterInstance.queue--;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 15.0f, 0.0f, cpvzero)));
body->p = emitterInstance.position;
body->v = cpvmult(cpv(frand_unit(), frand_unit()), 100.0f);
cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, 15.0f, cpvzero));
shape->collision_type = BALL_TYPE;
}
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 10;
space->gravity = cpv(0, -100);
cpBody *staticBody = &space->staticBody;
cpShape *shape;
// Data structure for our ball emitter
// We'll use two sensors for it, one to see if the emitter is blocked
// a second to catch the balls and add them back to the emitter
emitterInstance.queue = 5;
emitterInstance.blocked = 0;
emitterInstance.position = cpv(0, 150);
// Create our blocking sensor, so we know when the emitter is clear to emit another ball
shape = cpSpaceAddShape(space, cpCircleShapeNew(staticBody, 15.0f, emitterInstance.position));
shape->sensor = 1;
shape->collision_type = BLOCKING_SENSOR_TYPE;
shape->data = &emitterInstance;
// Create our catch sensor to requeue the balls when they reach the bottom of the screen
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-2000, -200), cpv(2000, -200), 15.0f));
shape->sensor = 1;
shape->collision_type = CATCH_SENSOR_TYPE;
shape->data = &emitterInstance;
cpSpaceAddCollisionHandler(space, BLOCKING_SENSOR_TYPE, BALL_TYPE, blockerBegin, NULL, NULL, blockerSeparate, NULL);
cpSpaceAddCollisionHandler(space, CATCH_SENSOR_TYPE, BALL_TYPE, catcherBarBegin, NULL, NULL, NULL, NULL);
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Sensors = {
"Sensors",
NULL,
init,
update,
destroy,
};

View File

@ -1,109 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
// Init is called by the demo code to set up the demo.
static cpSpace *
init(void)
{
// Create a space, a space is a simulation world. It simulates the motions of rigid bodies,
// handles collisions between them, and simulates the joints between them.
space = cpSpaceNew();
// Lets set some parameters of the space:
// More iterations make the simulation more accurate but slower
space->iterations = 10;
// These parameters tune the efficiency of the collision detection.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpSpace
cpSpaceResizeStaticHash(space, 30.0f, 1000);
cpSpaceResizeActiveHash(space, 30.0f, 1000);
// Give it some gravity
space->gravity = cpv(0, -100);
// Create A ground segment along the bottom of the screen
// By attaching it to &space->staticBody instead of a body, we make it a static shape.
cpShape *ground = cpSegmentShapeNew(&space->staticBody, cpv(-320,-240), cpv(320,-240), 0.0f);
// Set some parameters of the shape.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpShape
ground->e = 1.0f; ground->u = 1.0f;
ground->layers = NOT_GRABABLE_MASK; // Used by the Demo mouse grabbing code
// Add the shape to the space as a static shape
// If a shape never changes position, add it as static so Chipmunk knows it only needs to
// calculate collision information for it once when it is added.
// Do not change the postion of a static shape after adding it.
cpSpaceAddShape(space, ground);
// Add a moving circle object.
cpFloat radius = 15.0f;
cpFloat mass = 10.0f;
// This time we need to give a mass and moment of inertia when creating the circle.
cpBody *ballBody = cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero));
// Set some parameters of the body:
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpBody
ballBody->p = cpv(0, -240 + radius+50);
ballBody->v = cpv(0, -20);
// Add the body to the space so it will be simulated and move around.
cpSpaceAddBody(space, ballBody);
// Add a circle shape for the ball.
// Shapes are always defined relative to the center of gravity of the body they are attached to.
// When the body moves or rotates, the shape will move with it.
// Additionally, all of the cpSpaceAdd*() functions return the thing they added so you can create and add in one go.
cpShape *ballShape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, radius, cpvzero));
ballShape->e = 0.0f; ballShape->u = 0.9f;
return space;
}
// Update is called by the demo code each frame.
static void
update(int ticks)
{
// Chipmunk allows you to use a different timestep each frame, but it works much better when you use a fixed timestep.
// An excellent article on why fixed timesteps for game logic can be found here: http://gafferongames.com/game-physics/fix-your-timestep/
cpSpaceStep(space, 1.0f/60.0f);
}
// destroy is called by the demo code to free all the memory we've allocated
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Simple = {
"Simple",
NULL,
init,
update,
destroy,
};

View File

@ -1,172 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpFloat
springForce(cpConstraint *spring, cpFloat dist)
{
cpFloat clamp = 20.0f;
return cpfclamp(cpDampedSpringGetRestLength(spring) - dist, -clamp, clamp)*cpDampedSpringGetStiffness(spring);
}
static cpConstraint *
new_spring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiff, cpFloat damp)
{
cpConstraint *spring = cpDampedSpringNew(a, b, anchr1, anchr2, restLength, stiff, damp);
cpDampedSpringSetSpringForceFunc(spring, springForce);
return spring;
}
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpBody *
add_bar(cpVect a, cpVect b, int group)
{
cpVect center = cpvmult(cpvadd(a, b), 1.0f/2.0f);
cpFloat length = cpvlength(cpvsub(b, a));
cpFloat mass = length/160.0f;
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, mass*length*length/12.0f));
body->p = center;
cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, cpvsub(a, center), cpvsub(b, center), 10.0f));
shape->group = group;
return body;
}
static cpSpace *
init(void)
{
space = cpSpaceNew();
cpBody *staticBody = &space->staticBody;
cpBody *body1 = add_bar(cpv(-240, 160), cpv(-160, 80), 1);
cpBody *body2 = add_bar(cpv(-160, 80), cpv( -80, 160), 1);
cpBody *body3 = add_bar(cpv( 0, 160), cpv( 80, 0), 0);
cpBody *body4 = add_bar(cpv( 160, 160), cpv( 240, 160), 0);
cpBody *body5 = add_bar(cpv(-240, 0), cpv(-160, -80), 2);
cpBody *body6 = add_bar(cpv(-160, -80), cpv( -80, 0), 2);
cpBody *body7 = add_bar(cpv( -80, 0), cpv( 0, 0), 2);
cpBody *body8 = add_bar(cpv( 0, -80), cpv( 80, -80), 0);
cpBody *body9 = add_bar(cpv( 240, 80), cpv( 160, 0), 3);
cpBody *body10 = add_bar(cpv( 160, 0), cpv( 240, -80), 3);
cpBody *body11 = add_bar(cpv(-240, -80), cpv(-160, -160), 4);
cpBody *body12 = add_bar(cpv(-160, -160), cpv( -80, -160), 0);
cpBody *body13 = add_bar(cpv( 0, -160), cpv( 80, -160), 0);
cpBody *body14 = add_bar(cpv( 160, -160), cpv( 240, -160), 0);
cpSpaceAddConstraint(space, cpPivotJointNew2( body1, body2, cpv( 40,-40), cpv(-40,-40)));
cpSpaceAddConstraint(space, cpPivotJointNew2( body5, body6, cpv( 40,-40), cpv(-40,-40)));
cpSpaceAddConstraint(space, cpPivotJointNew2( body6, body7, cpv( 40, 40), cpv(-40, 0)));
cpSpaceAddConstraint(space, cpPivotJointNew2( body9, body10, cpv(-40,-40), cpv(-40, 40)));
cpSpaceAddConstraint(space, cpPivotJointNew2(body11, body12, cpv( 40,-40), cpv(-40, 0)));
cpFloat stiff = 100.0f;
cpFloat damp = 0.5f;
cpSpaceAddConstraint(space, new_spring(staticBody, body1, cpv(-320, 240), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body1, cpv(-320, 80), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body1, cpv(-160, 240), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body2, cpv(-160, 240), cpv( 40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body2, cpv( 0, 240), cpv( 40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body3, cpv( 80, 240), cpv(-40, 80), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body4, cpv( 80, 240), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body4, cpv( 320, 240), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body5, cpv(-320, 80), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body9, cpv( 320, 80), cpv( 40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body10, cpv( 320, 0), cpv( 40,-40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body10, cpv( 320,-160), cpv( 40,-40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body11, cpv(-320,-160), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body12, cpv(-240,-240), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body12, cpv( 0,-240), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body13, cpv( 0,-240), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body13, cpv( 80,-240), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv( 80,-240), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv( 240,-240), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv( 320,-160), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body1, body5, cpv( 40,-40), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body1, body6, cpv( 40,-40), cpv( 40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body2, body3, cpv( 40, 40), cpv(-40, 80), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body4, cpv(-40, 80), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body4, cpv( 40,-80), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body7, cpv( 40,-80), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body7, cpv(-40, 80), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body8, cpv( 40,-80), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body3, body9, cpv( 40,-80), cpv(-40,-40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body4, body9, cpv( 40, 0), cpv( 40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body5, body11, cpv(-40, 40), cpv(-40, 40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body5, body11, cpv( 40,-40), cpv( 40,-40), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body7, body8, cpv( 40, 0), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body8, body12, cpv(-40, 0), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body8, body13, cpv(-40, 0), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body8, body13, cpv( 40, 0), cpv( 40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring( body8, body14, cpv( 40, 0), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(body10, body14, cpv( 40,-40), cpv(-40, 0), 0.0f, stiff, damp));
cpSpaceAddConstraint(space, new_spring(body10, body14, cpv( 40,-40), cpv(-40, 0), 0.0f, stiff, damp));
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Springies = {
"Springies",
NULL,
init,
update,
destroy,
};

View File

@ -1,153 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
extern cpVect mousePoint;
static cpSpace *space;
static cpBody *tankBody, *tankControlBody;
static void
update(int ticks)
{
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
// turn the control body based on the angle relative to the actual body
cpVect mouseDelta = cpvsub(mousePoint, tankBody->p);
cpFloat turn = cpvtoangle(cpvunrotate(tankBody->rot, mouseDelta));
cpBodySetAngle(tankControlBody, tankBody->a - turn);
// drive the tank towards the mouse
if(cpvnear(mousePoint, tankBody->p, 30.0f)){
tankControlBody->v = cpvzero; // stop
} else {
cpFloat direction = (cpvdot(mouseDelta, tankBody->rot) > 0.0f ? 1.0f : -1.0f);
tankControlBody->v = cpvrotate(tankBody->rot, cpv(30.0f*direction, 0.0f));
}
cpSpaceStep(space, dt);
}
}
static cpBody *
add_box(cpFloat size, cpFloat mass)
{
cpVect verts[] = {
cpv(-size,-size),
cpv(-size, size),
cpv( size, size),
cpv( size,-size),
};
cpFloat radius = cpvlength(cpv(size, size));
cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts, cpvzero)));
body->p = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 4, verts, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
return body;
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 30.0f, 1000);
space->iterations = 10;
space->sleepTimeThreshold = 0.5f;
cpBody *staticBody = &space->staticBody;
cpShape *shape;
// Create segments around the edge of the screen.
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
for(int i=0; i<50; i++){
cpBody *body = add_box(10.0f, 1.0f);
cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, body, cpvzero, cpvzero));
pivot->biasCoef = 0.0f; // disable joint correction
pivot->maxForce = 1000.0f; // emulate linear friction
cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(staticBody, body, 0.0f, 1.0f));
gear->biasCoef = 0.0f; // disable joint correction
gear->maxForce = 5000.0f; // emulate angular friction
}
// We joint the tank to the control body and control the tank indirectly by modifying the control body.
tankControlBody = cpBodyNew(INFINITY, INFINITY);
tankBody = add_box(15.0f, 10.0f);
cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(tankControlBody, tankBody, cpvzero, cpvzero));
pivot->biasCoef = 0.0f; // disable joint correction
pivot->maxForce = 10000.0f; // emulate linear friction
cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(tankControlBody, tankBody, 0.0f, 1.0f));
gear->biasCoef = 1.0f; // limit angular correction rate
gear->maxBias = 1.0f; // limit angular correction rate
gear->maxForce = 500000.0f; // emulate angular friction
return space;
}
static void
destroy(void)
{
cpBodyFree(tankControlBody);
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Tank = {
"Tank",
NULL,
init,
update,
destroy,
};

View File

@ -1,180 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
/*
* The previous WalkBot demo I designed was fairly disappointing, so I implemented
* the mechanism that Theo Jansen uses in his kinetic sculptures. Brilliant.
* Read more here: http://en.wikipedia.org/wiki/Theo_Jansen
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpConstraint *motor;
static void
update(int ticks)
{
cpFloat coef = (2.0f + arrowDirection.y)/3.0f;
cpFloat rate = arrowDirection.x*10.0f*coef;
cpSimpleMotorSetRate(motor, rate);
motor->maxForce = (rate) ? 100000.0f : 0.0f;
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpFloat seg_radius = 3.0f;
static void
make_leg(cpFloat side, cpFloat offset, cpBody *chassis, cpBody *crank, cpVect anchor)
{
cpVect a, b;
cpShape *shape;
cpFloat leg_mass = 1.0f;
// make leg
a = cpvzero, b = cpv(0.0f, side);
cpBody *upper_leg = cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b));
upper_leg->p = cpv(offset, 0.0f);
cpSpaceAddBody(space, upper_leg);
cpSpaceAddShape(space, cpSegmentShapeNew(upper_leg, a, b, seg_radius));
cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, upper_leg, cpv(offset, 0.0f), cpvzero));
// lower leg
a = cpvzero, b = cpv(0.0f, -1.0f*side);
cpBody *lower_leg = cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b));
lower_leg->p = cpv(offset, -side);
cpSpaceAddBody(space, lower_leg);
shape = cpSegmentShapeNew(lower_leg, a, b, seg_radius);
shape->group = 1;
cpSpaceAddShape(space, shape);
shape = cpCircleShapeNew(lower_leg, seg_radius*2.0f, b);
shape->group = 1;
shape->e = 0.0f; shape->u = 1.0f;
cpSpaceAddShape(space, shape);
cpSpaceAddConstraint(space, cpPinJointNew(chassis, lower_leg, cpv(offset, 0.0f), cpvzero));
cpSpaceAddConstraint(space, cpGearJointNew(upper_leg, lower_leg, 0.0f, 1.0f));
cpConstraint *constraint;
cpFloat diag = cpfsqrt(side*side + offset*offset);
constraint = cpPinJointNew(crank, upper_leg, anchor, cpv(0.0f, side));
cpPinJointSetDist(constraint, diag);
cpSpaceAddConstraint(space, constraint);
constraint = cpPinJointNew(crank, lower_leg, anchor, cpvzero);
cpPinJointSetDist(constraint, diag);
cpSpaceAddConstraint(space, constraint);
}
static cpSpace *
init(void)
{
space = cpSpaceNew();
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 20;
space->gravity = cpv(0,-500);
cpBody *staticBody = &space->staticBody;
cpShape *shape;
cpVect a, b;
// Create segments around the edge of the screen.
shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f);
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
cpSpaceAddShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f);
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
cpSpaceAddShape(space, shape);
shape = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f);
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
cpSpaceAddShape(space, shape);
cpFloat offset = 30.0f;
// make chassis
cpFloat chassis_mass = 2.0f;
a = cpv(-offset, 0.0f), b = cpv(offset, 0.0f);
cpBody *chassis = cpBodyNew(chassis_mass, cpMomentForSegment(chassis_mass, a, b));
cpSpaceAddBody(space, chassis);
shape = cpSegmentShapeNew(chassis, a, b, seg_radius);
shape->group = 1;
cpSpaceAddShape(space, shape);
// make crank
cpFloat crank_mass = 1.0f;
cpFloat crank_radius = 13.0f;
cpBody *crank = cpBodyNew(crank_mass, cpMomentForCircle(crank_mass, crank_radius, 0.0f, cpvzero));
cpSpaceAddBody(space, crank);
shape = cpCircleShapeNew(crank, crank_radius, cpvzero);
shape->group = 1;
cpSpaceAddShape(space, shape);
cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, crank, cpvzero, cpvzero));
cpFloat side = 30.0f;
int num_legs = 2;
for(int i=0; i<num_legs; i++){
make_leg(side, offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+0)/num_legs*(cpFloat)M_PI), crank_radius));
make_leg(side, -offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+1)/num_legs*(cpFloat)M_PI), crank_radius));
}
motor = cpSimpleMotorNew(chassis, crank, 6.0f);
cpSpaceAddConstraint(space, motor);
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo TheoJansen = {
"Theo Jansen Machine",
NULL,
init,
update,
destroy,
};

View File

@ -1,133 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "chipmunk.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
static cpBody *staticBody;
static void
update(int ticks)
{
int steps = 3;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
// Manually update the position of the static shape so that
// the box rotates.
cpBodyUpdatePosition(staticBody, dt);
// Because the box was added as a static shape and we moved it
// we need to manually rehash the static spatial hash.
cpSpaceRehashStatic(space);
}
}
static cpSpace *
init(void)
{
staticBody = cpBodyNew(INFINITY, INFINITY);
cpResetShapeIdCounter();
space = cpSpaceNew();
cpSpaceResizeActiveHash(space, 40.0f, 999);
cpSpaceResizeStaticHash(space, 40.0f, 99);
space->gravity = cpv(0, -600);
cpBody *body;
cpShape *shape;
// Vertexes for the bricks
int num = 4;
cpVect verts[] = {
cpv(-30,-15),
cpv(-30, 15),
cpv( 30, 15),
cpv( 30,-15),
};
// Set up the static box.
cpVect a = cpv(-200, -200);
cpVect b = cpv(-200, 200);
cpVect c = cpv( 200, 200);
cpVect d = cpv( 200, -200);
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, a, b, 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, b, c, 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, c, d, 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, d, a, 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
// Give the box a little spin.
// Because staticBody is never added to the space, we will need to
// update it ourselves. (see above).
// NOTE: Normally you would want to add the segments as normal and not static shapes.
// I'm just doing it to demonstrate the cpSpaceRehashStatic() function.
staticBody->w = 0.4f;
// Add the bricks.
for(int i=0; i<3; i++){
for(int j=0; j<7; j++){
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
body->p = cpv(i*60 - 150, j*30 - 150);
shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
shape->e = 0.0f; shape->u = 0.7f;
}
}
return space;
}
static void
destroy(void)
{
cpBodyFree(staticBody);
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo Tumble = {
"Tumble",
NULL,
init,
update,
destroy,
};

View File

@ -1,112 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "chipmunk.h"
#include "chipmunk_unsafe.h"
#include "drawSpace.h"
#include "ChipmunkDemo.h"
static cpSpace *space;
#define NUM_CIRCLES 30
static cpShape *circles[NUM_CIRCLES];
static cpFloat circleRadius = 30.0f;
static void
update(int ticks)
{
if(arrowDirection.y){
circleRadius = cpfmax(10.0f, circleRadius + arrowDirection.y);
for(int i=0; i<NUM_CIRCLES; i++){
circles[i]->body->m = cpMomentForCircle(1.0f, 0.0f, circleRadius, cpvzero);
cpCircleShapeSetRadius(circles[i], circleRadius);
}
}
int steps = 1;
cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space, dt);
}
}
static cpSpace *
init(void)
{
cpResetShapeIdCounter();
space = cpSpaceNew();
space->iterations = 5;
space->gravity = cpv(0, -100);
cpSpaceResizeStaticHash(space, 40.0f, 999);
cpSpaceResizeActiveHash(space, 30.0f, 2999);
cpBody *body, *staticBody = &space->staticBody;
cpShape *shape;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
shape->e = 1.0f; shape->u = 1.0f;
shape->layers = NOT_GRABABLE_MASK;
for(int i=0; i<NUM_CIRCLES; i++){
body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 0.0f, circleRadius, cpvzero)));
body->p = cpvmult(cpv(frand()*2.0f - 1.0f, frand()*2.0f - 1.0f), circleRadius*5.0f);
circles[i] = shape = cpSpaceAddShape(space, cpCircleShapeNew(body, circleRadius, cpvzero));
shape->e = 0.0f; shape->u = 1.0f;
}
strcat(messageString,
"chipmunk_unsafe.h Contains functions for changing shapes, but they can cause severe stability problems if used incorrectly.\n"
"Shape changes occur as instantaneous changes to position without an accompanying velocity change. USE WITH CAUTION!");
return space;
}
static void
destroy(void)
{
cpSpaceFreeChildren(space);
cpSpaceFree(space);
}
chipmunkDemo UnsafeOps = {
"Unsafe Operations",
NULL,
init,
update,
destroy,
};

View File

@ -1,542 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
/*
IMPORTANT - READ ME!
This file sets up a simple interface that the individual demos can use to get
a Chipmunk space running and draw what's in it. In order to keep the Chipmunk
examples clean and simple, they contain no graphics code. All drawing is done
by accessing the Chipmunk structures at a very low level. It is NOT
recommended to write a game or application this way as it does not scale
beyond simple shape drawing and is very dependent on implementation details
about Chipmunk which may change with little to no warning.
*/
#include "cocos2d.h"
#include "chipmunk.h"
#include "drawSpace.h"
#include "cocos2dChipmunkDemo.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#define SLEEP_TICKS 16
#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#define glOrthof glOrtho
#endif
//extern chipmunkDemo Test;
extern chipmunkDemo LogoSmash;
extern chipmunkDemo Simple;
extern chipmunkDemo PyramidStack;
extern chipmunkDemo Plink;
extern chipmunkDemo Tumble;
extern chipmunkDemo PyramidTopple;
extern chipmunkDemo Bounce;
extern chipmunkDemo Planet;
extern chipmunkDemo Springies;
extern chipmunkDemo Pump;
extern chipmunkDemo TheoJansen;
extern chipmunkDemo MagnetsElectric;
extern chipmunkDemo UnsafeOps;
extern chipmunkDemo Query;
extern chipmunkDemo OneWay;
extern chipmunkDemo Player;
extern chipmunkDemo Sensors;
extern chipmunkDemo Joints;
extern chipmunkDemo Tank;
//extern chipmunkDemo Test;
static chipmunkDemo *demos[] = {
&LogoSmash,
&Simple,
&PyramidStack,
&Plink,
&Tumble,
&PyramidTopple,
&Bounce,
&Planet,
&Springies,
&Pump,
&TheoJansen,
&MagnetsElectric,
&UnsafeOps,
&Query,
&OneWay,
&Player,
&Sensors,
&Joints,
&Tank,
};
static int maxDemos = sizeof(demos) / sizeof(demos[0]);
static const int demoCount = sizeof(demos)/sizeof(chipmunkDemo *);
static chipmunkDemo *currDemo = NULL;
static const int firstDemoIndex = 'a' - 'a';
static int ticks = 0;
static cpSpace *space;
cpVect mousePoint;
cpVect mousePoint_last;
cpBody *mouseBody = NULL;
cpConstraint *mouseJoint = NULL;
char messageString[1024] = {};
int key_up = 0;
int key_down = 0;
int key_left = 0;
int key_right = 0;
cpVect arrowDirection = {};
drawSpaceOptions options = {
0,
0,
1,
4.0f,
0.0f,
1.5f,
};
static void
drawString(int x, int y, const char *str)
{
// glColor3f(0.0f, 0.0f, 0.0f);
// glRasterPos2i(x, y);
//
// for(int i=0, len=strlen(str); i<len; i++){
// if(str[i] == '\n'){
// y -= 16;
// glRasterPos2i(x, y);
// } else if(str[i] == '*'){ // print out the last demo key
// glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, 'A' + demoCount - 1);
// } else {
// glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, str[i]);
// }
// }
}
static void
drawInstructions()
{
drawString(-300, 220,
"Controls:\n"
"A - * Switch demos. (return restarts)\n"
"Use the mouse to grab objects.\n"
"Arrow keys control some demos.\n"
"\\ enables anti-aliasing.\n"
"- toggles spatial hash visualization.\n"
"= toggles bounding boxes."
);
}
static int maxArbiters = 0;
static int maxPoints = 0;
static int maxConstraints = 0;
static void
drawInfo()
{
int arbiters = space->arbiters->num;
int points = 0;
for(int i=0; i<arbiters; i++)
points += ((cpArbiter *)(space->arbiters->arr[i]))->numContacts;
int constraints = (space->constraints->num + points)*(space->iterations + space->elasticIterations);
maxArbiters = arbiters > maxArbiters ? arbiters : maxArbiters;
maxPoints = points > maxPoints ? points : maxPoints;
maxConstraints = constraints > maxConstraints ? constraints : maxConstraints;
char buffer[1024];
const char *format =
"Arbiters: %d (%d) - "
"Contact Points: %d (%d)\n"
"Other Constraints: %d, Iterations: %d\n"
"Constraints x Iterations: %d (%d)\n"
"KE:% 5.2e";
cpArray *bodies = space->bodies;
cpFloat ke = 0.0f;
for(int i=0; i<bodies->num; i++){
cpBody *body = (cpBody *)bodies->arr[i];
if(body->m == INFINITY || body->i == INFINITY) continue;
ke += body->m*cpvdot(body->v, body->v) + body->i*body->w*body->w;
}
sprintf(buffer, format,
arbiters, maxArbiters,
points, maxPoints,
space->constraints->num, space->iterations + space->elasticIterations,
constraints, maxConstraints, (ke < 1e-10f ? 0.0f : ke)
);
drawString(0, 220, buffer);
}
static void
reshape(int width, int height)
{
glViewport(0, 0, width, height);
float rx = width / 2.0f;
float ry = height / 2.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-rx, rx, -ry, ry, -1.0f, 1.0f);
glTranslatef(0.5f, 0.5f, 0.0f);
}
static void
display(void)
{
cpVect newPoint = cpvlerp(mousePoint_last, mousePoint, 0.25f);
mouseBody->p = newPoint;
mouseBody->v = cpvmult(cpvsub(newPoint, mousePoint_last), 60.0f);
mousePoint_last = newPoint;
currDemo->updateFunc(ticks);
// glClear(GL_COLOR_BUFFER_BIT);
//
// drawSpace(space, currDemo->drawOptions ? currDemo->drawOptions : &options);
// drawInstructions();
// drawInfo();
// drawString(-300, -210, messageString);
//
// glutSwapBuffers();
ticks++;
}
static char *
demoTitle(chipmunkDemo *demo)
{
static char title[1024];
sprintf(title, "Demo: %s", demo->name);
return title;
}
static void
runDemo(chipmunkDemo *demo)
{
if(currDemo)
currDemo->destroyFunc();
currDemo = demo;
ticks = 0;
mouseJoint = NULL;
messageString[0] = '\0';
maxArbiters = 0;
maxPoints = 0;
maxConstraints = 0;
space = currDemo->initFunc();
// glutSetWindowTitle(demoTitle(currDemo));
}
static void
keyboard(unsigned char key, int x, int y)
{
int index = key - 'a';
if(0 <= index && index < demoCount){
runDemo(demos[index]);
} else if(key == '\r'){
runDemo(currDemo);
} else if(key == '-'){
options.drawHash = !options.drawHash;
} else if(key == '='){
options.drawBBs = !options.drawBBs;
} else if(key == '\\'){
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
}
}
static cpVect
mouseToSpace(int x, int y)
{
// GLdouble model[16];
// glGetDoublev(GL_MODELVIEW_MATRIX, model);
//
// GLdouble proj[16];
// glGetDoublev(GL_PROJECTION_MATRIX, proj);
//
// GLint view[4];
// glGetIntegerv(GL_VIEWPORT, view);
//
// GLdouble mx, my, mz;
// gluUnProject(x, glutGet(GLUT_WINDOW_HEIGHT) - y, 0.0f, model, proj, view, &mx, &my, &mz);
//
// return cpv(mx, my);
return cpv(x,y);
}
static void
mouse(int x, int y)
{
mousePoint = mouseToSpace(x, y);
}
static void
click(int button, int state, int x, int y)
{
// if(button == GLUT_LEFT_BUTTON){
// if(state == GLUT_DOWN){
// cpVect point = mouseToSpace(x, y);
//
// cpShape *shape = cpSpacePointQueryFirst(space, point, GRABABLE_MASK_BIT, CP_NO_GROUP);
// if(shape){
// cpBody *body = shape->body;
// mouseJoint = cpPivotJointNew2(mouseBody, body, cpvzero, cpBodyWorld2Local(body, point));
// mouseJoint->maxForce = 50000.0f;
// mouseJoint->biasCoef = 0.15f;
// cpSpaceAddConstraint(space, mouseJoint);
// }
// } else if(mouseJoint){
// cpSpaceRemoveConstraint(space, mouseJoint);
// cpConstraintFree(mouseJoint);
// mouseJoint = NULL;
// }
// }
}
static void
timercall(int value)
{
// glutTimerFunc(SLEEP_TICKS, timercall, 0);
//
// glutPostRedisplay();
}
static void
set_arrowDirection()
{
int x = 0, y = 0;
if(key_up) y += 1;
if(key_down) y -= 1;
if(key_right) x += 1;
if(key_left) x -= 1;
arrowDirection = cpv(x, y);
}
static void
arrowKeyDownFunc(int key, int x, int y)
{
// if(key == GLUT_KEY_UP) key_up = 1;
// else if(key == GLUT_KEY_DOWN) key_down = 1;
// else if(key == GLUT_KEY_LEFT) key_left = 1;
// else if(key == GLUT_KEY_RIGHT) key_right = 1;
set_arrowDirection();
}
static void
arrowKeyUpFunc(int key, int x, int y)
{
// if(key == GLUT_KEY_UP) key_up = 0;
// else if(key == GLUT_KEY_DOWN) key_down = 0;
// else if(key == GLUT_KEY_LEFT) key_left = 0;
// else if(key == GLUT_KEY_RIGHT) key_right = 0;
set_arrowDirection();
}
//static void
//idle(void)
//{
// glutPostRedisplay();
//}
static void
initGL(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glEnableClientState(GL_VERTEX_ARRAY);
}
static void
glutStuff(int argc, const char *argv[])
{
// glutInit(&argc, (char**)argv);
//
// glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
//
// glutInitWindowSize(640, 480);
// glutCreateWindow(demoTitle(demos[firstDemoIndex]));
//
// initGL();
//
// glutReshapeFunc(reshape);
// glutDisplayFunc(display);
// // glutIdleFunc(idle);
// glutTimerFunc(SLEEP_TICKS, timercall, 0);
//
// glutIgnoreKeyRepeat(1);
// glutKeyboardFunc(keyboard);
//
// glutSpecialFunc(arrowKeyDownFunc);
// glutSpecialUpFunc(arrowKeyUpFunc);
//
// glutMotionFunc(mouse);
// glutPassiveMotionFunc(mouse);
// glutMouseFunc(click);
}
//#include <sys/time.h>
//void time_trial(char index, int count)
//{
// currDemo = demos[index];
// space = currDemo->initFunc();
//
// struct timeval start_time, end_time;
// gettimeofday(&start_time, NULL);
//
// for(int i=0; i<count; i++)
// currDemo->updateFunc(i);
//
// gettimeofday(&end_time, NULL);
// long millisecs = (end_time.tv_sec - start_time.tv_sec)*1000;
// millisecs += (end_time.tv_usec - start_time.tv_usec)/1000;
//
// currDemo->destroyFunc();
//
// printf("Time(%c) = %ldms\n", index + 'a', millisecs);
//}
void ChipmunkTestScene::runThisTest()
{
// create layer
ChipmunkTestLayer* pLayer = new ChipmunkTestLayer();
pLayer->init();
pLayer->autorelease();
addChild(pLayer);
CCDirector::sharedDirector()->replaceScene(this);
}
void ChipmunkTestLayer::init()
{
CCLayer::init();
CCLayer::setIsTouchEnabled(true);
demoIndex = 0;
cpInitChipmunk();
cp_collision_slop = 0.2f;
mouseBody = cpBodyNew(INFINITY, INFINITY);
runDemo(demos[firstDemoIndex]);
label = CCLabelTTF::labelWithString(demos[firstDemoIndex]->name, "Arial", 32);
label->setPosition( ccp(0, -300) );
label->setColor(ccBLACK);
addChild(label);
// [self schedule: @selector(step:)];
scheduleUpdate();
}
void ChipmunkTestLayer::onEnter()
{
CCLayer::onEnter();
glClearColor(1,1,1,1);
float factor = 1.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)
// portraint
//glOrthof(-320/factor, 320/factor, -480/factor, 480/factor, -1.0f, 1.0f);
// landscape
glOrthof(-320/factor, 320/factor, 0/factor, 960/factor, 1.0f, -1.0f);
#else
// portraint
//glOrthof(-320/factor, 320/factor, -480/factor, 480/factor, -1.0f, 1.0f);
// landscape
glOrthof(-480/factor, 480/factor, -320/factor, 320/factor, 1.0f, -1.0f);
#endif
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPointSize(3.0f);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
glLineWidth(1.5f);
}
void ChipmunkTestLayer::onExit()
{
CCDirector::sharedDirector()->setGLDefaultValues();
CCLayer::onExit();
}
void ChipmunkTestLayer::update(ccTime dt)
{
// call chipmunk demo c function
display();
}
void ChipmunkTestLayer::draw()
{
drawSpace(space, currDemo->drawOptions ? currDemo->drawOptions : &options);
}
void ChipmunkTestLayer::ccTouchesEnded(CCSet* touches, CCEvent *event)
{
demoIndex++;
if( demoIndex >= maxDemos )
demoIndex = 0;
runDemo(demos[demoIndex]);
label->setString( demos[demoIndex]->name );
}

View File

@ -1,80 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 "chipmunk.h"
#include "drawSpace.h"
#include "../testBasic.h"
struct chipmunkDemo;
typedef cpSpace *(*demoInitFunc)(void);
typedef void (*demoUpdateFunc)(int ticks);
typedef void (*demoDestroyFunc)(void);
typedef struct chipmunkDemo {
char *name;
drawSpaceOptions *drawOptions;
demoInitFunc initFunc;
demoUpdateFunc updateFunc;
demoDestroyFunc destroyFunc;
} chipmunkDemo;
static inline cpFloat
frand(void)
{
return (cpFloat)rand()/(cpFloat)RAND_MAX;
}
extern cpVect arrowDirection;
extern char messageString[1024];
#define GRABABLE_MASK_BIT (1<<31)
#define NOT_GRABABLE_MASK (~GRABABLE_MASK_BIT)
// cocos2d-x test interface decalre
class ChipmunkTestScene : public TestScene
{
public:
virtual void runThisTest();
};
class ChipmunkTestLayer : public CCLayer
{
protected:
std::string m_strTitle;
int demoIndex;
CCLabelTTF *label;
public:
void init();
// virtual std::string title();
virtual void onEnter();
virtual void onExit();
void update(ccTime dt);
void draw();
void ccTouchesEnded(CCSet* touches, CCEvent *event);
// void restartCallback(CCObject* pSender);
// void nextCallback(CCObject* pSender);
// void backCallback(CCObject* pSender);
};

View File

@ -1,536 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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 "cocos2d.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include "chipmunk.h"
#include "drawSpace.h"
using namespace cocos2d;
/*
IMPORTANT - READ ME!
This file sets up a simple interface that the individual demos can use to get
a Chipmunk space running and draw what's in it. In order to keep the Chipmunk
examples clean and simple, they contain no graphics code. All drawing is done
by accessing the Chipmunk structures at a very low level. It is NOT
recommended to write a game or application this way as it does not scale
beyond simple shape drawing and is very dependent on implementation details
about Chipmunk which may change with little to no warning.
*/
#define LINE_COLOR 0.0f, 0.0f, 0.0f, 1.0f
#define COLLISION_COLOR 1.0f, 0.0f, 0.0f, 1.0f
#define BODY_COLOR 0.0f, 0.0f, 1.0f, 1.0f
static void
glColor_from_pointer(void *ptr)
{
unsigned long val = (long)ptr;
// hash the pointer up nicely
val = (val+0x7ed55d16) + (val<<12);
val = (val^0xc761c23c) ^ (val>>19);
val = (val+0x165667b1) + (val<<5);
val = (val+0xd3a2646c) ^ (val<<9);
val = (val+0xfd7046c5) + (val<<3);
val = (val^0xb55a4f09) ^ (val>>16);
// GLfloat v = (GLfloat)val/(GLfloat)ULONG_MAX;
// v = 0.95f - v*0.15f;
//
// glColor3f(v, v, v);
GLubyte r = (val>>0) & 0xFF;
GLubyte g = (val>>8) & 0xFF;
GLubyte b = (val>>16) & 0xFF;
GLubyte max = r>g ? (r>b ? r : b) : (g>b ? g : b);
const int mult = 127;
const int add = 63;
r = (r*mult)/max + add;
g = (g*mult)/max + add;
b = (b*mult)/max + add;
// glColor4ub isn't implemented on some android devices
// glColor4ub(r, g, b, 255);
glColor4f( ((GLfloat)r)/255, ((GLfloat)g) / 255, ((GLfloat)b)/255, 1.0f );
}
static void
glColor_for_shape(cpShape *shape, cpSpace *space)
{
cpBody *body = shape->body;
if(body){
if(body->node.next){
GLfloat v = 0.25f;
glColor4f(v,v,v,1);
return;
} else if(body->node.idleTime > space->sleepTimeThreshold) {
GLfloat v = 0.9f;
glColor4f(v,v,v,1);
return;
}
}
glColor_from_pointer(shape);
}
static const GLfloat circleVAR[] = {
0.0000f, 1.0000f,
0.2588f, 0.9659f,
0.5000f, 0.8660f,
0.7071f, 0.7071f,
0.8660f, 0.5000f,
0.9659f, 0.2588f,
1.0000f, 0.0000f,
0.9659f, -0.2588f,
0.8660f, -0.5000f,
0.7071f, -0.7071f,
0.5000f, -0.8660f,
0.2588f, -0.9659f,
0.0000f, -1.0000f,
-0.2588f, -0.9659f,
-0.5000f, -0.8660f,
-0.7071f, -0.7071f,
-0.8660f, -0.5000f,
-0.9659f, -0.2588f,
-1.0000f, -0.0000f,
-0.9659f, 0.2588f,
-0.8660f, 0.5000f,
-0.7071f, 0.7071f,
-0.5000f, 0.8660f,
-0.2588f, 0.9659f,
0.0000f, 1.0000f,
0.0f, 0.0f, // For an extra line to see the rotation.
};
static const int circleVAR_count = sizeof(circleVAR)/sizeof(GLfloat)/2;
static void
drawCircleShape(cpBody *body, cpCircleShape *circle, cpSpace *space)
{
glVertexPointer(2, GL_FLOAT, 0, circleVAR);
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPushMatrix(); {
cpVect center = circle->tc;
glTranslatef(center.x, center.y, 0.0f);
glRotatef(body->a*180.0f/(float)M_PI, 0.0f, 0.0f, 1.0f);
glScalef(circle->r, circle->r, 1.0f);
if(!circle->shape.sensor){
glColor_for_shape((cpShape *)circle, space);
glDrawArrays(GL_TRIANGLE_FAN, 0, circleVAR_count - 1);
}
glColor4f(LINE_COLOR);
glDrawArrays(GL_LINE_STRIP, 0, circleVAR_count);
} glPopMatrix();
// restore default GL state
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
static const GLfloat pillVAR[] = {
0.0000f, 1.0000f, 1.0f,
0.2588f, 0.9659f, 1.0f,
0.5000f, 0.8660f, 1.0f,
0.7071f, 0.7071f, 1.0f,
0.8660f, 0.5000f, 1.0f,
0.9659f, 0.2588f, 1.0f,
1.0000f, 0.0000f, 1.0f,
0.9659f, -0.2588f, 1.0f,
0.8660f, -0.5000f, 1.0f,
0.7071f, -0.7071f, 1.0f,
0.5000f, -0.8660f, 1.0f,
0.2588f, -0.9659f, 1.0f,
0.0000f, -1.0000f, 1.0f,
0.0000f, -1.0000f, 0.0f,
-0.2588f, -0.9659f, 0.0f,
-0.5000f, -0.8660f, 0.0f,
-0.7071f, -0.7071f, 0.0f,
-0.8660f, -0.5000f, 0.0f,
-0.9659f, -0.2588f, 0.0f,
-1.0000f, -0.0000f, 0.0f,
-0.9659f, 0.2588f, 0.0f,
-0.8660f, 0.5000f, 0.0f,
-0.7071f, 0.7071f, 0.0f,
-0.5000f, 0.8660f, 0.0f,
-0.2588f, 0.9659f, 0.0f,
0.0000f, 1.0000f, 0.0f,
};
static const int pillVAR_count = sizeof(pillVAR)/sizeof(GLfloat)/3;
static void
drawSegmentShape(cpBody *body, cpSegmentShape *seg, cpSpace *space)
{
cpVect a = seg->ta;
cpVect b = seg->tb;
if(seg->r){
glVertexPointer(3, GL_FLOAT, 0, pillVAR);
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPushMatrix(); {
cpVect d = cpvsub(b, a);
cpVect r = cpvmult(d, seg->r/cpvlength(d));
const GLfloat matrix[] = {
r.x, r.y, 0.0f, 0.0f,
-r.y, r.x, 0.0f, 0.0f,
d.x, d.y, 0.0f, 0.0f,
a.x, a.y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
if(!seg->shape.sensor){
glColor_for_shape((cpShape *)seg, space);
glDrawArrays(GL_TRIANGLE_FAN, 0, pillVAR_count);
}
glColor4f(LINE_COLOR);
glDrawArrays(GL_LINE_LOOP, 0, pillVAR_count);
} glPopMatrix();
// restore default GL state
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
} else {
glColor4f(LINE_COLOR);
ccDrawLine(ccp(a.x, a.y),ccp(b.x, b.y));
}
}
static void
drawPolyShape(cpBody *body, cpPolyShape *poly, cpSpace *space)
{
int count = poly->numVerts;
#if CP_USE_DOUBLES
glVertexPointer(2, GL_DOUBLE, 0, poly->tVerts);
#else
glVertexPointer(2, GL_FLOAT, 0, poly->tVerts);
#endif
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(!poly->shape.sensor){
glColor_for_shape((cpShape *)poly, space);
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
}
glColor4f(LINE_COLOR);
glDrawArrays(GL_LINE_LOOP, 0, count);
// restore default GL state
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void
drawObject(cpShape *shape, cpSpace *space)
{
cpBody *body = shape->body;
switch(shape->klass->type){
case CP_CIRCLE_SHAPE:
drawCircleShape(body, (cpCircleShape *)shape, space);
break;
case CP_SEGMENT_SHAPE:
drawSegmentShape(body, (cpSegmentShape *)shape, space);
break;
case CP_POLY_SHAPE:
drawPolyShape(body, (cpPolyShape *)shape, space);
break;
default:
CCLOG("Bad enumeration in drawObject().\n");
break;
}
}
static const GLfloat springVAR[] = {
0.00f, 0.0f,
0.20f, 0.0f,
0.25f, 3.0f,
0.30f,-6.0f,
0.35f, 6.0f,
0.40f,-6.0f,
0.45f, 6.0f,
0.50f,-6.0f,
0.55f, 6.0f,
0.60f,-6.0f,
0.65f, 6.0f,
0.70f,-3.0f,
0.75f, 6.0f,
0.80f, 0.0f,
1.00f, 0.0f,
};
static const int springVAR_count = sizeof(springVAR)/sizeof(GLfloat)/2;
static void
drawSpring(cpDampedSpring *spring, cpBody *body_a, cpBody *body_b)
{
cpVect a = cpvadd(body_a->p, cpvrotate(spring->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(spring->anchr2, body_b->rot));
glPointSize(5.0f);
ccDrawPoint( ccp(a.x, a.y) );
ccDrawPoint( ccp(b.x, b.y) );
cpVect delta = cpvsub(b, a);
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, springVAR);
glPushMatrix(); {
GLfloat x = a.x;
GLfloat y = a.y;
GLfloat cos = delta.x;
GLfloat sin = delta.y;
GLfloat s = 1.0f/cpvlength(delta);
const GLfloat matrix[] = {
cos, sin, 0.0f, 0.0f,
-sin*s, cos*s, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
glDrawArrays(GL_LINE_STRIP, 0, springVAR_count);
} glPopMatrix();
// restore default GL state
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
static void
drawConstraint(cpConstraint *constraint)
{
cpBody *body_a = constraint->a;
cpBody *body_b = constraint->b;
const cpConstraintClass *klass = constraint->klass;
if(klass == cpPinJointGetClass()){
cpPinJoint *joint = (cpPinJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
glPointSize(5.0f);
ccDrawPoint( ccp(a.x, a.y) );
ccDrawPoint( ccp(b.x, b.y) );
ccDrawLine( ccp(a.x, a.y), ccp(b.x, b.y) );
} else if(klass == cpSlideJointGetClass()){
cpSlideJoint *joint = (cpSlideJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
glPointSize(5.0f);
ccDrawPoint( ccp(a.x, a.y) );
ccDrawPoint( ccp(b.x, b.y) );
ccDrawLine( ccp(a.x, a.y), ccp(b.x, b.y) );
} else if(klass == cpPivotJointGetClass()){
cpPivotJoint *joint = (cpPivotJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
glPointSize(10.0f);
ccDrawPoint( ccp(a.x, a.y) );
ccDrawPoint( ccp(b.x, b.y) );
} else if(klass == cpGrooveJointGetClass()){
cpGrooveJoint *joint = (cpGrooveJoint *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(joint->grv_a, body_a->rot));
cpVect b = cpvadd(body_a->p, cpvrotate(joint->grv_b, body_a->rot));
cpVect c = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
glPointSize(5.0f);
ccDrawPoint( ccp(c.x, c.y) );
ccDrawLine( ccp(a.x, a.y), ccp(b.x, b.y) );
} else if(klass == cpDampedSpringGetClass()){
drawSpring((cpDampedSpring *)constraint, body_a, body_b);
} else {
// printf("Cannot draw constraint\n");
}
}
static void
drawBB(cpShape *shape, void *unused)
{
CCPoint vertices[] = {
ccp(shape->bb.l, shape->bb.b),
ccp(shape->bb.l, shape->bb.t),
ccp(shape->bb.r, shape->bb.t),
ccp(shape->bb.r, shape->bb.b),
};
ccDrawPoly(vertices, 4, false);
}
// copied from cpSpaceHash.c
static inline cpHashValue
hash_func(cpHashValue x, cpHashValue y, cpHashValue n)
{
return (x*1640531513ul ^ y*2654435789ul) % n;
}
static void
drawSpatialHash(cpSpaceHash *hash)
{
cpBB bb = cpBBNew(-320, -240, 320, 240);
cpFloat dim = hash->celldim;
int n = hash->numcells;
int l = (int)floor(bb.l/dim);
int r = (int)floor(bb.r/dim);
int b = (int)floor(bb.b/dim);
int t = (int)floor(bb.t/dim);
for(int i=l; i<=r; i++){
for(int j=b; j<=t; j++){
int cell_count = 0;
int index = hash_func(i,j,n);
for(cpSpaceHashBin *bin = hash->table[index]; bin; bin = bin->next)
cell_count++;
GLfloat v = 1.0f - (GLfloat)cell_count/10.0f;
glColor4f(v,v,v,1);
// glRectf(i*dim, j*dim, (i + 1)*dim, (j + 1)*dim);
}
}
}
void
drawSpace(cpSpace *space, drawSpaceOptions *options)
{
if(options->drawHash){
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
drawSpatialHash(space->activeShapes);
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
drawSpatialHash(space->staticShapes);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
glLineWidth(options->lineThickness);
if(options->drawShapes){
cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)drawObject, space);
cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)drawObject, space);
}
glLineWidth(1.0f);
if(options->drawBBs){
glColor4f(0.3f, 0.5f, 0.3f,1);
cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)drawBB, NULL);
cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)drawBB, NULL);
}
cpArray *constraints = space->constraints;
glColor4f(0.5f, 1.0f, 0.5f, 1);
for(int i=0, count = constraints->num; i<count; i++){
drawConstraint((cpConstraint *)constraints->arr[i]);
}
if(options->bodyPointSize){
glPointSize(options->bodyPointSize);
cpArray *bodies = space->bodies;
glColor4f(LINE_COLOR);
for(int i=0, count = bodies->num; i<count; i++){
cpBody *body = (cpBody *)bodies->arr[i];
ccDrawPoint( ccp(body->p.x, body->p.y) );
}
// glColor3f(0.5f, 0.5f, 0.5f);
// cpArray *components = space->components;
// for(int i=0; i<components->num; i++){
// cpBody *root = components->arr[i];
// cpBody *body = root, *next;
// do {
// next = body->node.next;
// glVertex2f(body->p.x, body->p.y);
// } while((body = next) != root);
// }
}
if(options->collisionPointSize){
glPointSize(options->collisionPointSize);
cpArray *arbiters = space->arbiters;
for(int i=0; i<arbiters->num; i++){
cpArbiter *arb = (cpArbiter*)arbiters->arr[i];
glColor4f(COLLISION_COLOR);
for(int i=0; i<arb->numContacts; i++){
cpVect v = arb->contacts[i].p;
ccDrawPoint( ccp(v.x, v.y) );
}
}
}
}

View File

@ -1,37 +0,0 @@
/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
#ifndef _DRAW_SPACE_H_
#define _DRAW_SPACE_H_
typedef struct drawSpaceOptions {
int drawHash;
int drawBBs;
int drawShapes;
float collisionPointSize;
float bodyPointSize;
float lineThickness;
} drawSpaceOptions;
void drawSpace(cpSpace *space, drawSpaceOptions *options);
#endif //_DRAW_SPACE_H_

View File

@ -52,18 +52,17 @@ static TestScene* CreateTestScene(int nIdx)
pScene = new TileMapTestScene(); break;
case TEST_INTERVAL:
pScene = new IntervalTestScene(); break;
case TEST_CHIPMUNK:
// TODO:
// #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
// pScene = new ChipmunkTestScene(); break;
// #else
// #ifdef MARMALADEUSECHIPMUNK
// #if (MARMALADEUSECHIPMUNK == 1)
// pScene = new ChipmunkTestScene();
// #endif
// break;
// #endif
// #endif
case TEST_CHIPMUNKACCELTOUCH:
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
pScene = new ChipmunkAccelTouchTestScene(); break;
#else
#ifdef MARMALADEUSECHIPMUNK
#if (MARMALADEUSECHIPMUNK == 1)
pScene = new ChipmunkAccelTouchTestScene();
#endif
break;
#endif
#endif
case TEST_LABEL:
pScene = new AtlasTestScene(); break;
case TEST_TEXT_INPUT:
@ -77,9 +76,9 @@ static TestScene* CreateTestScene(int nIdx)
case TEST_TEXTURE2D:
pScene = new TextureTestScene(); break;
case TEST_BOX2D:
//TODO: pScene = new Box2DTestScene(); break;
pScene = new Box2DTestScene(); break;
case TEST_BOX2DBED:
//TODO: pScene = new Box2dTestBedScene(); break;
pScene = new Box2dTestBedScene(); break;
case TEST_EFFECT_ADVANCE:
pScene = new EffectAdvanceScene(); break;
case TEST_HIRES:

View File

@ -21,10 +21,7 @@
#include "TileMapTest/TileMapTest.h"
#include "IntervalTest/IntervalTest.h"
#include "LabelTest/LabelTest.h"
// havn't implement on marmalade
//#if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
#include "TextInputTest/TextInputTest.h"
//#endif
#include "SpriteTest/SpriteTest.h"
#include "SchedulerTest/SchedulerTest.h"
#include "RenderTextureTest/RenderTextureTest.h"
@ -47,11 +44,11 @@
#include "TextureCacheTest/TextureCacheTest.h"
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
#include "ChipmunkTest/cocos2dChipmunkDemo.h"
#include "ChipmunkAccelTouchTest/ChipmunkAccelTouchTest.h"
#else
#ifdef MARMALADEUSECHIPMUNK
#if (MARMALADEUSECHIPMUNK == 1)
#include "ChipmunkTest/cocos2dChipmunkDemo.h"
#include "ChipmunkAccelTouchTest/ChipmunkAccelTouchTest.h"
#endif
#endif
#endif // (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
@ -79,7 +76,7 @@ enum
TEST_PARALLAX,
TEST_TILE_MAP,
TEST_INTERVAL,
TEST_CHIPMUNK,
TEST_CHIPMUNKACCELTOUCH,
TEST_LABEL,
TEST_TEXT_INPUT,
TEST_SPRITE,
@ -126,7 +123,7 @@ const std::string g_aTestNames[TESTS_COUNT] = {
"ParallaxTest",
"TileMapTest",
"IntervalTest",
"ChipmunkTest",
"ChipmunkAccelTouchTest",
"LabelTest",
"TextInputTest",
"SpriteTest",