2
\$\begingroup\$

SUMMARY

I need help to create a weld joint that fixes the two bodies together in a way as illustrated in the first image.

ISSUE

I am having an issue where I cannot find out how to weld vertices of two polygonial bodies together while also snapping the edges between each object's vertices together resulting in something like this:

What I want it to be like

Now, I have no real idea how to even get the vertice positions of an active body, so I've tried doing this using one weld joint and creating an anchor at the position of one of the bodies (The one that is being controlled, which is the triangle). I have also not been able to snap the edges together using this method:

What I have achieved

The code to achieve the above:

/* Check for new collisions */
        Array<Contact> contactList = engine.getPhysicsWorld().getContactList();

        /* Iterate through the list of contact events in world */
        for (int i = 0; i < contactList.size; i++) {
            Contact contact = contactList.get(i);

            if (contact.isTouching()) {
                boolean sensorCollided = false;
                Fixture otherFixture = null;
                int sensorVertexNumber = 0;

                /* Iterate through the list of vertices for the current polygon object's body */
                for (int j = 1; j < polygon.getVerticeCount(); j++) {
                    sensorCollided = contact.getFixtureA().equals(polygon.body.getFixtureList().get(j));
                    if (sensorCollided) {
                        otherFixture = contact.getFixtureB();
                        sensorVertexNumber = j;
                        break;
                    }
                    sensorCollided = contact.getFixtureB().equals(polygon.body.getFixtureList().get(j));
                    if (sensorCollided) {
                        otherFixture = contact.getFixtureA();
                        sensorVertexNumber = j;
                        break;
                    }
                }

                /* If the colliding fixtures are sensors */
                if (otherFixture != null && otherFixture.isSensor() &&
                        polygon.body.getFixtureList().get(sensorVertexNumber).isSensor())
                {

                    Entity collision = engine.bodyOwnerLookupTable.get(otherFixture.getBody());
                    Polygon colPolygon = GameEngine.polygonMapper.get(collision);

                    /* Check if already collided with one sensor or not, we want to collide with two to merge */
                    if (colPolygon.sensorCollision == null ||
                            !(colPolygon.sensorCollision.equals(polygon.body.getFixtureList().get(sensorVertexNumber))))
                    {
                        /* If not collided with a sensor, set the first sensor collision to this sensor */
                        if (colPolygon.sensorCollision == null) {
                            colPolygon.sensorCollision = polygon.body.getFixtureList().get(sensorVertexNumber);
                        }

                        /* If this is the second sensor colliding, merge the two bodies together */
                        else {
                            /*int oldSensorVertexNumber = 0;
                            for (int j = 1; j < polygon.getVerticeCount(); j++) {
                                if (colPolygon.sensorCollision.equals(polygon.body.getFixtureList().get(j)))
                                    oldSensorVertexNumber = j;
                            }*/
                            colPolygon.isControlled = true;
                            colPolygon.setParent(polygon);
                            polygon.addChild(colPolygon);

                            /* Create weld joint */
                            WeldJointDef weldJointDef = new WeldJointDef();
                            weldJointDef.initialize(polygon.body, colPolygon.body, polygon.body.getPosition());
                            weldJointDef.collideConnected = false;

                            engine.getPhysicsWorld().createJoint(weldJointDef);
                        }
                    }
                }
            }
        }

If someone knows how to achieve this behaviour, it would be very appreciated if you would let me know how to do it. Thanks.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

SOLUTION

I have somewhat solved my problem, even if it is not the best solution. I present to you an illustration of my solution followed by an explanation of each step:

Solution

  1. At the merging event of two sensors (see step 2), I access the parental fixture of the controlled sensor by calling getUserData(). When I have grabbed my parental fixture, I can access each of it's world transformed vertices by calling ((PolygonShape)fixture.getShape()).getVertex(index, Vector2) (PolygonShape).
  2. At the creation of a body (or attached fixture, see step 3), I create one CircleShape fixture as sensor for each of the edges of the parental fixture. I also give each sensor it's own side ID to know which side of the parental fixture it is on. By doing this, I can now check for a collision with another sensor belonging to another body and initiate a merge event.
  3. When the merge event is run, the body collided with gets removed and a fixture on the controlled body is created with the same shape as it's ancestor. The newly created fixture is then rotated so that the two vertices on each side of each fixture is colliding (Polygon makes it easy to rotate vertices). New sensors for the newly created fixture is created and all actions described in step 2 is made.
  4. At creation of the fixture described in step 3, it's origin of rotation is set to one of the vertices of the edge of the controlled fixture so that rotation will be easier.

Note that no WeldJoints were used in this solution.

Hope my solution helps some people that has the same issue as I had when I wrote this question.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .