Create a download(export) button/function for the 3d model

Hi guys,
I would like to know if it is possible to create the project I have conceived using PlayCanvas. In short, the user must assemble a model from the proposed tool and download this model to his PC.
The main question is to create a download button for the created model.
I found information only in downloading screenshots and I hope that it is possible to download the model as well.

Hi @Alexei_Dobrynovich and welcome,

There isn’t official support for exported models from a PlayCanvas scene.

There is this work in progress glTF exporter by @will (I think it needs an older PlayCanvas engine to launch): PlayCanvas 3D HTML5 Game Engine

Some other users have also played with OBJ export (for mesh geometry export, no material/texture support).

Actually, we have a fully supported glTF exporter here:

It was written by @mvaligursky.

1 Like

So nice, I knew I had to tag Will on this! Very happy that this is officially available :clap:

1 Like

See an example here:
https://playcanvas.github.io/#/loaders/gltf-export

It has limited material support though, only handles the basic material properties. Try to export the glb file from the example, and view it in the viewer: PlayCanvas glTF Viewer

4 Likes

Thank you all for your help @Leonidas , @will , @mvaligursky .
After seeing your answers, I took the plunge and learned JS. Outcome. I was able to make a download button.
But there is one but. The bundle downloads everything below in the hierarchy. Here is a working example (See scene 2)([PlayCanvas | HTML5 Game Engine]).

I tried to do it using Application Events, but it gives an error (Uncaught TypeError: this.downloadGlb is not a function).

`Export.prototype.initialize = function() {
const exporter = new GltfExporter();
const buffer = exporter.buildGlb(this.entity);

var onPlayerMove = function(x, y) {
    this.downloadGlb(buffer);
    console.log('expp');
};
   

this.app.on('ruun', onPlayerMove);

this.on('destroy', function() {
    this.app.off('player:move', onPlayerMove);
});

};`

ButtonLogic.prototype.initialize = function() {

    

    this.entity.button.on('click', function() {

        this.app.fire('ruun');

        console.log('knopca');

    }, this);

    
};

There was another attempt to pass true to the (onPlayerMove) function, to make a while loop that executed this.downloadGlb(buffer);. But I couldn’t interact with the (onPlayerMove) function.

Sorry, I don’t understand what you mean here

At startup, only model (mod _a) is exported. Therefore, I need to bind the export script to the root so that two models are exported (mod_a and mod_b).
image

The way I would do this is to have an Entity as the parent of all the other entities that you want to export.

Then pass that to buildGlb function

image
image
image
image

var Export = pc.createScript('export');
Export.attributes.add('NEntity', { type: 'entity'});
Export.prototype.downloadGlb = function (buffer) {
    var element = document.createElement('a');
    var blob = new Blob([ buffer ], { type: "application/octet-stream" });
    element.href = URL.createObjectURL(blob);
    element.download = 'scene.glb';
    element.style.display = 'none';
    document.body.appendChild(element);
    element.click();
    document.body.removeChild(element);
};

// initialize code called once per entity
Export.prototype.initialize = function() {
       
   
    this.entity.button.on('click', function() {
        const exporter = new GltfExporter();
        const buffer = exporter.buildGlb('NEntity');
        this.downloadGlb(buffer);
        console.log('knopca');
    }, this);
    
  
};

I hope I understood you and did as you suggested. But it gives an error. Or did I make a mistake somewhere?

Almost!

This should be:

        const buffer = exporter.buildGlb(this.NEntity);


New error.
I added you to the project (maybe this will help you better understand)

        const buffer = exporter.buildGlb(this.ENntity);

You made a typo. This should be:

        const buffer = exporter.buildGlb(this.NEntity);
1 Like

I am very sorry for such mistakes. I looked for about two minutes and could not find a difference in your example (vision leads). :sweat_smile:
Thank you very much for your help!