three.js 士兵示例(根据规定定位移动)

运用相关:vue3、three.js

模型下载:https://github.com/mrdoob/three.js/  


<template>

  <div ref="sceneRef">

</template>

<script setup>

import {onMounted,ref }from 'vue'

import *as THREEfrom "three"

import { OrbitControls }from 'three/examples/jsm/controls/OrbitControls'

import { GLTFLoader }from 'three/examples/jsm/loaders/GLTFLoader.js'

import gsapfrom 'gsap'

let scene,camera,renderer,orbitControls

let sceneRef =ref()

let model =ref(null)//用于模型移动

let mixer =ref(null)

let clock =new THREE.Clock()

let curve =null

//启动动画

function startAnimation(skinnedMesh, animations, animationName) {

// 申明动画场景

  const m_mixer =new THREE.AnimationMixer(skinnedMesh)

// 查找动画

  const clip = THREE.AnimationClip.findByName(animations, animationName)

if (clip) {

// 播放

    const action =m_mixer.clipAction(clip)

action.play()

}

return m_mixer

}

// 曲线/移动

function makeCurve() {

// 创建曲线

  curve =new THREE.CatmullRomCurve3([

new THREE.Vector3(0,0,0),

new THREE.Vector3(5,0,0),

new THREE.Vector3(0,0,5)

])

// 曲线类型

  curve.curveType ="catmullrom"

  // 设置曲线闭环

  curve.closed =true

  // 设置曲线张力0-1

  curve.tension =0.5

  // 获取点位

  const points =curve.getPoints(100)

// 存储属性

  const geometry =new THREE.BufferGeometry().setFromPoints(points)

// 更改线的颜色

  const material =new THREE.LineBasicMaterial({color:0x000000})

// 生成线

  const  curveObject =new THREE.Line(geometry,material)

// 加入场景

  scene.add(curveObject)

let obj ={num:0 }

gsap.to(obj, {

num:1,

// 时间

    duration:30,

// 循环

    repeat: -1,

// 缓动效果

    ease:'none',

onUpdate() {

let point =curve.getPoint(obj.num)

model.value.scene.position.copy(point)

let pointNext =curve.getPoint(obj.num -0.001)

model.value.scene.lookAt(pointNext)

}

})

// console.log(points)

// console.log('gltf', model)

}

// 引入模型

function loadModel() {

const gltfLoader =new GLTFLoader()

gltfLoader.setPath('/modules/')

.load('Soldier.glb', (gltf) => {

console.log(gltf,'gltf')

// 旋转模型

    gltf.scene.rotation.y =Math.PI

    // 模型缩放

    gltf.scene.scale.set(1,1,1)

// 遍历模型对象(网格对象:改变属性)

    gltf.scene.traverse((object) => {

if (object.isMesh) {

// 阴影

        object.castShadow =true

        // 接受投影

        object.receiveShadow =true

      }

})

// 获取跑步动画

    mixer.value =startAnimation(

gltf.scene,

gltf.animations,

gltf.animations[3].name

    )

model.value = gltf

makeCurve()

scene.add(gltf.scene)

})

}

function init() {

// 场景

  scene =new THREE.Scene()

// 相机 透视相机 fov视场角 aspect宽高比 near靠近摄像机的裁剪平面的距离 far远处的裁剪平面的距离

  camera =new THREE.PerspectiveCamera(75,window.innerWidth /window.innerHeight,0.1,1000)

// 渲染器

  renderer =new  THREE.WebGLRenderer()

// 相机位置

  camera.position.set(5,5,5)

// 相机看向那边

  camera.lookAt(scene.position)

// 添加辅助坐标x(红色),y(绿色),z(蓝色)

  const axes =new THREE.AxesHelper(20)

scene.add(axes)

// 场景背景

  scene.background =new THREE.Color(0xa0a0a0)

// 场景边界雾化效果

  scene.fog =new THREE.Fog(0xa0a0a0,10,30)

// 半球形光源

  const hemiLight =new THREE.HemisphereLight(0xffffff,0x444444)

hemiLight.position.set(0,10,0)

scene.add(hemiLight)

// 创建一个虚拟的球形网格 Mesh 的辅助对象来模拟 半球形光源HemisphereLight

  const hemiLightHelper =new THREE.HemisphereLightHelper(hemiLight,5)

scene.add(hemiLightHelper)

// 地面 Mesh三位网格对象(集合体对象,材质) PlaneGeometry创建平面几何体 MeshPhongMaterial模拟光滑表面的高光效果

  const mesh =new THREE.Mesh(new THREE.PlaneGeometry(100,100),new THREE.MeshPhongMaterial({color:0x999999,depthWrite:false}))

mesh.rotation.x = -Math.PI /2

  mesh.receiveShadow =true

  scene.add(mesh)

// 平行光

  const directionalLight =new THREE.DirectionalLight(0xffffff)

// 灯光需要开启“引起阴影”

  directionalLight.castShadow =true

  // 阴影样式

  directionalLight.shadow.camera.near =0.5

  directionalLight.shadow.camera.far =50

  directionalLight.shadow.camera.left = -10

  directionalLight.shadow.camera.right =10

  directionalLight.shadow.camera.top =10

  directionalLight.shadow.camera.bottom = -10

  directionalLight.position.set(0,5,5)

// 阴影清晰度 默认512

  directionalLight.shadow.mapSize.set(2048,2048)

scene.add(directionalLight)

// 用于模拟场景中平行光 DirectionalLight 的辅助对象. 其中包含了表示光位置的平面和表示光方向的线段

  const directionalLightHelper =new THREE.DirectionalLightHelper(directionalLight,5)

scene.add(directionalLightHelper)

// 渲染阴影

  renderer.shadowMap.enabled =true

  renderer.setSize(window.innerWidth,window.innerHeight)

sceneRef.value.appendChild(renderer.domElement)

}

function animate() {

requestAnimationFrame(animate)

if(mixer.value){

mixer.value.update(clock.getDelta())

}

renderer.render(scene,camera)

}

function initOrbitControls() {

orbitControls =new OrbitControls(camera,renderer.domElement)

// orbitControls.enableDamping = true

  //相机位置与观察目标点最大值

  // orbitControls.maxDistance = 1300

// orbitControls.maxPolarAngle = Math.PI / 2

  // // 上下旋转范围

  // orbitControls.minPolarAngle = -Math.PI / 2 //默认值0

  // orbitControls.maxPolarAngle = Math.PI / 2 //默认值Math.PI

  // // // 左右旋转范围

  // orbitControls.minAzimuthAngle = -Math.PI / 2

// orbitControls.maxAzimuthAngle = Math.PI / 2

}

// 监听窗口大小变化事件

window.addEventListener('resize',function() {

// 更新渲染器尺寸

  renderer.setSize(window.innerWidth,window.innerHeight);

// 更新相机宽高比

  camera.aspect =window.innerWidth /window.innerHeight;

camera.updateProjectionMatrix();

});

onMounted(() => {

init()

loadModel()

initOrbitControls()

animate()

})

<style scoped lang="scss">

</style>



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容