Loading a 3D scene with libGDX

本文介绍了如何使用不同模型文件构建3D场景,并通过代码示例展示了如何加载和渲染这些模型。具体包括从单独的OBJ文件加载模型到合并多个模型为一个场景的过程,以及如何在代码中控制每个模型的位置和旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原始办法:将obj文件load进来,然后依次渲染

  assets = new AssetManager();
  assets.load("data/ship.obj", Model.class);
  assets.load("data/block.obj", Model.class);
  assets.load("data/invader.obj", Model.class);
  assets.load("data/spacesphere.obj", Model.class);

可以用建模工具 maya等 将多个文件合并后导出 FBX 文件,用fbx-conv转换为g3db格式,代码控制model的摆放和数量等

 Model model = assets.get("data/invaders.g3db", Model.class);
        ship = new ModelInstance(model, "ship");
        ship.transform.setToRotation(Vector3.Y, 180).trn(0, 0, 6f);
        instances.add(ship);

        for (float x = -5f; x <= 5f; x += 2f) {
            ModelInstance block = new ModelInstance(model, "block");
            block.transform.setToTranslation(x, 0, 3f);
            instances.add(block);
            blocks.add(block);
        }

        for (float x = -5f; x <= 5f; x += 2f) {
            for (float z = -8f; z <= 0f; z += 2f) {
                ModelInstance invader = new ModelInstance(model, "invader");
                invader.transform.setToTranslation(x, 0, z);
                instances.add(invader);
                invaders.add(invader);
            }
        }

        space = new ModelInstance(model, "space");

直接建模工具设置好 各个模型的整体效果,然后导出文件:

 public void create () {
        ...
        assets = new AssetManager();
        assets.load("data/invaderscene.g3db", Model.class);
        loading = true;
    }

    private void doneLoading() {
        Model model = assets.get("data/invaderscene.g3db", Model.class);
        for (int i = 0; i < model.nodes.size; i++) {
            String id = model.nodes.get(i).id;
            ModelInstance instance = new ModelInstance(model, id);
            Node node = instance.getNode(id);

            instance.transform.set(node.globalTransform);
            node.translation.set(0,0,0);
            node.scale.set(1,1,1);
            node.rotation.idt();
            instance.calculateTransforms();

            if (id.equals("space")) {
                space = instance;
                continue;
            }

            instances.add(instance);

            if (id.equals("ship"))
                ship = instance;
            else if (id.startsWith("block"))
                blocks.add(instance);
            else if (id.startsWith("invader"))
                invaders.add(instance);
        }

        loading = false;
    }

Here's what we changed: First we fetch the invaders model, just like before. As we've seen earlier this contains all models including their name we had in the modeling application. These are stored in the nodes. So we iterate over the nodes and fetch the name (id) of each node. Then we create a ModelInstance using the model and id as arguments, just like we did earlier. On the next line we fetch the node from the instance, which is basically a copy of the node within the model.

Next we set the transformation of the ModelInstance to the transformation of the node. Practically this reads the transformation (like rotation and translation) we set earlier within the modeling application. Then we need to reset the node's transformation, because we now use the ModelInstance transform. For translation this is (0,0,0), for scale this is (1,1,1) and for rotation we set the quaternion to identity. This is followed by a call to calculateTransforms() to make sure the ModelInstance is updated with these new values.

Now that we have the ModelInstance just like it was in the modeling application, we need to add it to our scene. If the id is space, we simply assign the space ModelInstance and continue, because we manually render that. Otherwise we add it to the instances array, so it gets properly rendered. Finally we check the id if it starts with either "ship", "block" or "invader" and accordingly assign the ship ModelInstance or add it to the appropriate Array.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值