Libbulletjme icon indicating copy to clipboard operation
Libbulletjme copied to clipboard

[question] how to set a centre of mass

Open CrazyWords1 opened this issue 9 months ago • 2 comments

Based on the previous issue, I wrote a simple code to turn a json model from Minecraft into a CompoundCollisionShape using boxes.

But I encountered three oddities,

  1. The model does not want to accept setScale normally.
  2. The center of mass at the corner
  3. In minecraft itself, the model does not want to converge with the visual representation, although when using obj and v-hacd4, everything is fine.

P.S(I think I made a mistake in model conversion function, but I don't realize what I made wrong)

public static CompoundCollisionShape createCollisionShapeFromFile(String filename) throws IOException {
        JsonObject rootNode = JsonParser.parseReader(new FileReader(filename)).getAsJsonObject();

        CompoundCollisionShape compoundShape = new CompoundCollisionShape();

        JsonArray elements = rootNode.getAsJsonArray("elements");
        for (JsonElement element : elements) {

            JsonObject elementObj = element.getAsJsonObject();

            Vector3f from = parseVector(elementObj.getAsJsonArray("from"));
            Vector3f to = parseVector(elementObj.getAsJsonArray("to"));
            Vector3f halfExtents = to.subtract(from).multLocal(0.5f);

            BoxCollisionShape boxShape = new BoxCollisionShape(halfExtents);

            Vector3f offset = from.add(halfExtents);

            if (elementObj.has("rotation")) {
                JsonObject rotationObj = elementObj.getAsJsonObject("rotation");
                float angle = (float) Math.toRadians(rotationObj.get("angle").getAsFloat());
                String axis = rotationObj.get("axis").getAsString();
                Vector3f origin = parseVector(rotationObj.getAsJsonArray("origin"));

                Quaternion quaternion = new Quaternion();
                if ("x".equals(axis)) {
                    quaternion.fromAngleNormalAxis(angle, Vector3f.UNIT_X);
                } else if ("y".equals(axis)) {
                    quaternion.fromAngleNormalAxis(angle, Vector3f.UNIT_Y);
                } else if ("z".equals(axis)) {
                    quaternion.fromAngleNormalAxis(angle, Vector3f.UNIT_Z);
                }

                Vector3f correctedOffset = offset.subtract(origin);
                Quaternion vectorQuat = new Quaternion(correctedOffset.x, correctedOffset.y, correctedOffset.z, 0);
                Quaternion resultQuat = quaternion.mult(vectorQuat).multLocal(quaternion.inverse());
                Vector3f rotatedOffset = new Vector3f(resultQuat.getX(), resultQuat.getY(), resultQuat.getZ());
                rotatedOffset.addLocal(origin);

                Transform transform = new Transform(rotatedOffset, quaternion);
                compoundShape.addChildShape(boxShape, transform);
            }
        }

        return compoundShape;
    }

    private static Vector3f parseVector(JsonArray jsonArray) {
        float x = jsonArray.get(0).getAsFloat();
        float y = jsonArray.get(1).getAsFloat();
        float z = jsonArray.get(2).getAsFloat();
        return new Vector3f(x, y, z);
    }

populateSpace

        CompoundCollisionShape shape;
        try {
            shape = createCollisionShapeFromFile("F:\\json_models\\christmas-hat.json");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        PhysicsRigidBody box = new PhysicsRigidBody(shape, 10F);

        physicsSpace.addCollisionObject(box);

        // Visualize the collision objects.
        visualizeShape(floor);
        visualizeShape(box);

Test model - christmas-hat.json изображение

If you can at least give me a hint as to what I'm doing wrong, I'd really appreciate it!

CrazyWords1 avatar May 20 '24 00:05 CrazyWords1