Mesh following path3D

Hi, i need move a mesh (mortar grenade) over path 3D :

mi code

class MortarGrenade{
//....

dead(){
    if( this.mode ){
      this.step = 0;
      this.mode = false;
      this.mesh.setEnabled(false);
      this.path_points=[];
      this.bezier=null;
      this.path.setEnabled(false);
    }
    
  }//fin de dead

  shoot(_from, _to){

    this.bz_points[0] = _from;
    this.bz_points[3] = _to;
    this.pos_start = _from;
    this.pos_end = _to;
    let _x = this.pos_start.x + 0.2 * (this.pos_end.x - this.pos_start.x);
    let _z = this.pos_start.z + 0.2 * (this.pos_end.z - this.pos_start.z);
    this.bz_points[1].x = _x;
    this.bz_points[1].y = this.taller;
    this.bz_points[1].z = _z;

    _x = this.pos_start.x + 0.7 * (this.pos_end.x - this.pos_start.x);
    _z = this.pos_start.z + 0.7 * (this.pos_end.z - this.pos_start.z);
    this.bz_points[2].x = _x;
    this.bz_points[2].y = this.taller;
    this.bz_points[2].z = _z;

    // console.log( this.bz_points );
    
    this.bezier = BABYLON.Curve3.CreateCubicBezier(this.bz_points[0],this.bz_points[1],this.bz_points[2],this.bz_points[3],this.max_points);
    
    this.path_points = this.bezier.getPoints();
    console.log( this.name );
    console.log( this.path_points );
    this.path = BABYLON.Mesh.CreateLines(this.name+"_path", this.path_points, scenes[this.parent_scene]);
    this.path.color = new BABYLON.Color4(1, 0.6, 0,0.3);
    this.step = 0;
    this.old_step =0;
    this.mesh.position = this.path_points[this.step];
    this.mesh.setEnabled(true);
    this.mode = true;
    this.total_points = this.path_points.length-1;
    this.path3d = new BABYLON.Path3D(this.path_points, scenes[this.parent_scene]);
    this.normals = this.path3d.getNormals();
    console.log( this.total_points );
  }//fin de dispara

  update(){
    
    if( this.forward.counter > 0 ){
      this.forward.counter-=1;
      if( this.forward.counter == 0 ){
        this.forward.counter=this.forward.max;
        this.step += 1;

        //determinar angulo de rotacion
        if( this.step < (this.total_points)){   
          
          //FAIL
          // let _theta = Math.acos(BABYLON.Vector3.Dot(this.tangents[this.step],this.tangents[this.step+1]));  //amount of turn
          // let _dir = BABYLON.Vector3.Cross(this.tangents[this.step],this.tangents[this.step+1]).y; //enables direction of turn to be found depending if +ve or -ve
          // let _dor = _dir/Math.abs(_dir); //dir takes value 1 or -1
          // this.mesh.rotate(BABYLON.Axis.Y, _dor * _theta, BABYLON.Space.WORLD);

          // this.mesh.rotate(BABYLON.Axis.Y, this.normals[this.step].y, BABYLON.Space.LOCAL);

          this.mesh.rotation = this.normals[this.step];
        }
        
        this.old_step = this.step;

        if( this.step >= this.max_points ){
          this.dead();
          return;
        }
        this.mesh.position = this.path_points[this.step];
      }
    
    }
    

    

  }//fin de update

  
  static runNext(_from,_to){
    //determinar puntos intermedios
    mortar_grenade_index+=1;
    if( mortar_grenade_index >= mortar_grenade_max ){
      mortar_grenade_index=0;
    }
    
    if( !mortar_grenades[mortar_grenade_index].mode ){
      mortar_grenades[mortar_grenade_index].shoot(_from,_to);
    }

  }//fin de run next / end of run next
}

in 2d is ok for me :

How to control/smoothen the rotation of an object moving along a 3D Path? - Questions - Babylon.js (babylonjs.com)

A reference that might be useful to you?

Hey,

This is what I did for my fireball projectiles, should fit what you’re looking for.

      var points = [startPosition, endVector];
      var path = new Path3D(points);
      var i = 0;
      var loop = this._scene.onBeforeRenderObservable.add(() => {
          if (i < 1) {
              projectile.position = path.getPointAt(i);
              i += 0.005;
          }
          // if intesect with a mesh || arrrived a destination
          if (projectile.intersectsMesh(mesh, true) || i > 1) {
                 // do something
          }
      });

thanks.


my approach :

class MortarGrenade {

//....
dead(){
    if( this.mode ){
      this.step = 0;
      this.mode = false;
      this.mesh.setEnabled(false);
      this.path_points=[];
      this.bezier=null;
      this.path.setEnabled(false);
    }
    
  }//fin de dead

  shoot(_from, _to){

    this.bz_points[0] = _from;
    this.bz_points[3] = _to;
    this.pos_start = _from;
    this.pos_end = _to;
    let _x = this.pos_start.x + 0.2 * (this.pos_end.x - this.pos_start.x);
    let _z = this.pos_start.z + 0.2 * (this.pos_end.z - this.pos_start.z);
    this.bz_points[1].x = _x;
    this.bz_points[1].y = this.taller;
    this.bz_points[1].z = _z;

    _x = this.pos_start.x + 0.7 * (this.pos_end.x - this.pos_start.x);
    _z = this.pos_start.z + 0.7 * (this.pos_end.z - this.pos_start.z);
    this.bz_points[2].x = _x;
    this.bz_points[2].y = this.taller;
    this.bz_points[2].z = _z;

    
    this.bezier = BABYLON.Curve3.CreateCubicBezier(this.bz_points[0],this.bz_points[1],this.bz_points[2],this.bz_points[3],this.max_points);
    
    this.path_points = this.bezier.getPoints();
    console.log( this.name );
    console.log( this.path_points );
    this.path = BABYLON.Mesh.CreateLines(this.name+"_path", this.path_points, scenes[this.parent_scene]);
    this.path.color = new BABYLON.Color4(1, 0.6, 0,0.3);
    this.step = 0;
    this.old_step =0;
    this.mesh.position = this.path_points[this.step];
    this.mesh.setEnabled(true);
    this.mode = true;
    this.total_points = this.path_points.length-1;
    this.path3d = new BABYLON.Path3D(this.path_points, scenes[this.parent_scene]);
    
    this.curvePath = this.path3d.getCurve();
    console.log( this.total_points );
  }//fin de dispara

  update(){
    
    if( this.forward.counter > 0 ){
      this.forward.counter-=1;
      if( this.forward.counter == 0 ){
        this.forward.counter=this.forward.max;
        this.step += 1;

        //determinar angulo de rotacion
        if( this.step < (this.total_points)){   
          
          
          this.mesh.lookAt(this.curvePath[this.step + 1] || this.curvePath[0], 0, PI, PI, BABYLON.Space.LOCAL);
          this.mesh.computeWorldMatrix();
          if (!this.mesh.rotationQuaternion) {
            this.mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.mesh.rotation.y, this.mesh.rotation.x, this.mesh.rotation.z);
          }

        }
        
        this.old_step = this.step;

        if( this.step >= this.max_points ){
          this.dead();
          return;
        }
        this.mesh.position = this.path_points[this.step];
      }
    
    }
  
  }//fin de update

  
  static runNext(_from,_to){
    //determinar puntos intermedios
    mortar_grenade_index+=1;
    if( mortar_grenade_index >= mortar_grenade_max ){
      mortar_grenade_index=0;
    }
    
    if( !mortar_grenades[mortar_grenade_index].mode ){
      mortar_grenades[mortar_grenade_index].shoot(_from,_to);
    }

  }//fin ed run next

}//end of class mortar grenade



1 Like