Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Box2d Lua module #8712

Merged
merged 15 commits into from Apr 3, 2024
Merged

Added Box2d Lua module #8712

merged 15 commits into from Apr 3, 2024

Conversation

JCash
Copy link
Contributor

@JCash JCash commented Mar 25, 2024

This allows you to get a physics body and manipulate its forces, velocities and other properties.

Example:

local id = factory.create("#factory", position)
local url = msg.url(nil, id, "collisionobject") -- get the collision object in the spawned object
self.body = b2d.get_body(url) -- get the b2body object
b2d.body.dump(self.body) -- debug print

-- add an impulse
local pos = b2d.body.get_position(self.body)
b2d.body.apply_linear_impulse(self.body, vmath.vector3(300,200,0), pos + vmath.vector3(16,16,0))

A full list of functions is available in the reference api for b2d and b2d.body.
Note that this was a first step. Next up is adding the missing structs, e.g. world, joints, fixtures and shapes support.

Fixes #8256
Fixes #8101
Fixes #5405
Fixes #3191
Fixes #3120

PR checklist

  • Code
    • Add engine and/or editor unit tests.
    • New and changed code follows the overall code style of existing code
    • Add comments where needed
  • Documentation
    • Make sure that API documentation is updated in code comments
    • Make sure that manuals are updated (in github.com/defold/doc)
  • Prepare pull request and affected issue for automatic release notes generator
    • Pull request - Write a message that explains what this pull request does. What was the problem? How was it solved? What are the changes to APIs or the new APIs introduced? This message will be used in the generated release notes. Make sure it is well written and understandable for a user of Defold.
    • Pull request - Write a pull request title that in a sentence summarises what the pull request does. Do not include "Issue-1234 ..." in the title. This text will be used in the generated release notes.
    • Pull request - Link the pull request to the issue(s) it is closing. Use on of the approved closing keywords.
    • Affected issue - Assign the issue to a project. Do not assign the pull request to a project if there is an issue which the pull request closes.
    • Affected issue - Assign the "breaking change" label to the issue if introducing a breaking change.
    • Affected issue - Assign the "skip release notes" is the issue should not be included in the generated release notes.

Example of a well written PR description:

  1. Start with the user facing changes. This will end up in the release notes.
  2. Add one of the GitHub approved closing keywords
  3. Optionally also add the technical changes made. This is information that might help the reviewer. It will not show up in the release notes. Technical changes are identified by a line starting with one of these:
    1. ### Technical changes
    2. Technical changes:
    3. Technical notes:
There was a anomaly in the carbon chroniton propeller, introduced in version 8.10.2. This fix will make sure to reset the phaser collector on application startup.

Fixes #1234

### Technical changes
* Pay special attention to line 23 of phaser_collector.clj as it contains some interesting optimizations
* The propeller code was not taking into account a negative phase.

@JCash JCash requested review from Jhonnyg and AGulev March 25, 2024 19:28
@@ -1305,6 +1305,7 @@ namespace dmEngine
script_lib_context.m_HidContext = engine->m_HidContext;
script_lib_context.m_GraphicsContext = engine->m_GraphicsContext;
script_lib_context.m_JobThread = engine->m_JobThreadContext;
script_lib_context.m_ConfigFile = engine->m_Config;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To allow for reading game properties, like physics.scale

Comment on lines 68 to 71
void PushWorld(struct lua_State* L, class b2World* world)
{
lua_pushlightuserdata(L, world);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: add script_box2d_world.cpp with proper user type.

dmGameObject::GetComponentUserDataFromLua(L, index, collection, COLLISION_OBJECT_EXT, (uintptr_t*)comp, 0, comp_world);
}

static int B2D_GetWorld(lua_State* L)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These parts should be moved to a world specific .cpp file

SETCONSTANT(b2BodyType, b2_staticBody);
SETCONSTANT(b2BodyType, b2_kinematicBody);
SETCONSTANT(b2BodyType, b2_dynamicBody);
lua_setfield(L, -2, "b2BodyType");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They'll show up as box2d.b2bodyType.b2_staticBody

Comment on lines +350 to +351
void* GetWorldContext2D(HWorld2D world);
void* GetCollisionObjectContext2D(HCollisionObject2D collision_object);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to resolve the glue between our physics engine and box2d

Comment on lines 454 to 455
//{"get_user_data", Body_GetUserData}, - could return the game object id ?
//{"set_user_data", Body_SetUserData}, - could attach the body to a game object?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting the id of the game object is useful, and it should be possible to set the id as well, with some extra component functions to make sure that the game+physics objects life times are considered.

b2Body* body = dmGameSystem::CompCollisionObjectGetBox2DBody(component);

if (body)
PushBody(L, body);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to make this more robust, as it currently contains an internal pointer, and the game object may be deleted directly after (and along with is the collision object).

E.g. if this has a game object id set, then we need to check it before doing any operations on the body.

{"__tostring", Body_tostring},
{"__eq", Body_eq},

{"get_position", Body_GetPosition},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous extension, uses the Box2D naming style: GetPosition().
Here I'm using the naming style in Defold.

Yay, or nay?

Comment on lines 461 to 465
// {"get_mass_data", Body_GetMassData},
// {"set_mass_data", Body_SetMassData},
// {"reset_mass_data", Body_ResetMassData},
// {"synchronize_fixtures", SynchronizeFixtures},
// SynchronizeSingle(b2Shape* shape, int32 index)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For mvp2

* @name b2body
*/

/**
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied all documentation, but set some to "undocumented" /** until they're implemented.

AGulev
AGulev previously approved these changes Mar 30, 2024
Copy link
Contributor

@AGulev AGulev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it a lot!

A couple of small things should be fixed in docs.

  • tests are still red.

* Set the position of the body's origin and rotation.
* This breaks any contacts and wakes the other bodies.
* Manipulating a body's transform may cause non-physical behavior.
* @name body:set_transform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documentation still uses body:* syntax


/*# Get the user data pointer that was provided in the body definition.
* @name body:get_user_data
* @return id [type: hash] the game object id this body is connected to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function isn't implemented, should be hidden from docs

/** Get the total force currently applied on this object
* @name body:get_force
* @note Defold Specific
* @return force [type: vmath.vector3]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like this function is already implemented but it's commented (as I understand /** - comment out function, and /*# - added function?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

Jhonnyg
Jhonnyg previously approved these changes Apr 2, 2024
Comment on lines 137 to 163
// #define SETCONSTANT(NS, NAME) \
// lua_pushnumber(L, (lua_Number) NS :: NAME); \
// lua_setfield(L, -2, #NAME);


// lua_newtable(L);
// SETCONSTANT(b2Shape, e_circle);
// SETCONSTANT(b2Shape, e_edge);
// SETCONSTANT(b2Shape, e_polygon);
// SETCONSTANT(b2Shape, e_chain);
// lua_setfield(L, -2, "b2Shape");

// lua_newtable(L);
// SETCONSTANT(b2JointType, e_unknownJoint)
// SETCONSTANT(b2JointType, e_revoluteJoint)
// SETCONSTANT(b2JointType, e_prismaticJoint)
// SETCONSTANT(b2JointType, e_distanceJoint)
// SETCONSTANT(b2JointType, e_pulleyJoint)
// SETCONSTANT(b2JointType, e_mouseJoint)
// SETCONSTANT(b2JointType, e_gearJoint)
// SETCONSTANT(b2JointType, e_wheelJoint)
// SETCONSTANT(b2JointType, e_weldJoint)
// SETCONSTANT(b2JointType, e_frictionJoint)
// SETCONSTANT(b2JointType, e_ropeJoint)
// lua_setfield(L, -2, "b2JointType");

// #undef SETCONSTANT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this dead code, debug code, or a todo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of both. I'll remove it.

@JCash JCash dismissed stale reviews from Jhonnyg and AGulev via 1e6dc8a April 2, 2024 10:05
@JCash JCash merged commit acdd78d into dev Apr 3, 2024
22 checks passed
@JCash JCash deleted the script-box2d branch April 3, 2024 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants