Three.js案例从0到1(5)更酷的对象--变形,缩放

这篇博客介绍了如何利用Three.js库来创建一个3D飞行模拟,包括变形的机舱设计,通过调整BoxGeometry的顶点实现造型变化,并添加了带有动态头发的飞行员模型,通过更新头发的位置来实现动画效果。同时,还展示了如何根据鼠标左右移动调整相机视角,实现飞机模型的缩放效果,为3D场景增添了互动性。
摘要由CSDN通过智能技术生成

1. 变形记,让飞机更漂亮

CSDN只能上传5M的图片,这截屏随便7、8M啊

代码调整

    // 创建更酷的机舱
    var geomCockpit = new THREE.BoxGeometry(80, 50, 50, 1, 1, 1);
    var matCockpit = new THREE.MeshPhongMaterial({
        color: Colors.red,
        shading: THREE.FlatShading
    });
    // 我们可以通过访问形状中顶点数组中一组特定的顶点

// 然后移动它的 x, y, z 属性:

geomCockpit.vertices[4].y-=10;

geomCockpit.vertices[4].z+=20;

geomCockpit.vertices[5].y-=10;

geomCockpit.vertices[5].z-=20;

geomCockpit.vertices[6].y+=30;

geomCockpit.vertices[6].z+=20;

geomCockpit.vertices[7].y+=30;

geomCockpit.vertices[7].z-=20;
    var cockpit = new THREE.Mesh(geomCockpit, matCockpit);
    cockpit.castShadow = true;
    cockpit.receiveShadow = true;
    this.mesh.add(cockpit);

 2. 添加个驾驶飞机的飞行员,酷酷的

定义飞行员

// 创建飞行员
var Pilot = function(){
    this.mesh = new THREE.Object3D();
    this.mesh.name = "pilot";
    // angleHairs是用于后面头发的动画的属性
       this.angleHairs=0;
    // 飞行员的身体
    var bodyGeom = new THREE.BoxGeometry(15,15,15);
    var bodyMat = new THREE.MeshPhongMaterial({color:Colors.brown, shading:THREE.FlatShading});
    var body = new THREE.Mesh(bodyGeom, bodyMat);
    body.position.set(2,-12,0);
    this.mesh.add(body);
   // 飞行员的脸部
    var faceGeom = new THREE.BoxGeometry(10,10,10);
    var faceMat = new THREE.MeshLambertMaterial({color:Colors.pink});
    var face = new THREE.Mesh(faceGeom, faceMat);
    this.mesh.add(face);
    // 飞行员的头发
    var hairGeom = new THREE.BoxGeometry(4,4,4);
    var hairMat = new THREE.MeshLambertMaterial({color:Colors.brown});
    var hair = new THREE.Mesh(hairGeom, hairMat);
     // 调整头发的形状至底部的边界,这将使它更容易扩展。
    hair.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(0,2,0));
   // 创建一个头发的容器
    var hairs = new THREE.Object3D();
    
    // 创建一个头发顶部的容器(这会有动画效果)
    
       this.hairsTop = new THREE.Object3D();


       // 创建头顶的头发并放置他们在一个34的网格中
    for (var i=0; i<12; i++){
      var h = hair.clone();
      var col = i%3;
      var row = Math.floor(i/3);
      var startPosZ = -4;
      var startPosX = -4;
      h.position.set(startPosX + row*4, 0, startPosZ + col*4);
      this.hairsTop.add(h);
    }
    hairs.add(this.hairsTop);
       // 创建脸庞的头发
    var hairSideGeom = new THREE.BoxGeometry(12,4,2);
    hairSideGeom.applyMatrix(new THREE.Matrix4().makeTranslation(-6,0,0));
    var hairSideR = new THREE.Mesh(hairSideGeom, hairMat);
    var hairSideL = hairSideR.clone();
    hairSideR.position.set(8,-2,6);
    hairSideL.position.set(8,-2,-6);
    hairs.add(hairSideR);
    hairs.add(hairSideL);
    
    // 创建后脑勺的头发
    var hairBackGeom = new THREE.BoxGeometry(2,8,10);
    var hairBack = new THREE.Mesh(hairBackGeom, hairMat);
    hairBack.position.set(-1,-4,0)
    hairs.add(hairBack);
    hairs.position.set(-5,5,0);
    this.mesh.add(hairs);
    
    var glassGeom = new THREE.BoxGeometry(5,5,5);
    var glassMat = new THREE.MeshLambertMaterial({color:Colors.brown});
    var glassR = new THREE.Mesh(glassGeom,glassMat);
    glassR.position.set(6,0,3);
    var glassL = glassR.clone();
    glassL.position.z = -glassR.position.z;
    var glassAGeom = new THREE.BoxGeometry(11,1,11);
    var glassA = new THREE.Mesh(glassAGeom, glassMat);
 
    this.mesh.add(glassR);
    this.mesh.add(glassL);
    this.mesh.add(glassA);
    
    
    
    
    var earGeom = new THREE.BoxGeometry(2,3,2);
    
    var earL = new THREE.Mesh(earGeom,faceMat);
    
    earL.position.set(0,0,-6);
    
    var earR = earL.clone();
    
    earR.position.set(0,0,6);
    
    this.mesh.add(earL);
    
    this.mesh.add(earR);
    
    }

让头发动起来


    
    // 移动头发
    
    Pilot.prototype.updateHairs = function(){
    
    
    
    
    // 获得头发
    
       var hairs = this.hairsTop.children;
    
    
    // 根据 angleHairs 的角度更新头发
    
       var l = hairs.length;
    
    for (var i=0; i<l; i++){
    
    var h = hairs[i];
    
    // 每根头发将周期性的基础上原始大小的75%至100%之间作调整。
    
           h.scale.y = .75 + Math.cos(this.angleHairs+i/3)*.25;
    
    }
    
    // 在下一帧增加角度
    
       this.angleHairs += 0.16;
    
    }
    

 

飞机构造添加飞行员模型


    this.pilot = new Pilot();
    this.pilot.mesh.position.set(-10,27,0);
    this.mesh.add(this.pilot.mesh);

动画部分添加

airplane.pilot.updateHairs();  // 让飞行员头发动起来


 3. 让飞机模型随着鼠标左右移动实现缩放

相机缩放调整


 // 随着鼠标左右移动进行一定范围缩放
function updateCameraFov(){
    camera.fov = normalize(mousePos.x,-1,1,40, 80);
    camera.updateProjectionMatrix();
  }
 // 归一化
 function normalize(v,vmin,vmax,tmin, tmax){
    var nv = Math.max(Math.min(v,vmax), vmin);
    var dv = vmax-vmin;
    var pc = (nv-vmin)/dv;
    var dt = tmax-tmin;
    var tv = tmin + (pc*dt);
    return tv;
    
    }

在动画循环里调用此函数


function animate() {
    requestAnimationFrame(animate);
    //海浪效果
    sea.mesh.rotation.z += .005;
    //螺旋桨效果
    airplane.propeller.rotation.x += 0.3;
    //天空效果
    sky.mesh.rotation.z += .01;
    updatePlane();
    airplane.pilot.updateHairs();  // 让飞行员头发动起来
    updateCameraFov();  //缩放效果
    renderer.render(scene, camera);


};

效果还不错

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海里的鱼2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值