RayCast for Box2d - Hack

Box2D / Chipmunk

Moderator: stun

RayCast for Box2d - Hack

Postby mikegriffin » Tue Mar 13, 2012 11:16 am

Amendments to MOAIBox2DWorld

to add raycast supports requires a callback class (ie RayCastCallback)

Code: Select all
  1.  

  2. // Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.

  3. // <!-- m --><a class="postlink" href="http://getmoai.com">http://getmoai.com</a><!-- m -->

  4.  

  5. #include "pch.h"

  6. #include <Box2D/Box2D.h>

  7. #include <moaicore/MOAIBox2DArbiter.h>

  8. #include <moaicore/MOAIBox2DBody.h>

  9. #include <moaicore/MOAIBox2DDebugDraw.h>

  10. #include <moaicore/MOAIBox2DDistanceJoint.h>

  11. #include <moaicore/MOAIBox2DFixture.h>

  12. #include <moaicore/MOAIBox2DFrictionJoint.h>

  13. #include <moaicore/MOAIBox2DGearJoint.h>

  14. #include <moaicore/MOAIBox2DJoint.h>

  15. #include <moaicore/MOAIBox2DMouseJoint.h>

  16. #include <moaicore/MOAIBox2DPrismaticJoint.h>

  17. #include <moaicore/MOAIBox2DPulleyJoint.h>

  18. #include <moaicore/MOAIBox2DRevoluteJoint.h>

  19. #include <moaicore/MOAIBox2DRopeJoint.h>

  20. #include <moaicore/MOAIBox2DWeldJoint.h>

  21. #include <moaicore/MOAIBox2DWheelJoint.h>

  22. #include <moaicore/MOAIBox2DWorld.h>

  23. #include <moaicore/MOAIDraw.h>

  24. #include <moaicore/MOAIGfxDevice.h>

  25. #include <moaicore/MOAILogMessages.h>

  26.  

  27. SUPPRESS_EMPTY_FILE_WARNING

  28. #if USE_BOX2D

  29.  

  30.         class RayCastCallback : public b2RayCastCallback

  31.    {

  32.    public:

  33.       RayCastCallback()

  34.       {

  35.          m_fixture = NULL;

  36.       }

  37.      

  38.       float32 ReportFixture(   b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)

  39.       {

  40.          m_fixture = fixture;

  41.          m_point = point;

  42.          m_normal = normal;

  43.          

  44.          return fraction;

  45.       }

  46.      

  47.       b2Fixture* m_fixture;

  48.       b2Vec2 m_point;

  49.       b2Vec2 m_normal;

  50.    };

  51.  

  52. //================================================================//

  53. // MOAIBox2DPrim

  54. //================================================================//

  55.  

  56. //----------------------------------------------------------------//

  57. float MOAIBox2DPrim::GetUnitsToMeters () {

  58.  

  59.         if ( this->mWorld ) {

  60.                 return this->mWorld->GetUnitsToMeters ();

  61.         }

  62.         return 1.0f;

  63. }

  64.  

  65. //----------------------------------------------------------------//

  66. MOAIBox2DPrim::MOAIBox2DPrim () :

  67.         mWorld ( 0 ),

  68.         mDestroy ( false ),

  69.         mDestroyNext ( 0 ) {

  70. }

  71. //================================================================//

  72. // local

  73. //================================================================//

  74.  

  75. //----------------------------------------------------------------//

  76. /**     @name   addBody

  77.         @text   Create and add a body to the world.

  78.        

  79.         @in             MOAIBox2DWorld self

  80.         @in             number type             One of MOAIBox2DBody.DYNAMIC, MOAIBox2DBody.KINEMATIC, MOAIBox2DBody.STATIC

  81.         @opt    number x

  82.         @opt    number y

  83.         @out    MOAIBox2DBody joint

  84. */

  85. int MOAIBox2DWorld::_addBody ( lua_State* L ) {

  86.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UN" )

  87.        

  88.         if ( self->IsLocked ()) {

  89.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  90.                 return 0;

  91.         }

  92.        

  93.         u32 type        = state.GetValue < u32 >( 2, 0 );

  94.         float x         = state.GetValue < float >( 3, 0.0f ) * self->mUnitsToMeters;

  95.         float y         = state.GetValue < float >( 4, 0.0f ) * self->mUnitsToMeters;

  96.        

  97.         b2BodyDef groundBodyDef;

  98.         groundBodyDef.type = ( b2BodyType )type;

  99.         groundBodyDef.position.Set ( x, y );

  100.        

  101.         MOAIBox2DBody* body = new MOAIBox2DBody ();

  102.         body->SetBody ( self->mWorld->CreateBody ( &groundBodyDef ));

  103.         body->SetWorld ( self );

  104.         self->LuaRetain ( *body );

  105.        

  106.         body->PushLuaUserdata ( state );

  107.         return 1;

  108. }

  109.  

  110. //----------------------------------------------------------------//

  111. /**     @name   addDistanceJoint

  112.         @text   Create and add a joint to the world. See Box2D documentation.

  113.        

  114.         @in             MOAIBox2DWorld self

  115.         @in             MOAIBox2DBody bodyA

  116.         @in             MOAIBox2DBody bodyB

  117.         @in             number anchorA_X

  118.         @in             number anchorA_Y

  119.         @in             number anchorB_X

  120.         @in             number anchorB_Y

  121.         @opt    number frequencyHz                      Default value determined by Box2D

  122.         @opt    number dampingRatio                     Default value determined by Box2D

  123.         @opt    number collideConnected         Default value is false

  124.         @out    MOAIBox2DJoint joint

  125. */

  126. int     MOAIBox2DWorld::_addDistanceJoint ( lua_State* L ) {

  127.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNNNN" )

  128.        

  129.         if ( self->IsLocked ()) {

  130.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  131.                 return 0;

  132.         }

  133.        

  134.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  135.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  136.        

  137.         if ( !( bodyA && bodyB )) return 0;

  138.        

  139.         b2Vec2 anchorA;

  140.         anchorA.x       = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  141.         anchorA.y       = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  142.        

  143.         b2Vec2 anchorB;

  144.         anchorB.x       = state.GetValue < float >( 6, 0 ) * self->mUnitsToMeters;

  145.         anchorB.y       = state.GetValue < float >( 7, 0 ) * self->mUnitsToMeters;

  146.        

  147.         b2DistanceJointDef jointDef;

  148.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchorA, anchorB );

  149.        

  150.         jointDef.frequencyHz    = state.GetValue < float >( 8, jointDef.frequencyHz );

  151.         jointDef.dampingRatio   = state.GetValue < float >( 9, jointDef.dampingRatio );

  152.         jointDef.collideConnected = state.GetValue < bool >( 10, false );

  153.        

  154.         MOAIBox2DDistanceJoint* joint = new MOAIBox2DDistanceJoint ();

  155.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  156.         joint->SetWorld ( self );

  157.         self->LuaRetain ( *joint );

  158.        

  159.         joint->PushLuaUserdata ( state );

  160.         return 1;

  161. }

  162.  

  163. //----------------------------------------------------------------//

  164. /**     @name   addFrictionJoint

  165.         @text   Create and add a joint to the world. See Box2D documentation.

  166.        

  167.         @in             MOAIBox2DWorld self

  168.         @in             MOAIBox2DBody bodyA

  169.         @in             MOAIBox2DBody bodyB

  170.         @in             number anchorX

  171.         @in             number anchorY

  172.         @opt    number maxForce                 Converted to N.         Default value determined by Box2D

  173.         @opt    number maxTorque                Converted to N-m.       Default value determined by Box2D

  174.         @out    MOAIBox2DJoint joint

  175. */

  176. int     MOAIBox2DWorld::_addFrictionJoint ( lua_State* L ) {

  177.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNN" )

  178.        

  179.         if ( self->IsLocked ()) {

  180.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  181.                 return 0;

  182.         }

  183.        

  184.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  185.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  186.        

  187.         if ( !( bodyA && bodyB )) return 0;

  188.        

  189.         b2Vec2 anchor;

  190.         anchor.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  191.         anchor.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  192.        

  193.         b2FrictionJointDef jointDef;

  194.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchor );

  195.  

  196.         float unitsToMeters = self->GetUnitsToMeters();

  197.  

  198.         jointDef.maxForce       = state.GetValue < float >( 6, jointDef.maxForce / unitsToMeters ) * unitsToMeters;

  199.         /* Convert to/from N-m (kg m / s^2) * m from/to (kg unit / s^2) * unit */

  200.         jointDef.maxTorque      = state.GetValue < float >( 7, jointDef.maxTorque / ( unitsToMeters * unitsToMeters ) ) * unitsToMeters * unitsToMeters;

  201.        

  202.         MOAIBox2DFrictionJoint* joint = new MOAIBox2DFrictionJoint ();

  203.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  204.         joint->SetWorld ( self );

  205.         self->LuaRetain ( *joint );

  206.        

  207.         joint->PushLuaUserdata ( state );

  208.         return 1;

  209. }

  210.  

  211. //----------------------------------------------------------------//

  212. /**     @name   addGearJoint

  213.         @text   Create and add a joint to the world. See Box2D documentation.

  214.        

  215.         @in             MOAIBox2DWorld self

  216.         @in             MOAIBox2DJoint jointA

  217.         @in             MOAIBox2DJoint jointB

  218.         @in             float ratio

  219.         @out    MOAIBox2DJoint joint

  220. */

  221. int     MOAIBox2DWorld::_addGearJoint ( lua_State* L ) {

  222.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUN" )

  223.        

  224.         if ( self->IsLocked ()) {

  225.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  226.                 return 0;

  227.         }

  228.        

  229.         MOAIBox2DJoint* jointA = state.GetLuaObject < MOAIBox2DJoint >( 2 );

  230.         MOAIBox2DJoint* jointB = state.GetLuaObject < MOAIBox2DJoint >( 3 );

  231.        

  232.         if ( !( jointA && jointB )) return 0;

  233.        

  234.         b2GearJointDef jointDef;

  235.        

  236.         jointDef.bodyA  = jointA->mJoint->GetBodyA ();

  237.         jointDef.bodyB  = jointB->mJoint->GetBodyB ();

  238.         jointDef.joint1 = jointA->mJoint;

  239.         jointDef.joint2 = jointB->mJoint;

  240.         jointDef.ratio  = state.GetValue < float >( 4, 0.0f );

  241.        

  242.         MOAIBox2DGearJoint* joint = new MOAIBox2DGearJoint ();

  243.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  244.         joint->SetWorld ( self );

  245.         self->LuaRetain ( *joint );

  246.        

  247.         joint->mJointA.Set ( *self, jointA );

  248.         joint->mJointB.Set ( *self, jointB );

  249.        

  250.         joint->PushLuaUserdata ( state );

  251.         return 1;

  252. }

  253.  

  254. //----------------------------------------------------------------//

  255. /**     @name   addMouseJoint

  256.         @text   Create and add a joint to the world. See Box2D documentation.

  257.        

  258.         @in             MOAIBox2DWorld self

  259.         @in             MOAIBox2DBody bodyA

  260.         @in             MOAIBox2DBody bodyB

  261.         @in             number targetX

  262.         @in             number targetY

  263.         @in             number maxForce

  264.         @opt    number frequencyHz                      Default value determined by Box2D

  265.         @opt    number dampingRatio                     Default value determined by Box2D

  266.         @out    MOAIBox2DJoint joint

  267. */

  268. int     MOAIBox2DWorld::_addMouseJoint ( lua_State* L ) {

  269.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNNN" )

  270.        

  271.         if ( self->IsLocked ()) {

  272.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  273.                 return 0;

  274.         }

  275.        

  276.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  277.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  278.        

  279.         if ( !( bodyA && bodyB )) return 0;

  280.        

  281.         b2Vec2 target;

  282.         target.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  283.         target.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  284.        

  285.         b2MouseJointDef jointDef;

  286.         jointDef.bodyA                  = bodyA->mBody;

  287.         jointDef.bodyB                  = bodyB->mBody;

  288.         jointDef.target                 = target;

  289.         jointDef.maxForce               = state.GetValue < float >( 6, 0.0f ) * self->mUnitsToMeters;

  290.         jointDef.frequencyHz    = state.GetValue < float >( 7, jointDef.frequencyHz );

  291.         jointDef.dampingRatio   = state.GetValue < float >( 8, jointDef.dampingRatio );

  292.        

  293.         MOAIBox2DMouseJoint* joint = new MOAIBox2DMouseJoint ();

  294.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  295.         joint->SetWorld ( self );

  296.         self->LuaRetain ( *joint );

  297.        

  298.         joint->PushLuaUserdata ( state );

  299.         return 1;

  300. }

  301.  

  302. //----------------------------------------------------------------//

  303. /**     @name   addPrismaticJoint

  304.         @text   Create and add a joint to the world. See Box2D documentation.

  305.        

  306.         @in             MOAIBox2DWorld self

  307.         @in             MOAIBox2DBody bodyA

  308.         @in             MOAIBox2DBody bodyB

  309.         @in             number anchorA

  310.         @in             number anchorB

  311.         @in             number axisA

  312.         @in             number axisB

  313.         @out    MOAIBox2DJoint joint

  314. */

  315. int     MOAIBox2DWorld::_addPrismaticJoint ( lua_State* L ) {

  316.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNNNN" )

  317.        

  318.         if ( self->IsLocked ()) {

  319.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  320.                 return 0;

  321.         }

  322.        

  323.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  324.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  325.        

  326.         if ( !( bodyA && bodyB )) return 0;

  327.        

  328.         b2Vec2 anchor;

  329.         anchor.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  330.         anchor.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  331.        

  332.         b2Vec2 axis;

  333.         axis.x          = state.GetValue < float >( 6, 0 );

  334.         axis.y          = state.GetValue < float >( 7, 0 );

  335.        

  336.         b2PrismaticJointDef jointDef;

  337.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchor, axis );

  338.        

  339.         MOAIBox2DPrismaticJoint* joint = new MOAIBox2DPrismaticJoint ();

  340.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  341.         joint->SetWorld ( self );

  342.         self->LuaRetain ( *joint );

  343.        

  344.         joint->PushLuaUserdata ( state );

  345.         return 1;

  346. }

  347.  

  348. //----------------------------------------------------------------//

  349. /**     @name   addPulleyJoint

  350.         @text   Create and add a joint to the world. See Box2D documentation.

  351.        

  352.         @in             MOAIBox2DWorld self

  353.         @in             MOAIBox2DBody bodyA

  354.         @in             MOAIBox2DBody bodyB

  355.         @in             number groundAnchorA_X

  356.         @in             number groundAnchorA_Y

  357.         @in             number groundAnchorB_X

  358.         @in             number groundAnchorB_Y

  359.         @in             number anchorA_X

  360.         @in             number anchorA_Y

  361.         @in             number anchorB_X

  362.         @in             number anchorB_Y

  363.         @in             number ratio

  364.         @in             number maxLengthA

  365.         @in             number maxLengthB

  366.         @out    MOAIBox2DJoint joint

  367. */

  368. int     MOAIBox2DWorld::_addPulleyJoint ( lua_State* L ) {

  369.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNNNNNNNNNNN" )

  370.        

  371.         if ( self->IsLocked ()) {

  372.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  373.                 return 0;

  374.         }

  375.        

  376.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  377.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  378.        

  379.         if ( !( bodyA && bodyB )) return 0;

  380.        

  381.         b2Vec2 groundAnchorA;

  382.         groundAnchorA.x         = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  383.         groundAnchorA.y         = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  384.        

  385.         b2Vec2 groundAnchorB;

  386.         groundAnchorB.x         = state.GetValue < float >( 6, 0 ) * self->mUnitsToMeters;

  387.         groundAnchorB.y         = state.GetValue < float >( 7, 0 ) * self->mUnitsToMeters;

  388.        

  389.         b2Vec2 anchorA;

  390.         anchorA.x                       = state.GetValue < float >( 8, 0 ) * self->mUnitsToMeters;

  391.         anchorA.y                       = state.GetValue < float >( 9, 0 ) * self->mUnitsToMeters;

  392.        

  393.         b2Vec2 anchorB;

  394.         anchorB.x                       = state.GetValue < float >( 10, 0 ) * self->mUnitsToMeters;

  395.         anchorB.y                       = state.GetValue < float >( 11, 0 ) * self->mUnitsToMeters;

  396.        

  397.         float ratio                     = state.GetValue < float >( 12, 0 );

  398.        

  399.         b2PulleyJointDef jointDef;

  400.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, groundAnchorA, groundAnchorB, anchorA, anchorB, ratio );

  401.        

  402.         jointDef.lengthA        = state.GetValue < float >( 13, 0 ) * self->mUnitsToMeters;

  403.         jointDef.lengthB        = state.GetValue < float >( 14, 0 ) * self->mUnitsToMeters;

  404.        

  405.         MOAIBox2DPulleyJoint* joint = new MOAIBox2DPulleyJoint ();

  406.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  407.         joint->SetWorld ( self );

  408.         self->LuaRetain ( *joint );

  409.        

  410.         joint->PushLuaUserdata ( state );

  411.         return 1;

  412. }

  413.  

  414. //----------------------------------------------------------------//

  415. /**     @name   addRevoluteJoint

  416.         @text   Create and add a joint to the world. See Box2D documentation.

  417.        

  418.         @in             MOAIBox2DWorld self

  419.         @in             MOAIBox2DBody bodyA

  420.         @in             MOAIBox2DBody bodyB

  421.         @in             number anchorX

  422.         @in             number anchorY

  423.         @out    MOAIBox2DJoint joint

  424. */

  425. int     MOAIBox2DWorld::_addRevoluteJoint ( lua_State* L ) {

  426.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNN" )

  427.        

  428.         if ( self->IsLocked ()) {

  429.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  430.                 return 0;

  431.         }

  432.        

  433.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  434.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  435.        

  436.         if ( !( bodyA && bodyB )) return 0;

  437.        

  438.         b2Vec2 anchor;

  439.         anchor.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  440.         anchor.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  441.        

  442.         b2RevoluteJointDef jointDef;

  443.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchor );

  444.        

  445.         MOAIBox2DRevoluteJoint* joint = new MOAIBox2DRevoluteJoint ();

  446.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  447.         joint->SetWorld ( self );

  448.         self->LuaRetain ( *joint );

  449.        

  450.         joint->PushLuaUserdata ( state );

  451.         return 1;

  452. }

  453.  

  454. //----------------------------------------------------------------//

  455. /**     @name   addRopeJoint

  456.  @text  Create and add a rope joint to the world. See Box2D documentation.

  457.  

  458.  @in            MOAIBox2DWorld self

  459.  @in            MOAIBox2DBody bodyA

  460.  @in            MOAIBox2DBody bodyB

  461.  @in            number maxLength

  462.  @opt           number anchorAX

  463.  @opt           number anchorAY

  464.  @opt           number anchorBX

  465.  @opt           number anchorBY

  466.  @out   MOAIBox2DJoint joint

  467.  */

  468. int     MOAIBox2DWorld::_addRopeJoint ( lua_State* L ) {

  469.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUU" )

  470.        

  471.         if ( self->IsLocked ()) {

  472.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  473.                 return 0;

  474.         }

  475.        

  476.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  477.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  478.        

  479.         if ( !( bodyA && bodyB )) return 0;

  480.        

  481.         float maxLength = state.GetValue < float >( 4, 1 ) * self->mUnitsToMeters;

  482.        

  483.         b2Vec2 anchorA;

  484.         anchorA.x       = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  485.         anchorA.y       = state.GetValue < float >( 6, 0 ) * self->mUnitsToMeters;

  486.        

  487.         b2Vec2 anchorB;

  488.         anchorB.x       = state.GetValue < float >( 7, 0 ) * self->mUnitsToMeters;

  489.         anchorB.y       = state.GetValue < float >( 8, 0 ) * self->mUnitsToMeters;

  490.        

  491.         b2RopeJointDef jointDef;

  492.         jointDef.bodyA = bodyA->mBody;

  493.         jointDef.bodyB = bodyB->mBody;

  494.         jointDef.maxLength = maxLength;

  495.        

  496.         MOAIBox2DRopeJoint* joint = new MOAIBox2DRopeJoint ();

  497.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  498.         joint->SetWorld ( self );

  499.         self->LuaRetain ( *joint );

  500.        

  501.         joint->PushLuaUserdata ( state );

  502.         return 1;

  503. }

  504.  

  505.  

  506. //----------------------------------------------------------------//

  507. /**     @name   addWeldJoint

  508.         @text   Create and add a joint to the world. See Box2D documentation.

  509.        

  510.         @in             MOAIBox2DWorld self

  511.         @in             MOAIBox2DBody bodyA

  512.         @in             MOAIBox2DBody bodyB

  513.         @in             number anchorX

  514.         @in             number anchorY

  515.         @out    MOAIBox2DJoint joint

  516. */

  517. int     MOAIBox2DWorld::_addWeldJoint ( lua_State* L ) {

  518.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNN" )

  519.        

  520.         if ( self->IsLocked ()) {

  521.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  522.                 return 0;

  523.         }

  524.        

  525.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  526.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  527.        

  528.         if ( !( bodyA && bodyB )) return 0;

  529.        

  530.         b2Vec2 anchor;

  531.         anchor.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  532.         anchor.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  533.        

  534.         b2WeldJointDef jointDef;

  535.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchor );

  536.        

  537.         MOAIBox2DWeldJoint* joint = new MOAIBox2DWeldJoint ();

  538.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  539.         joint->SetWorld ( self );

  540.         self->LuaRetain ( *joint );

  541.        

  542.         joint->PushLuaUserdata ( state );

  543.         return 1;

  544. }

  545.  

  546. //----------------------------------------------------------------//

  547. /**     @name addWheelJoint

  548.         @text   Create and add a joint to the world. See Box2D documentation.

  549.  

  550.  @in            MOAIBox2DWorld self

  551.  @in            MOAIBox2DBody bodyA

  552.  @in            MOAIBox2DBody bodyB

  553.  @in            number anchorX

  554.  @in            number anchorY

  555.  @in            number axisX

  556.  @in            number axisY

  557.  @out   MOAIBox2DJoint joint

  558.  */

  559. int     MOAIBox2DWorld::_addWheelJoint ( lua_State* L ) {

  560.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UUUNNNN" )

  561.        

  562.         if ( self->IsLocked ()) {

  563.                 MOAILog ( state, MOAILogMessages::MOAIBox2DWorld_IsLocked );

  564.                 return 0;

  565.         }

  566.        

  567.         MOAIBox2DBody* bodyA = state.GetLuaObject < MOAIBox2DBody >( 2 );

  568.         MOAIBox2DBody* bodyB = state.GetLuaObject < MOAIBox2DBody >( 3 );

  569.        

  570.         if ( !( bodyA && bodyB )) return 0;

  571.        

  572.         b2Vec2 anchor;

  573.         anchor.x        = state.GetValue < float >( 4, 0 ) * self->mUnitsToMeters;

  574.         anchor.y        = state.GetValue < float >( 5, 0 ) * self->mUnitsToMeters;

  575.        

  576.         b2Vec2 axis;

  577.         axis.x          = state.GetValue < float >( 6, 0 );

  578.         axis.y      = state.GetValue < float >( 7, 0 );

  579.        

  580.         b2WheelJointDef jointDef;

  581.         jointDef.Initialize ( bodyA->mBody, bodyB->mBody, anchor, axis );

  582.        

  583.         MOAIBox2DWheelJoint* joint = new MOAIBox2DWheelJoint ();

  584.         joint->SetJoint ( self->mWorld->CreateJoint ( &jointDef ));

  585.         joint->SetWorld ( self );

  586.         self->LuaRetain ( *joint );

  587.        

  588.         joint->PushLuaUserdata ( state );

  589.         return 1;

  590. }

  591.  

  592. //----------------------------------------------------------------//

  593. /**     @name   getAngularSleepTolerance

  594.         @text   See Box2D documentation.

  595.        

  596.         @in             MOAIBox2DWorld self

  597.         @out    number angularSleepTolerance

  598. */

  599. int MOAIBox2DWorld::_getAngularSleepTolerance ( lua_State* L ) {

  600.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  601.        

  602.         lua_pushnumber ( state, self->mWorld->GetAngularSleepTolerance ());

  603.         return 0;

  604. }

  605.  

  606. //----------------------------------------------------------------//

  607. /**     @name   getAutoClearForces

  608.         @text   See Box2D documentation.

  609.        

  610.         @in             MOAIBox2DWorld self

  611.         @out    boolean autoClearForces

  612. */

  613. int MOAIBox2DWorld::_getAutoClearForces ( lua_State* L ) {

  614.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  615.        

  616.         bool autoClearForces = self->mWorld->GetAutoClearForces ();

  617.         lua_pushboolean ( L, autoClearForces );

  618.        

  619.         return 1;

  620. }

  621.  

  622. //----------------------------------------------------------------//

  623. /**     @name   getRayCast

  624.         @text   return RayCast 1st point hit

  625.        

  626.         @in             MOAIBox2DWorld self

  627.         @in             number p1x

  628.         @in             number p1y

  629.         @in             number p2x

  630.         @in             number p2y

  631.         @out    number hitpoint.x

  632.         @out    number hitpoint.y

  633. */

  634.  

  635. int MOAIBox2DWorld::_getRayCast ( lua_State* L ) {

  636.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  637.         float p1x=state.GetValue < float >( 2, 0 );

  638.         float p1y=state.GetValue < float >( 3, 0 );

  639.         float p2x=state.GetValue < float >( 4, 0 );

  640.         float p2y=state.GetValue < float >( 5, 0 );

  641.  

  642.    b2Vec2 p1(p1x,p1y);

  643.    b2Vec2 p2(p2x,p2y);

  644.    

  645.    RayCastCallback callback;

  646.    self->mWorld->RayCast(&callback, p1, p2);

  647.    

  648.    b2Vec2 hitpoint = callback.m_point;

  649.  

  650.    lua_pushnumber ( state, hitpoint.x / self->mUnitsToMeters );

  651.    lua_pushnumber ( state, hitpoint.y / self->mUnitsToMeters );

  652.  

  653.    return 2;

  654. }

  655.  

  656. //----------------------------------------------------------------//

  657. /**     @name   getGravity

  658.         @text   See Box2D documentation.

  659.        

  660.         @in             MOAIBox2DWorld self

  661.         @out    number gravityX

  662.         @out    number gravityY

  663. */

  664. int MOAIBox2DWorld::_getGravity ( lua_State* L ) {

  665.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  666.        

  667.         b2Vec2 gravity = self->mWorld->GetGravity ();

  668.        

  669.         lua_pushnumber ( L, gravity.x / self->mUnitsToMeters );

  670.         lua_pushnumber ( L, gravity.y / self->mUnitsToMeters );

  671.        

  672.         return 2;

  673. }

  674.  

  675. //----------------------------------------------------------------//

  676. /**     @name   getLinearSleepTolerance

  677.         @text   See Box2D documentation.

  678.        

  679.         @in             MOAIBox2DWorld self

  680.         @out    number linearSleepTolerance

  681. */

  682. int MOAIBox2DWorld::_getLinearSleepTolerance ( lua_State* L ) {

  683.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  684.        

  685.         lua_pushnumber ( state, self->mWorld->GetLinearSleepTolerance () / self->mUnitsToMeters );

  686.         return 0;

  687. }

  688.  

  689. //----------------------------------------------------------------//

  690. /**     @name   getTimeToSleep

  691.         @text   See Box2D documentation.

  692.        

  693.         @in             MOAIBox2DWorld self

  694.         @out    number timeToSleep

  695. */

  696. int MOAIBox2DWorld::_getTimeToSleep ( lua_State* L ) {

  697.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  698.        

  699.         lua_pushnumber ( state, self->mWorld->GetTimeToSleep ());

  700.         return 0;

  701. }

  702.  

  703. //----------------------------------------------------------------//

  704. /**     @name   setAngularSleepTolerance

  705.         @text   See Box2D documentation.

  706.        

  707.         @in             MOAIBox2DWorld self

  708.         @opt    number angularSleepTolerance            Default value is 0.0f.

  709.         @out    nil

  710. */

  711. int MOAIBox2DWorld::_setAngularSleepTolerance ( lua_State* L ) {

  712.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  713.        

  714.         self->mWorld->SetAngularSleepTolerance ( state.GetValue < float >( 2, 0.0f ));

  715.         return 0;

  716. }

  717.  

  718. //----------------------------------------------------------------//

  719. /**     @name   setAutoClearForces

  720.         @text   See Box2D documentation.

  721.        

  722.         @in             MOAIBox2DWorld self

  723.         @opt    boolean autoClearForces         Default value is 'true'

  724.         @out    nil

  725. */

  726. int MOAIBox2DWorld::_setAutoClearForces ( lua_State* L ) {

  727.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  728.        

  729.         bool autoClearForces = state.GetValue < bool >( 2, true );

  730.        

  731.         self->mWorld->SetAutoClearForces ( autoClearForces );

  732.        

  733.         return 0;

  734. }

  735.  

  736. //----------------------------------------------------------------//

  737. /**     @name   setGravity

  738.         @text   See Box2D documentation.

  739.        

  740.         @in             MOAIBox2DWorld self

  741.         @opt    number gravityX                 Default value is 0.

  742.         @opt    number gravityY                 Default value is 0.

  743.         @out    nil

  744. */

  745. int MOAIBox2DWorld::_setGravity ( lua_State* L ) {

  746.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  747.        

  748.         b2Vec2 gravity;

  749.        

  750.         gravity.x       = state.GetValue < float >( 2, 0.0f ) * self->mUnitsToMeters;

  751.         gravity.y       = state.GetValue < float >( 3, 0.0f ) * self->mUnitsToMeters;

  752.        

  753.         self->mWorld->SetGravity ( gravity );

  754.        

  755.         return 0;

  756. }

  757.  

  758. //----------------------------------------------------------------//

  759. /**     @name   setIterations

  760.         @text   See Box2D documentation.

  761.        

  762.         @in             MOAIBox2DWorld self

  763.         @opt    number velocityIteratons                        Default value is current value of velocity iterations.

  764.         @opt    number positionIterations                       Default value is current value of positions iterations.

  765.         @out    nil

  766. */

  767. int MOAIBox2DWorld::_setIterations ( lua_State* L ) {

  768.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  769.        

  770.         self->mVelocityIterations = state.GetValue < u32 >( 2, self->mVelocityIterations );

  771.         self->mPositionIterations = state.GetValue < u32 >( 3, self->mPositionIterations );

  772.        

  773.         return 0;

  774. }

  775.  

  776. //----------------------------------------------------------------//

  777. /**     @name   setLinearSleepTolerance

  778.         @text   See Box2D documentation.

  779.        

  780.         @in             MOAIBox2DWorld self

  781.         @opt    number linearSleepTolerance             Default value is 0.0f.

  782.         @out    nil

  783. */

  784. int MOAIBox2DWorld::_setLinearSleepTolerance ( lua_State* L ) {

  785.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  786.        

  787.         self->mWorld->SetLinearSleepTolerance ( state.GetValue < float >( 2, 0.0f ) * self->mUnitsToMeters );

  788.         return 0;

  789. }

  790.  

  791. //----------------------------------------------------------------//

  792. /**     @name   setTimeToSleep

  793.         @text   See Box2D documentation.

  794.        

  795.         @in             MOAIBox2DWorld self

  796.         @opt    number timeToSleep                              Default value is 0.0f.

  797.         @out    nil

  798. */

  799. int MOAIBox2DWorld::_setTimeToSleep ( lua_State* L ) {

  800.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  801.        

  802.         self->mWorld->SetTimeToSleep ( state.GetValue < float >( 2, 0.0f ));

  803.         return 0;

  804. }

  805.  

  806. //----------------------------------------------------------------//

  807. /**     @name   setUnitsToMeters

  808.         @text   Sets a scale factor for converting game world units to Box2D meters.

  809.        

  810.         @in             MOAIBox2DWorld self

  811.         @opt    number unitsToMeters                    Default value is 1.

  812.         @out    nil

  813. */

  814. int MOAIBox2DWorld::_setUnitsToMeters ( lua_State* L ) {

  815.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  816.        

  817.         self->mUnitsToMeters = state.GetValue ( 2, 1.0f );

  818.        

  819.         return 0;

  820. }

  821.  

  822. //================================================================//

  823. // MOAIBox2DWorld

  824. //================================================================//

  825.  

  826. //----------------------------------------------------------------//

  827. void MOAIBox2DWorld::Destroy () {

  828.  

  829.         if ( this->mLock ) return;

  830.         this->mLock = true;

  831.  

  832.         while ( this->mDestroyFixtures ) {

  833.                 MOAIBox2DPrim* prim = this->mDestroyFixtures;

  834.                 this->mDestroyFixtures = this->mDestroyFixtures->mDestroyNext;

  835.                 prim->Destroy ();

  836.                

  837.                 prim->SetWorld ( 0 );

  838.                 this->LuaRelease ( *prim );

  839.         }

  840.        

  841.         while ( this->mDestroyJoints ) {

  842.                 MOAIBox2DPrim* prim = this->mDestroyJoints;

  843.                 this->mDestroyJoints = this->mDestroyJoints->mDestroyNext;

  844.                 prim->Destroy ();

  845.                

  846.                 prim->SetWorld ( 0 );

  847.                 this->LuaRelease ( *prim );

  848.         }

  849.        

  850.         while ( this->mDestroyBodies ) {

  851.                 MOAIBox2DPrim* prim = this->mDestroyBodies;

  852.                 this->mDestroyBodies = this->mDestroyBodies->mDestroyNext;

  853.                 prim->Destroy ();

  854.                

  855.                 prim->SetWorld ( 0 );

  856.                 this->LuaRelease ( *prim );

  857.         }

  858.        

  859.         this->mLock = false;

  860. }

  861.  

  862. //----------------------------------------------------------------//

  863. void MOAIBox2DWorld::DrawDebug () {

  864.  

  865.         if ( this->mDebugDraw ) {

  866.                

  867.                 MOAIDraw::Bind ();

  868.                

  869.                 MOAIGfxDevice& gfxDevice = MOAIGfxDevice::Get ();

  870.                

  871.                 gfxDevice.SetVertexMtxMode ( MOAIGfxDevice::VTX_STAGE_WORLD, MOAIGfxDevice::VTX_STAGE_PROJ );

  872.                 gfxDevice.SetVertexTransform ( MOAIGfxDevice::VTX_WORLD_TRANSFORM );

  873.                

  874.                 this->mDebugDraw->mScale = 1.0f / this->mUnitsToMeters;

  875.                 this->mWorld->DrawDebugData ();

  876.         }

  877. }

  878.  

  879. //----------------------------------------------------------------//

  880. bool MOAIBox2DWorld::IsDone () {

  881.  

  882.         return false;

  883. }

  884.  

  885. //----------------------------------------------------------------//

  886. bool MOAIBox2DWorld::IsLocked () {

  887.  

  888.         if ( this->mWorld ) {

  889.                 return this->mWorld->IsLocked ();

  890.         }

  891.         return false;

  892. }

  893.  

  894. //----------------------------------------------------------------//

  895. MOAIBox2DWorld::MOAIBox2DWorld () :

  896.         mLock ( false ),

  897.         mVelocityIterations ( 10 ),

  898.         mPositionIterations ( 10 ),

  899.         mUnitsToMeters ( 1.0f ),

  900.         mDestroyBodies ( 0 ),

  901.         mDestroyFixtures ( 0 ),

  902.         mDestroyJoints ( 0 ) {

  903.        

  904.         RTTI_BEGIN

  905.                 RTTI_EXTEND ( MOAIAction )

  906.         RTTI_END

  907.        

  908.         this->mArbiter.Set ( *this, new MOAIBox2DArbiter ());

  909.        

  910.         b2Vec2 gravity ( 0.0f, 0.0f );

  911.         this->mWorld = new b2World ( gravity);

  912.         this->mWorld->SetContactListener ( this->mArbiter );

  913.         this->mWorld->SetDestructionListener ( this );

  914.         this->mWorld->SetAllowSleeping(true);

  915.         this->mDebugDraw = new MOAIBox2DDebugDraw ();

  916.         this->mWorld->SetDebugDraw ( this->mDebugDraw );

  917.        

  918.         this->mDebugDraw->SetFlags (

  919.                 b2Draw::e_shapeBit                      |

  920.                 b2Draw::e_jointBit                      |

  921.                 //b2DebugDraw::e_aabbBit                        |

  922.                 //b2DebugDraw::e_pairBit                        |

  923.                 b2Draw::e_centerOfMassBit

  924.         );

  925. }

  926.  

  927. //----------------------------------------------------------------//

  928. MOAIBox2DWorld::~MOAIBox2DWorld () {

  929.  

  930.         this->mWorld->SetContactListener ( 0 );

  931.  

  932.         while ( b2Body* body = this->mWorld->GetBodyList ()) {

  933.                 MOAIBox2DBody* moaiBody = ( MOAIBox2DBody* )body->GetUserData ();

  934.                

  935.                 this->mWorld->DestroyBody ( body );

  936.                 moaiBody->mBody = 0;

  937.                 moaiBody->SetWorld ( 0 );

  938.                 this->LuaRelease ( *moaiBody );

  939.         }

  940.        

  941.         this->mArbiter.Set ( *this, 0 );

  942.        

  943.         delete ( this->mDebugDraw );

  944.         delete ( this->mWorld );

  945. }

  946.  

  947. //----------------------------------------------------------------//

  948. void MOAIBox2DWorld::OnUpdate ( float step ) {

  949.        

  950.         this->mLock = true;

  951.         this->mWorld->Step ( step, this->mVelocityIterations, this->mPositionIterations );

  952.         this->mLock = false;

  953.        

  954.         this->Destroy ();

  955.        

  956.         b2Body* body = this->mWorld->GetBodyList ();

  957.         for ( ; body; body = body->GetNext ()) {

  958.                 if ( body->IsActive () && body->IsAwake ()) {

  959.                         MOAIBox2DBody* moaiBody = ( MOAIBox2DBody* )body->GetUserData ();

  960.                         moaiBody->ScheduleUpdate ();

  961.                 }

  962.         }

  963. }

  964.  

  965. //----------------------------------------------------------------//

  966. void MOAIBox2DWorld::RegisterLuaClass ( MOAILuaState& state ) {

  967.  

  968.         MOAIAction::RegisterLuaClass ( state );

  969. }

  970.  

  971. //----------------------------------------------------------------//

  972. void MOAIBox2DWorld::RegisterLuaFuncs ( MOAILuaState& state ) {

  973.        

  974.         MOAIAction::RegisterLuaFuncs ( state );

  975.  

  976.         luaL_Reg regTable [] = {

  977.                 { "addBody",                                    _addBody },

  978.                 { "addDistanceJoint",                   _addDistanceJoint },

  979.                 { "addFrictionJoint",                   _addFrictionJoint },

  980.                 { "addGearJoint",                               _addGearJoint },

  981.                 { "addMouseJoint",                              _addMouseJoint },

  982.                 { "addPrismaticJoint",                  _addPrismaticJoint },

  983.                 { "addPulleyJoint",                             _addPulleyJoint },

  984.                 { "addRevoluteJoint",                   _addRevoluteJoint },

  985.                 { "addRopeJoint",                               _addRopeJoint },

  986.                 { "addWeldJoint",                               _addWeldJoint },

  987.                 { "addWheelJoint",                              _addWheelJoint },

  988.                 { "getAngularSleepTolerance",   _getAngularSleepTolerance },

  989.                 { "getAutoClearForces",                 _getAutoClearForces },

  990.                 { "getGravity",                                 _getGravity },

  991.                 { "getLinearSleepTolerance",    _getLinearSleepTolerance },

  992.                 { "getTimeToSleep",                             _getTimeToSleep },

  993.                 { "setAngularSleepTolerance",   _setAngularSleepTolerance },

  994.                 { "setAutoClearForces",                 _setAutoClearForces },

  995.                 { "setGravity",                                 _setGravity },

  996.                 { "setIterations",                              _setIterations },

  997.                 { "setLinearSleepTolerance",    _setLinearSleepTolerance },

  998.                 { "setTimeToSleep",                             _setTimeToSleep },

  999.                 { "setUnitsToMeters",                   _setUnitsToMeters },

  1000.                 { "getRayCast",                                 _getRayCast },

  1001.                 { NULL, NULL }

  1002.         };

  1003.        

  1004.         luaL_register ( state, 0, regTable );

  1005. }

  1006.  

  1007. //----------------------------------------------------------------//

  1008. void MOAIBox2DWorld::SayGoodbye ( b2Fixture* fixture ) {

  1009.  

  1010.         MOAIBox2DFixture* moaiFixture = ( MOAIBox2DFixture* )fixture->GetUserData ();

  1011.         if ( moaiFixture->mFixture ) {

  1012.                 moaiFixture->mFixture = 0;

  1013.                 moaiFixture->SetWorld ( 0 );

  1014.                 this->LuaRelease ( *moaiFixture );

  1015.         }

  1016. }

  1017.  

  1018. //----------------------------------------------------------------//

  1019. void MOAIBox2DWorld::SayGoodbye ( b2Joint* joint ) {

  1020.  

  1021.         MOAIBox2DJoint* moaiJoint = ( MOAIBox2DJoint* )joint->GetUserData ();

  1022.         if ( moaiJoint->mJoint ) {

  1023.                 moaiJoint->mJoint = 0;

  1024.                 moaiJoint->SetWorld ( 0 );

  1025.                 this->LuaRelease ( *moaiJoint );

  1026.         }

  1027. }

  1028.  

  1029. //----------------------------------------------------------------//

  1030. void MOAIBox2DWorld::ScheduleDestruction ( MOAIBox2DBody& body ) {

  1031.  

  1032.         if ( !body.mDestroy ) {

  1033.                 body.mDestroyNext = this->mDestroyBodies;

  1034.                 this->mDestroyBodies = &body;

  1035.                 body.mDestroy = true;

  1036.         }

  1037.         this->Destroy ();

  1038. }

  1039.  

  1040. //----------------------------------------------------------------//

  1041. void MOAIBox2DWorld::ScheduleDestruction ( MOAIBox2DFixture& fixture ) {

  1042.  

  1043.         if ( !fixture.mDestroy ) {

  1044.                 fixture.mDestroyNext = this->mDestroyFixtures;

  1045.                 this->mDestroyFixtures = &fixture;

  1046.                 fixture.mDestroy = true;

  1047.         }

  1048.         this->Destroy ();

  1049. }

  1050.  

  1051. //----------------------------------------------------------------//

  1052. void MOAIBox2DWorld::ScheduleDestruction ( MOAIBox2DJoint& joint ) {

  1053.  

  1054.         if ( !joint.mDestroy ) {

  1055.                 joint.mDestroyNext = this->mDestroyJoints;

  1056.                 this->mDestroyJoints = &joint;

  1057.                 joint.mDestroy = true;

  1058.         }

  1059.         this->Destroy ();

  1060. }

  1061.  

  1062.  

  1063. #endif

  1064.  

  1065.  

  1066.  

mikegriffin
 
Posts: 68
Joined: Thu Feb 02, 2012 12:04 pm

Re: RayCast for Box2d - Hack

Postby naturally » Fri Sep 27, 2013 3:08 am

I've added this, compiled it, and called getRayCast().

Question is, how do you use it?
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby naturally » Fri Sep 27, 2013 3:15 am

I've noticed it returns a point, but the point seems to be useless, a very small decimal - that doesn't change except when restarting app. Weird
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby naturally » Fri Sep 27, 2013 3:35 am

MOAIBox2DWorld.h:

add:
Code: Select all
  1.  

  2.         static int              _getRayCast                             ( lua_State* L );

  3.  



Code: Select all
  1.  

  2. //================================================================//

  3. // MOAIBox2DRayCastCallback

  4. //================================================================//

  5. class MOAIBox2DRayCastCallback : public b2RayCastCallback

  6. {

  7. public:

  8.           MOAIBox2DRayCastCallback()

  9.   {

  10.      m_fixture = NULL;

  11.   }

  12.  

  13.   float32 ReportFixture(   b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)

  14.   {

  15.      m_fixture = fixture;

  16.      m_point = point;

  17.      m_normal = normal;

  18.      

  19.      return fraction;

  20.   }

  21.  

  22.   b2Fixture* m_fixture;

  23.   b2Vec2 m_point;

  24.   b2Vec2 m_normal;

  25. };

  26.  



In MOAIBox2DWorld.cpp:

Code: Select all
  1.  

  2. //----------------------------------------------------------------//

  3. /**     @name   getRayCast

  4.         @text   return RayCast 1st point hit

  5.        

  6.         @in             MOAIBox2DWorld self

  7.         @in             number p1x

  8.         @in             number p1y

  9.         @in             number p2x

  10.         @in             number p2y

  11.         @out    number hitpoint.x

  12.         @out    number hitpoint.y

  13. */

  14.  

  15. int MOAIBox2DWorld::_getRayCast ( lua_State* L ) {

  16.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "U" )

  17.         float p1x=state.GetValue < float >( 2, 0 );

  18.         float p1y=state.GetValue < float >( 3, 0 );

  19.         float p2x=state.GetValue < float >( 4, 0 );

  20.         float p2y=state.GetValue < float >( 5, 0 );

  21.  

  22.    b2Vec2 p1(p1x,p1y);

  23.    b2Vec2 p2(p2x,p2y);

  24.    

  25.    MOAIBox2DRayCastCallback callback;

  26.    self->mWorld->RayCast(&callback, p1, p2);

  27.    

  28.    b2Vec2 hitpoint = callback.m_point;

  29.  

  30.    lua_pushnumber ( state, hitpoint.x / self->mUnitsToMeters );

  31.    lua_pushnumber ( state, hitpoint.y / self->mUnitsToMeters );

  32.  

  33.    return 2;

  34. }

  35.  



It seems to me that I have to get access to the raycast class (object?) by exposing it like so:

Code: Select all
  1.  

  2.         DECL_LUA_FACTORY ( MOAIBox2DRayCastCallback )

  3.  

  4.         GET_SET ( float, point, m_point )

  5.         GET_SET ( float, fixture, m_fixture )

  6.         GET_SET ( float, normal, m_normal )

  7.  

  8.         void                    RegisterLuaClass                ( MOAILuaState& state );

  9.         void                    RegisterLuaFuncs                ( MOAILuaState& state );

  10.  



However, that doesn't compile. And how can I get the fixture? Isn't that a body pointer? Doesn't the raycast return multiple hits? How to deal with that? A little confused here.
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby naturally » Tue Oct 08, 2013 8:45 am

Bump! There are at least two people who have this working... please respond! :)
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby stun » Tue Oct 08, 2013 12:51 pm

Damn yes sorry I have this working at home. I'll try and get the code I have up today sometime. It's not that hard to do, but yes there was some code on this forum that was a little broken. I had to do some work to get it working properly.
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm

Re: RayCast for Box2d - Hack

Postby naturally » Tue Oct 08, 2013 3:03 pm

Yay stun! Well I am interested to know what I'm failing to do, cuz I cannot get this callback to do anything...
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby stun » Tue Oct 08, 2013 6:09 pm

Ok well here's a quick blog post about what I'm using for Box2D ray casting:

http://www.fivevolthigh.com/2013/10/moa ... g-to-moai/

It is based off the earlier forum post, but has been modified to work nicely for my own uses. I can confirm this code definitely does work as I've used it in a 2D game of my own to ray cast from one 'wall' of a 2D cavern (made from a Box2D chain) to find the opposite wall and measure the distances between them.

Let me know if you have any questions and I'll endeavour to help!
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm

Re: RayCast for Box2d - Hack

Postby davek » Wed Oct 09, 2013 5:53 am

Thanks stun!

How do you call it from Lua, something like this?

Code: Select all
  1. hit, hx, hy, fixture = physicsWorld:getRayCast(ox, oy, dx, dy)

davek
 
Posts: 34
Joined: Wed Aug 21, 2013 11:02 am

Re: RayCast for Box2d - Hack

Postby stun » Wed Oct 09, 2013 11:59 am

Exactly, although careful not localising variables like that because that's bitten me a number of times. Even in example code, out of habit I'd go:

local hit, hx, hy, fixture = etc. etc.

One thing is that the code in that blog post will only return the closest hit fixture to the origin (which the post mentions several times). It shouldn't be hard to expand the use of the Box2d callback into Lua (perhaps by examining the other MOAI callback usage, the input callbacks spring to mind), but I didn't need that functionality so it's not implemented.

I think the problem of the original code on here was simply that it wasn't scaled to the world coordinates. From memory that's the only real change I made to get it working properly.
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm

Re: RayCast for Box2d - Hack

Postby naturally » Wed Oct 09, 2013 7:47 pm

I thought I was losing my mind for a while... I wasn't able to get the raycast to hti anything... then I thought about the unitsToMeters... you have to convert any points you pass via unitsToMeters first!

Thanks a bunch stun.

I will likely attempt to modify it to allow for further hits, but this is a GREAT feature! Kinda the last major technical hurdle I had for my project proof-of-concept. Can't really have proper enemies if they are blind. :)
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby ibisum » Fri Oct 11, 2013 4:22 am

We really need this in the mainline dist of MOAI as soon as possible!
;
--
ibisum@gmail.com
Got a MOAI snippet? Please consider adding it to http://moaisnippets.info/
User avatar
ibisum
 
Posts: 1339
Joined: Mon Oct 17, 2011 1:11 am
Location: Vienna, Austria

Re: RayCast for Box2d - Hack

Postby stun » Fri Oct 11, 2013 8:09 pm

To be honest it probably needs to be generalised into a callback before that happens. This is sort of a hacky interim solution as it only handles the one case (closest fixture hit). The entire Box2d callback with the 'fraction return' functionality should be exposed to Lua so you get full control. Unfortunately I haven't got around to doing that yet...
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm

Re: RayCast for Box2d - Hack

Postby naturally » Sat Oct 12, 2013 8:46 am

I think it would be ideal to have two methods in MOAIBox2DWorld, a "Closest" raycast (this) and the "Full" raycast (unfinished).

Most people probably just need a closest-raycast, so a simple function like what we have now will be very helpful, it would be silly to throw it away and force a more complicated solution on everyone. If people need the extra fixtures they would use the full raycast. However for the sake of consistency the closest raycast function should not be matched to the Box2D name, it should be a unique thing to MOAI, like ... "ClosestRaycast()" :roll:
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby stun » Sat Oct 12, 2013 12:46 pm

Yes not a bad idea. The full raycast lets you do so much more of course, like detect line segments completely inside fixtures etc. which would be very useful for slicing objects. Be an interesting exercise to extend the callback all the way to Lua as well. That's something I haven't tried yet.
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm

Re: RayCast for Box2d - Hack

Postby naturally » Sat Oct 12, 2013 7:21 pm

I took a shot at it but didn't have the time to really get into it. I don't have the knowledge/skills to do it at the moment.

My strategy was to add a b2World pointer to the callback:

Code: Select all
  1. MOAIBox2DRayCastCallback(b2World* world)

  2.   {

  3.      m_fixture = NULL;

  4.          m_point.SetZero();

  5.          m_normal.SetZero();

  6.      m_world = world;

  7.   }

  8.  

  9.   float32 ReportFixture(   b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction)

  10.   {

  11.      return m_world->CallUserRaycastHandler(fixture, point, normal, fraction);

  12.   }

  13.  



Not sure if I should use b2World or MOAIBox2DWorld?
And here is some junk code copied from the body collision handler:

Code: Select all
  1. int MOAIBox2DWorld::_setUserRaycastHandler ( lua_State* L ) {

  2.         MOAI_LUA_SETUP ( MOAIBox2DWorld, "UF" )

  3.        

  4.         self->SetLocal ( state, 2, self->mUserRaycastHandler );

  5.        

  6.         return 0;

  7. }

  8.  

  9. int MOAIBox2DWorld::CallUserRaycastHandler (b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction) {

  10.  

  11.         int fraction = 0;

  12.        

  13.         if ( self->mUserRaycastHandler ) {

  14.        

  15.                 MOAIScopedLuaState state = MOAILuaRuntime::Get ().State ();

  16.                 if ( this->PushLocal ( state, self->mUserRaycastHandler )) {

  17.                        

  18.                         state.Push ( eventType );

  19.                         this->PushLuaUserdata ( state );

  20.                         // ?

  21.                         state.DebugCall ( 4, 0 );

  22.                 }

  23.         }      

  24.  

  25.         return fraction;

  26. }



I just don't understand how the Lua to C++ flow works, and I'm content with the closest raycast, so I gave up. But I would leave the building of an array of fixtures, normals, and points, and the fraction return values to the Lua side.

I'd like the capability to ignore fixtures if they weren't really blocking the view, like a glass wall, or small item. If I really needed that I could either: build a separate box2d world for raycasting (eck), add custom code in c++ (maybe doable), or extend the full raycast (hard/unable).
Naturally Intelligent Software - Lovable games and apps.
User avatar
naturally
 
Posts: 439
Joined: Thu Aug 29, 2013 8:05 pm
Location: Canada

Re: RayCast for Box2d - Hack

Postby stun » Sat Oct 12, 2013 11:52 pm

No that would be entirely doable if we extended the Box2D callback all the way to Lua, as one of the properties of the callback is the fixture that has been hit. The code in that blog post already returns the MOAIBox2DFixture (which is just the userData on the box2D fixture object). So if you could get that information in your Lua callback you could just add additional Lua properties to test again like 'material' for example.

I'll see if I can get anything working this week and tidy up the raycast code I have.
1GAM Dev with MOAI for Android: http://fivevolthigh.com
stun
 
Posts: 200
Joined: Wed Jul 25, 2012 2:31 pm


Return to Physics

Who is online

Users browsing this forum: No registered users and 0 guests

x