3

I have a 3D model , containing many child meshes.
I want to "explode" that mesh ... meaning that every child mesh has to move away from a central point exactly like that thread :
Exploded view algorithm for CAD

To do that , I generate a bounding box of the ancestor mesh , with THREE.Box3 , and compute the center with .getCenter() .

The issue here comes from threeJS's scene graph ...
when setting the position of each child , the whole 3D model does explode when I set it to do so in all directions (XYZ) , but when I choose other combinations like X alone , the explode either bugs and spreads in all directions when it shouldn't, or doesn't explode at all .

Here is the code I am using:

/**
 * obj : the current node on the scene graph
 * box_ct_world : a vec3 center of the bounding box
 * 
 */
  explode : function(obj , parent ,  box_ct_world , dif){
    var scene = this.el.sceneEl.object3D ; //I am using Aframe , so this is how I retrieve the whole scene . 
    var object = this.el.object3D ; //same here , this for retrieving the whole 3D model .  
    var speed = 1 ; 

    if(obj instanceof THREE.Mesh){
      var box_center = box_ct_world ; 
      var position = obj.position ; 
      /**
       * so this is the beginning of my troubles : I am considering retrieving a world position instead of a local position... 
       * I have to translate the nodes without the parent matrices interfering . 
       * The current ligne works the same way as if I retrieved local transformations ... exploding on XYZ , but glitching on the other cases . 
       */ 
     position.setFromMatrixPosition(scene.matrixWorld) ; 

     var addx =0 ;
     var addy =0 ;
     var addz =0 ; 

     /**
      * This is the vector from the center of the box to the node . we use that to translate every meshes away from the center
      */
      if(this.data.X === true){
      var addx =(position.x - box_center.x)*this.data.factor *speed ; 

      }
      if(this.data.Y === true){
      var addy =(position.y - box_center.y)*this.data.factor *speed;
      }
      if(this.data.Z === true){
      var addz =(position.z - box_center.z)*this.data.factor *speed; 
      }

      var explode_vectorx=  addx;
            var explode_vectory=  addy;
      var explode_vectorz=  addz;

      /**
       * this is for making the nodes translate back to their original locations
       */
      if(diff < 0 ){
        if(explode_vectorx > 0)
          explode_vectorx = -explode_vectorx ; 
        if(explode_vectory > 0)
          explode_vectory = -explode_vectory; 
        if(explode_vectorz > 0)
          explode_vectorz = -explode_vectorz;


      }
      if(diff > 0 ){
        if(explode_vectorx < 0)
          explode_vectorx = -explode_vectorx ; 
        if(explode_vectory < 0)
          explode_vectory = -explode_vectory; 
        if(explode_vectorz < 0)
          explode_vectorz = -explode_vectorz;
      }


      var vector = new THREE.Vector3(explode_vectorx , explode_vectory, explode_vectorz) ; 
      console.log(vector.x+"    " + vector.y+ "    " + vector.z ); 
      /**
       * and here is my biggest problem :
       * this function seems to use ancestors matrices 
       * I need the nodes to move without calling the ancestors matrices , but still keep their original rotation and scale . 
       */
      obj.position.set(vector.x , vector.y , vector.z ) ;

      if(obj.children.length != 0 ){
        for(var i = 0 ; i < obj.children.length ; i++){
          this.explode(obj.children[i] ,obj,  box_ct_world , dif); 
        }
      }

      }

        else{
            if(obj.children.length != 0 )
                {
                    for(var i = 0 ; i < obj.children.length ; i++){

                        this.explode(obj.children[i] ,obj,  box_ct_world , dif); 

       }            
                }
    }
},

so here is a screenshot using a XYZ explode :
enter image description here

It works pretty fine .

But when using a single axis , like X :
enter image description here

the mesh still goes on all axis as if it was random, when it is supposed to translate only on the X axis . I think this could be fixed by translating the meshes directly in world space , but I don't know how that can be done in threeJS , especially in that case , because I cannot change the values in matrixWorld (A frame is updating the world matrix every frame I think for these objects , so even if I change any value in the matrixWorld , these will be overriden)
thank you all for your help.

Amine Bensalem
  • 362
  • 3
  • 15

0 Answers0