I can't control Camera for my model

I can’t control camera exactly.
Is there any method to display my model.
I have model and I can share model.
There is not error in model. But the size is very large.
In this case, how can I fit my camera to this model?

Hello and welcome to the Babylon community :slight_smile:
Framing behavior might be what you need: Camera Behaviors | Babylon.js Documentation (babylonjs.com)

Thank you for reply.
I will try again.

Hi, @carolhmj ,
Sorry but it doesn’t work.
I have uploaded the model here.

Can you help me?
:slight_smile:

Welcome to the Community,
I’m afraid we do not have enough information to further help here. The model alone won’t really help.
We would need to know what type of camera you are using and see your code if there’s something to debug.
Do you know how to set-up a playground and import your external asset in the playground?

With this playground, you will likely get the answer you are seeking.
Wheras, for your question:

The above answer of using the framingBehavior (camera.useFramingBehavior = true) would likely apply here.
Let us know if you have any questions when trying to set-up your repro in the playground.
Meanwhile, have a great day :sunglasses:

Thank you for your help @carolhmj , @mawa .
I have displayed my model.
How can I rotate my model after display?

Not sure I understand your question correctly.

Do you want to autorotate the camera (in case of an arcRotateCamera targeting your mesh)?… which you can do like that. Here some more details from the doc.

    • OR - -
      Do you want to rotate your model on its axis while the camera remains static?
      Which you can achieve either through an animation or a runtime animation.
      In this case you want to select the root node of the model (or in other words, the parent) and perform a rotate(Vector3) on this parent node.
      Someting like this, among other ways.
      In fact, here it will also depend on how you are loading your model. You have multiple methods and you can also choose to remove the original _root_ node that is created from the conversion of right-handed system (used for i.e. glb and gltf models) to comply with the left-handed system coordinates of babylonjs.

Also in this case, the use of ‘rotation’ needs to follow a few rules. I would urge you to read the doc to learn more about ‘#rotate’ VS ‘#rotation’ VS ‘#rotationQuartenion’. The doc has pretty explicit content and lots of PG to discover, try, fail :wink: and try again :grin:
Hope this helps and meanwhile, have a great day :sunglasses:

1 Like

Thank you for reply. This is current Image.
Current position is not good for me(alpha, beta).
So I want to rotate my model a little.

And next problem is that is auto rotate something when I rotate certain direction.

You should really try provide a PG. It would make things a lot easier for both of us.
If I understand correctly, your model does not show correctly when first displayed to the camera (arcRotateCamera, is it?).
You can rotate the object on itself on the x,y,z axis (Vector3).
myobject.rotation = new BABYLON.Vector3(Math.PI/2, Math.PI/4, 30/57.295)

Though the values from rotation in BJS are based on Math.PI(*2) for a complete revolution.
Where 3.14xx rotates the object half a revolution. If you want to use degrees instead there’s a helper/tool for it.
Now, this will only work if you are not rotating your object afterwards while the axis on this model would not be set correctly. Understand, the axis on the model is already displaced. In this case, you have to either edit the model to set the axis correctly or perform a normalize operation or parent to new and make the correction on the child. You will next use the new parent for your model animations. Though honestly, not knowing of your issue and in the absence of a PG, this is becoming too complex and is only based on assumptions. Not the best way to quickly solve a problem, is it? :sweat_smile: :wink:

1 Like

I have created my playground for this.

Your model is not imported due to CORS policies. I don’t think you can allow cross-origin from google drive to work in the PG (not sure though, I don’t use drive).
For a safe way, you should load your model from one of the ‘reliable sources’ stated in this section of the doc.

I have updated by github source.

But it doesn’t work too.

Hi,
Had a look at it but both the PG and the mesh have/had a number of issues. Fixed a few.
Why it didn’t work? First thing I noticed is that you changed to a free camera but setTarget doesn’t work with it. It creates an e.substract error. Also your import function looked a bit funny to me (not sure what the last line of parameters are for. You create a camera but next you are using the helper ‘createDefaultCameraOrLight’ and set all to true. This one is kind of on the side of BJS because the naming of this helper should actually be createDefaultCameraAndLight. That’s the correct reading. If you create your camera but want default light you can use the helper ‘createDefaultLight’.
Next comes the mesh. I spent 15 minutes just finding it in the scene. When normalizing it, I get very fancy offset values, like miles away from the scene and a scaling of the tiny-mini. The axis must be completely displaced. May be there are even some loose points left around the mesh. And the scaling looks kind of inappropriate. Still sort of managed to at least get in in the screen. That’s how far I went.
Not sure what the initial rotation of the object towards the camera should be?

Great! Thank you very much.
Sorry but How can I display my model to center of scene and auto scale when I import another model(its size is smaller than this).

The same I did here, with this model. Here I quickly added a sphere, you can see the model is already at world zero position.

If you have multiple models from various sources to load and can’t or don’t want to edit them, normalizing to a unitCube and scale them from the bounding box hierarchy is a way I know works. In fact, I’m using this currently in my scene. I’m loading about 60 models of sculptures from sketchfab to display on pods. I’m not using the framingBehavior of the camera but you can simply add it the way it’s now. If some models have a hierarchy with more meshes, you will however want to generate a target from the bounding box hierarchy.

So, basically, it would be an async function you call when loading a model and the base would look something like this (this is a sample based on an extract of my code, parts of it are related to my project and might not apply for your project… and then, there are also other ways to do it):

    //the model to load
    var _modelnum = 0;

    //a variable you can use to track if a model is loaded
    var _display = null;

    //a variable you can use while loading a model (i.e. for a loading sequence or to trigger an event)
    var _modeldone = false;

   const displayMesh = async(scene)=>{

        var url = "scenes/pg/";
        var file = "skull.babylon";
        var descr = "Introduction bla bla bla";

    //models selection
        if(_modelnum == 0){
            url = "scenes/pg/"
            file = "skull.babylon"
            descr = "a skull from the BJS asset library"
        }
        if(_modelnum == 1){
            url = "scenes/Alien/"
            file = "Alien.gltf"
            descr = "An animated alien bust from the BJS asset library"
        }
        if(_modelnum == 2){
            url = "scenes/pg/"
            file = "aerobatic_plane.glb"
            descr = "A funny animated aeroplane from the BJS asset library"
        }   
    
        if (_display == false && _modeldone == true|| _display == null){
            _modeldone = false;
            BABYLON.SceneLoader.ShowLoadingScreen = true;
            adtdisplay.getControlByName("InfoDisplayText").text = "Please wait…"

            const resultPromise = BABYLON.SceneLoader.ImportMeshAsync("", url, file, scene);
                
            resultPromise.then((result) => {

                console.log ("RESULT PROMISE IS DONE")

                result.meshes[0].visibility = 0;

                let loadedmesh = result.meshes[0];

                loadedmesh.name = "displaymesh";
                loadedmesh.normalizeToUnitCube();
                loadedmesh.position = new BABYLON.Vector3.Zero();
                loadedmesh.scaling.scaleInPlace(25);
                //loadedmesh.rotation = new BABYLON.Vector3(0, -Math.PI/2, 0)
                loadedmesh.computeWorldMatrix(true);

                const boundingInfo = loadedmesh.getHierarchyBoundingVectors(true);
                const sizeVec = boundingInfo.max.subtract(boundingInfo.min);
                const halfSizeVec = sizeVec.scale(0.5);
                const center = boundingInfo.min.add(halfSizeVec);
                const Ybottom = sizeVec.scale(0);

                result.meshes[0].position = center.scale(-1);
                //result.meshes[0].position.y += halfSizeVec.y;
                result.meshes[0].position.y += Ybottom.y;
                result.meshes[0].computeWorldMatrix(true)

                //eventually parent your root mesh to a new root (to act on this new root or on the root child, useful to fix things like rotation)
                result.meshes[0].parent = displayroot;

                result.meshes[0].getDescendants().forEach(function(mesh) {
                    //do something for all descendants of the mesh
                    light0.includedOnlyMeshes.push(mesh);
                    light1.includedOnlyMeshes.push(mesh);
                });


                //another example of acting on descendants of the mesh (i.e. for materials)
                result.meshes[0].getDescendants().forEach((mesh)=>{

                    if (mesh.material && mesh.material.getClassName() == "PBRMaterial")
                    {
                        mesh.material.albedoTexture.level = (1 +(_displayvalue2/10));
                        mesh.material.unlit = true;
                    }

                });

                //the promise is done - model is loaded
                _modeldone = true;
                BABYLON.SceneLoader.ShowLoadingScreen = false;

                //eventually use a timeout to ensure the model is fully ready before i.e. running some animation (like an autorotation)
                setTimeout(()=>{
                    console.log("diplaying fully loaded state");
                    _display = true;  
                    displayAutoRot();                        
                    }

                }, 2000) 
            })
        }
    }

///////

EDIT: Forgot to mention that the above operation normalizes each model to a same scale (unitCube scale). This is good if you want to have all your models fit in your camera view and they have no relation in terms of scaling to each other. Of course, if you want your models to keep with their relation in terms of scale, well… then I guess best would be to edit them in a tool and make sure they are all scaled properly on export. Else, you would need to adjust the scaling of each on import (which might be a bit tedious if you have a large number of these).

Thank you @mawa .
It’s good working.
:slight_smile: :kissing_smiling_eyes:

1 Like