vue+threeJs 创建多色几何体+加载obj模型+跳转ojb模型中心

嗨,我是小路。今天主要和大家分享的主题是"vue+threeJs 创建多色几何体+加载obj模型+跳转ojb模型中心"。

项目案例示意图

1.创建网格

定义:创建辅助网格主要用以下方法执行,其中有四个参数

javascript 复制代码
new THREE.GridHelper(大小,分割段数,中心线轴颜色,网格颜色)

|-----------------|-------|
| 属性列表 | 列表说明 |
| size | 大小 |
| divisions | 分割段数 |
| colorCenterLine | 颜色中心线 |
| colorGrid | 颜色网格 |

2.加载obj模型并调整模型中心

定义:获取模型中心,需用用到box3中的getCenter来获取。

javascript 复制代码
const group = new THREE.Group();
const manager = new THREE.LoadingManager();
  const loader = new OBJLoader(manager);
  loader.load('./models/model.obj', function (object) {
    // 计算几何体中心
    const box = new THREE.Box3().setFromObject(object);
    const center = box.getCenter(new THREE.Vector3());
    console.log('obj', object);

    // 将模型几何顶点平移到中心点位置
    object.position.set(-center.x, -center.y, -center.z);
    object.position.y = 100;
    //然后将模型套入group
    group.add(object);
    scene.add(group);
  })

二、实例代码

javascript 复制代码
<!--加载obj-->
<template>
  <div class="pageBox">
    <div class="leftBox" ref="leftRef"></div>
  </div>

</template>
<script setup>
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { getRandomColor, createLight } from '../utils/commonThree';
import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
const leftRef = ref();
// 定义相机输出画布的尺寸(单位:像素px)
let width = window.innerWidth; //宽度
let height = window.innerHeight; //高度
// 创建3D场景对象Scene
const scene = new THREE.Scene();
//设置背景色
scene.background = new THREE.Color(0x646d59);

const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
//三角形缩放过大时,会形成多种三角形形成的背景图
camera.position.x = 100;
camera.position.y = 300;
camera.position.z = 600;

camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt({
  x: 0,
  y: 0,
  z: 0
});

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();



let tubes = [];
let objMesh;
const group = new THREE.Group();
const createObj = () => {
  const manager = new THREE.LoadingManager();
  const loader = new OBJLoader(manager);
  loader.load('./models/model.obj', function (object) {
    // 计算几何体中心
    const box = new THREE.Box3().setFromObject(object);
    const center = box.getCenter(new THREE.Vector3());
    console.log('obj', object);

    // 将模型几何顶点平移到中心点位置
    object.position.set(-center.x, -center.y, -center.z);
    object.position.y = 100;
    //然后将模型套入group
    group.add(object);
    scene.add(group);
  })
  const geometry = new THREE.BoxGeometry(30, 30, 30);
  console.log(geometry);
  const material = [
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
    new THREE.MeshBasicMaterial({
      color: getRandomColor()
    }),
  ];

  const tube = new THREE.Mesh(geometry, material);
  tube.position.set(0, 0, 0);
  return tube;
}

onMounted(() => {

  initData()

  //添加相机空间
  const controls = new OrbitControls(camera, renderer.domElement);
  // 如果OrbitControls改变了相机参数,重新调用渲染器渲染三维场景
  controls.addEventListener('change', function () {
    renderer.render(scene, camera); //执行渲染操作
  });//监听鼠标、键盘事件
  renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
  //将innerHTML置空,避免append重复添加渲染
  leftRef.value.innerHTML = ''
  leftRef.value.append(renderer.domElement);

})
let outSphere;
const initData = () => {
  createLight(scene, 100, 100, 200);
  outSphere = createObj();

  scene.add(outSphere);
  //创建网格辅助线
  const helper = new THREE.GridHelper(1000, 50, getRandomColor(), getRandomColor());
  console.log('helper', helper);
  scene.add(helper);

  render();
}
function render() {
  requestAnimationFrame(render);
  group.rotation.y += 0.01;
  outSphere.rotation.y += 0.01;


  renderer.render(scene, camera);
}
onUnmounted(() => {
  //释放内存
  renderer.dispose();
})


</script>
<style scoped lang="less">
.pageBox {
  width: 100%;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;

  .rightBox {
    width: 100%;
    height: 100%;
  }
}
</style>

三、总结

1、主要注意模型中心位置的调整。目前主要的思路是将obj模型移动到其中心点的位置,然后将其用group包裹,然后让group绕自身旋转。

2、加载obj模型时,需要用loadManager这个方法进行加载。

3、obj模型和gltf模型有很大的不同,gltf有scene,但obj没有。两个方法不同用同一个使用;

都看到这里了,记得【点赞】+【关注】哟。

参考文章:

vue+threeJs 在开发中将部分常用的代码模块封装-CSDN博客

相关推荐
saadiya~10 分钟前
Vue3 + 高德地图实现围栏绘制与线路渲染(含 GeoJSON 支持)
vue.js
酷爱码29 分钟前
CSS3实现的账号密码输入框提示效果
前端·javascript·css3
NoneCoder34 分钟前
React Context 与状态管理:用与不用
前端·react.js·面试
不爱吃饭爱吃菜34 分钟前
uniapp小程序开发,判断跳转页面是否需要登录方法封装
开发语言·前端·javascript·vue.js·uni-app
霸王蟹37 分钟前
React 泛型组件:用TS来打造灵活的组件。
前端·学习·react.js·typescript·前端框架
菥菥爱嘻嘻40 分钟前
React---day3
javascript·react.js·ecmascript
Dontla41 分钟前
React声明式编程(手动控制,大型项目,深度定制)与Vue响应式系统(自动优化,中小型项目,快速开发)区别
javascript·vue.js·react.js
阳光开朗大男孩 = ̄ω ̄=1 小时前
【JavaScript】Ajax 侠客行:axios 轻功穿梭服务器间
前端·javascript·ajax
顽强d石头1 小时前
微信小程序关于截图、录屏拦截
前端
新中地GIS开发老师1 小时前
25年GIS开发暑期实训营,15天Get三维可视化智慧城市开发项目
前端·人工智能·智慧城市·web·gis开发·webgis·地信