Skip to content
This repository has been archived by the owner on Jun 22, 2022. It is now read-only.

Exported model from Blender 2.83 LTS breaks ForwardRenderer #100

Closed
kungfooman opened this issue Jul 10, 2020 · 13 comments · Fixed by playcanvas/engine#2275
Closed

Exported model from Blender 2.83 LTS breaks ForwardRenderer #100

kungfooman opened this issue Jul 10, 2020 · 13 comments · Fixed by playcanvas/engine#2275
Assignees
Labels

Comments

@kungfooman
Copy link
Contributor

Hi, I used this model all the time for testing (mostly exported by using Blender 2.79), but for some reason it breaks multiple things when exported from Blender 2.83 LTS:

image

Supposed to look like:

image

playcanvas-stable.js:8109 Uncaught TypeError: Cannot read property '_aabbVer' of undefined
    at MeshInstance.get (playcanvas-stable.js:8109)
    at scriptType.OrbitCamera._buildAabb (orbit-camera.js:600)
    at scriptType.OrbitCamera._buildAabb (orbit-camera.js:608)
    at scriptType.OrbitCamera.focus (orbit-camera.js:400)
    at scriptType.<anonymous> (orbit-camera.js:540)
    at scriptType.fire (playcanvas-stable.js:326)
    at scriptType.set (playcanvas-stable.js:41555)
    at Viewer.initializeScene (viewer.js:209)
    at playcanvas-gltf.js:1457
    at parse (playcanvas-gltf.js:1300)
get @ playcanvas-stable.js:8109
OrbitCamera._buildAabb @ orbit-camera.js:600
OrbitCamera._buildAabb @ orbit-camera.js:608
OrbitCamera.focus @ orbit-camera.js:400
(anonymous) @ orbit-camera.js:540
fire @ playcanvas-stable.js:326
set @ playcanvas-stable.js:41555
initializeScene @ viewer.js:209
(anonymous) @ playcanvas-gltf.js:1457
parse @ playcanvas-gltf.js:1300
(anonymous) @ playcanvas-gltf.js:1445
(anonymous) @ playcanvas-gltf.js:1267
loadBuffers @ playcanvas-gltf.js:1248
loadGltf @ playcanvas-gltf.js:1443
loadGltf @ viewer.js:220
fr.onload @ viewer.js:434
load (async)
loadFile @ viewer.js:424
(anonymous) @ viewer.js:489
(anonymous) @ viewer.js:456
6804playcanvas-stable.js:12010 Uncaught TypeError: Cannot read property 'worldTransform' of undefined
    at ForwardRenderer.drawInstance (playcanvas-stable.js:12010)
    at ForwardRenderer.renderForward (playcanvas-stable.js:12477)
    at ForwardRenderer.renderComposition (playcanvas-stable.js:13189)
    at Application.render (playcanvas-stable.js:47367)
    at playcanvas-stable.js:47948

The glTF model for testing:

maila.zip

@mvaligursky
Copy link
Contributor

Hi @kungfooman,

The crash is something we can fix, but as we're about to release new viewer which does not exhibit the crash issue, we might not get to fix the old one.

Try new viewer from here: https://github.com/playcanvas/engine/tree/master/tools/viewer
(you need to have local engine build, or download engine to build folder)

But missing parts of the mesh could perhaps be something to do with the gltf file itself? I tried loading it into 2 other viewers, and they both show missing parts.

threejs https://gltf-viewer.donmccurdy.com/
babylon https://sandbox.babylonjs.com/

@kungfooman
Copy link
Contributor Author

Hi @mvaligursky, thank you for the quick answer! The gltf file itself is indeed missing the body (Blender only exported the selected objects).

So I exported everything now:

image

Thanks for referencing the new viewer, I just have a hard time to understand how it loads an entire model (with textures). I tried to drag&drop the model folder (like this viewer works), but it seems to only support single files (maybe thats something you work on already)

@willeastcott
Copy link
Contributor

@slimbuck Were you planning on supporting loading of unpacked glTF in the new viewer?

@slimbuck
Copy link
Member

Hi @kungfooman @willeastcott, the latest version of the viewer will support dragging multiple files into the viewer. The viewer released with engine 1.31.0 has limited support for multiple files.

@slimbuck
Copy link
Member

@kungfooman I'd suggest migrating to the engine-native glTF support soon as you can.

The engine glTF code is actively maintained and developed, it largely has feature parity with playcanvas-gltf and in some cases has much better support (for example morph targets).

We'll also continue developing the viewer, so if you have any feature requests please shout :)

@kungfooman
Copy link
Contributor Author

Once the new viewer supports folder drag&drop I would like to test/compare the performance, so my feature request would be a "Spawn 8x8" button 😅

@willeastcott
Copy link
Contributor

So I was pretty relaxed about adding that 8x8 feature to the viewer in this repo. But it's a bit of a non-standard feature for a model viewer IMHO. So I probably wouldn't want to add it to the new viewer in the engine repo. But if you want to fork the viewer and add it to your fork, go right ahead. 😄 (BTW, just FYI, we're probably going to move the viewer in the engine repo out into its own repo in the coming days).

@kungfooman
Copy link
Contributor Author

IMHO not having a 8x8 cloning button just shows the inability of these other viewers. When I worked a bit with ThreeJS/glTF it wasn't even possible to clone an animated glTF model and it still has open issues (and the cloning problem dates back to 2016).

https://www.google.com/search?q=gltf+clone+threejs+fail

Being able to quickly and easily clone a model 64 times also allowed me to discover/verify memory/GC issues in the past (like #70)

Looking forward to the new viewer repo 🎉

@mvaligursky
Copy link
Contributor

I'm not saying it's an effective way to add 64 objects, but you can drag & drop while holding Shift (or Ctrl?) and it adds the object without removing what's already there.

@kungfooman
Copy link
Contributor Author

An aspect of this bug is present in both glTF loaders (playcanvas-gltf and glb-parser), they just shine through differently.

So we are all on the same page and analyze the same thing here, this is the full test model:
maila.zip

It defines a scene like this:

    "scenes" : [
        {
            "name" : "Scene",
            "nodes" : [
                0,
                1,
                97,
                100
            ]
        }
    ]

However, as we can see here, glb-loader will have six rootNodes (two more than defined in the scene). Because glb-loader doesn't looks into the scenes key and just searches every node with parent === null:

image

This is how the hierarchy looks in Blender:

image

Point001/Maila_EyeR and Point002/Maila_EyeL are treated as rootNodes, but they are a child of Bip001. This confusion renders the eyes at the wrong position:

image

@mvaligursky
Copy link
Contributor

Good observation, I've noticed that on Friday when looking at some other improvements / optimizations to glb characters. I'll be fixing this shortly. Thanks!

@mvaligursky
Copy link
Contributor

I have a fix for your issue @kungfooman, it should get released soon.
The problem in your case is that you seem to have two nodes referencing left and two nodes referencing right eye mesh, but only one of these nodes each side is part of the scene, the other is not. We didn't handle a case where mesh is not part of the scene, and ended up with undefined node crashing rendering. Now I correctly (I believe) skip creating the meshInstance completely.
But honestly, this seems to point to issue with either model, or exporter. I would not expect valid gltf file to have node referencing mesh that is not used in the scene, as what's the point of it?

@kungfooman
Copy link
Contributor Author

Thank you so much for fixing Glb-parser @mvaligursky

That's a huge argument to switch now, as it even seems to perform faster than playcanvas-gltf (quite hard to compare without materials yet):

clones = [];

/**
 * @summary
 * clones viewer.entities[0] 64 times
 * 8 rows, 8 cols
 * useful for performance tracing
 */

function spawn8x8() {
    var entity = viewer.entities[0];
    if (!entity) {
        console.log("drag&drop an entity first");
        return;
    }
    var padding_x = 0;
    var padding_z = 0;
    for (var i=0; i<entity.model.meshInstances.length; i++) {
        var aabb = entity.model.meshInstances[i].aabb;
        padding_x = Math.max(padding_x, aabb.halfExtents.x * 2);
        padding_z = Math.max(padding_z, aabb.halfExtents.z * 2);
    }
    for (var i=1; i<=8; i++) {
        for (var j=1; j<=8; j++) {
            var clone = entity.clone();
            clone.setLocalPosition(
                i * padding_x,
                0,
                j * padding_z * -1
            );
            clones.push(clone);
        }
    }
    // add all clones to scene
    for (var i=0; i<clones.length; i++) {
        var clone = clones[i];
        viewer.app.root.addChild(clone);
    }
}

spawn8x8();

image

And Glb-parser feels like a "first-class citizen", e.g. no custom-clone-function, simply entity.clone().

I would just like to point out that this issue is not solved for playcanvas-gltf (but probably nobody cares anyway now):

image

But honestly, this seems to point to issue with either model, or exporter. I would not expect valid gltf file to have node referencing mesh that is not used in the scene, as what's the point of it?

Yea, too bad that exporter is written in Python. I had a look once but I find it confusingly hard to debug. I would love a blend format file parser dumping a glTF, written in pure JavaScript (maybe some point in the future).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants