当前位置: 首页 > news >正文

学习threejs,使用JSON格式保存和加载模型

👨‍⚕️ 主页: gis分享者
👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨‍⚕️ 收录于专栏:threejs gis工程师


文章目录

  • 一、🍀前言
    • 1.1 ☘️THREE toJSON()方法
  • 二、🍀使用JSON格式保存和加载模型
    • 1. ☘️实现思路
    • 2. ☘️代码样例


一、🍀前言

本文详细介绍如何基于threejs在三维场景中使用JSON格式保存和加载模型,亲测可用。希望能帮助到您。一起学习,加油!加油!

1.1 ☘️THREE toJSON()方法

通过调用Three.js各个对象的.toJSON()方法可以保存这些对象为json格式,比如你通过Threejs开发一个三维模型编辑系统,想保存Threejs中创建的立方体、球体、obj、glb等三维模型的顶点、材质等数据,就可以通过.toJSON()方法实现。

二、🍀使用JSON格式保存和加载模型

1. ☘️实现思路

  • 1、初始化renderer渲染器
  • 2、初始化Scene三维场景
  • 3、初始化camera相机,定义相机位置 camera.position.set,定义相机方向lookAt。
  • 4、初始化THREE.AmbientLight环境光源,scene场景加入环境光源,初始化THREE.DirectionalLight平行光源,设置平行光源位置,设置平行光源投影,scene添加平行光源。
  • 5、加载几何模型:创建THREE.AxesHelper坐标辅助工具,scene场景加入THREE.AxesHelper坐标辅助工具。
  • 6、加入gui控制,定义重绘方法redraw、模型保存方法save、模型加载方法load,实现细节具体看代码样例。加入controls,加入stats监控器,监控帧数信息。

2. ☘️代码样例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>learn40(使用JSON格式保存和加载模型)</title><script src="lib/threejs/127/three.js-master/build/three.js"></script><script src="lib/threejs/127/three.js-master/examples/js/utils/SceneUtils.js"></script><script src="lib/threejs/127/three.js-master/examples/js/controls/OrbitControls.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/stats.min.js"></script><script src="lib/threejs/127/three.js-master/examples/js/libs/dat.gui.min.js"></script>
</head>
<style>html, body {margin: 0;height: 100%;}canvas {display: block;}
</style>
<body onload="draw()">
</body>
<script>var renderervar initRender = () => {renderer = new THREE.WebGLRenderer({antialias: true})renderer.setClearColor(new THREE.Color(0x000000))renderer.setSize(window.innerWidth, window.innerHeight)document.body.appendChild(renderer.domElement)}var scenevar initScene = () => {scene = new THREE.Scene()}var cameravar initCamera = () => {camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)camera.position.set(-25, 40, 50)camera.lookAt(new THREE.Vector3(-25, 0, 0))}var lightvar initLight = () => {scene.add(new THREE.AmbientLight(0x404040))light = new THREE.DirectionalLight(0xffffff)light.position.set(1, 1, 1)scene.add(light)}var initModel = () => {var helper = new THREE.AxesHelper(50)scene.add(helper)}var statsvar initStats = () => {stats = new Stats()document.body.appendChild(stats.dom)}var controls, knot, loadedMeshvar initGui = () => {//声明一个保存需求修改的相关数据的对象controls = {"radius": 13,"tube": 1.7,"radialSegments": 156,"tubularSegments": 12,"p": 3,"q": 4,"heightScale": 3.5,"rotate": false,redraw: function () {// 删除掉原有的模型if (knot) scene.remove(knot)// 创建一个环形结构///<param name ="radius" type="float">环形结半径</param>///<param name ="tube" type="float">环形结弯管半径</param>///<param name ="radialSegments" type="int">环形结圆周上细分线段数</param>///<param name ="tubularSegments" type="int">环形结弯管圆周上的细分线段数</param>///<param name ="p" type="float">p\Q:对knot(节)状方式有效,控制曲线路径缠绕的圈数,P决定垂直方向的参数.</param>///<param name ="q" type="float">p\Q:对knot(节)状方式有效,控制曲线路径缠绕的圈数,Q决定水平方向的参数.</param>///<param name ="heightScale" type="float">环形结高方向上的缩放.默认值是1</param>var geom = new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q), controls.heightScale)//判断绘制的模型knot = createMesh(geom)// 将新创建的模型添加进去scene.add(knot)},save: function () {console.log(knot)var result = knot.toJSON()localStorage.setItem("json", JSON.stringify(result))},load: function () {scene.remove(loadedMesh)var json = localStorage.getItem("json")if (json) {var loadedGeometry = JSON.parse(json)var loader = new THREE.ObjectLoader()loadedMesh = loader.parse(loadedGeometry)loadedMesh.position.x -= 50scene.add(loadedMesh)console.log(loadedMesh)}}};var gui = new dat.GUI()//将设置属性添加到gui当中,gui.add(对象,属性,最小值,最大值)gui.add(controls, 'size', 0, 10).onChange(controls.redraw);var loadFolder = gui.addFolder("保存/加载")loadFolder.add(controls, "save")loadFolder.add(controls, "load")var meshFolder = gui.addFolder("模型相关");meshFolder.add(controls, 'radius', 0, 40).onChange(controls.redraw)meshFolder.add(controls, 'tube', 0, 40).onChange(controls.redraw)meshFolder.add(controls, 'radialSegments', 0, 400).step(1).onChange(controls.redraw)meshFolder.add(controls, 'tubularSegments', 1, 20).step(1).onChange(controls.redraw)meshFolder.add(controls, 'p', 1, 10).step(1).onChange(controls.redraw)meshFolder.add(controls, 'q', 1, 15).step(1).onChange(controls.redraw)meshFolder.add(controls, 'heightScale', 0, 5).onChange(controls.redraw)meshFolder.add(controls, 'rotate')controls.redraw()}var step = 0var render = () => {if (controls.rotate) {knot.rotation.y = step += 0.01}renderer.render(scene, camera)}var generateSprite = () => {var canvas = document.createElement('canvas')canvas.width = 16canvas.height = 16var context = canvas.getContext('2d')var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2)gradient.addColorStop(0, 'rgba(255,255,255,1)')gradient.addColorStop(0.2, 'rgba(0,255,255,1)')gradient.addColorStop(0.4, 'rgba(0,0,64,1)')gradient.addColorStop(1, 'rgba(0,0,0,1)')context.fillStyle = gradientcontext.fillRect(0, 0, canvas.width, canvas.height)var texture = new THREE.Texture(canvas)texture.needsUpdate = truereturn texture}var createPointCloud = () => {var material = new THREE.PointCloudMaterial({color: 0xffffff,size: 3,transparent: true,blending: THREE.AdditiveBlending,map: generateSprite(),depthTest: false})var cloud = new THREE.Points(geom, material)cloud.sortParticles = truereturn cloud}var createMesh = (geom) => {// 创建两面都显示的纹理var meshMaterial = new THREE.MeshNormalMaterial({wireframe: true})meshMaterial.side = THREE.DoubleSide// 生成模型var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, [meshMaterial])return mesh}var onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()render()renderer.setSize(window.innerWidth, window.innerHeight)}var animate = () => {render()stats.update()requestAnimationFrame(animate)}var draw = () => {initRender()initScene()initCamera()initLight()initModel()initGui()initStats()animate()window.onresize = onWindowResize}
</script>
</html>

效果如下:
在这里插入图片描述


http://www.mrgr.cn/news/67544.html

相关文章:

  • ENSP作业——园区网
  • How to use ffmpeg to convert video format from .webm to .mp4
  • 2024年11月6日Day6
  • Linux——Shell的运行原理和Linux文件权限
  • ThreadX在STM32上的移植:F1,F4通用启动文件tx_initialize_low_level.s
  • 如何在 PyQt 中启动“绘图循环”?
  • MELON的难题
  • 数据库 - 一文看懂MongoDB
  • encodeURIComponent和decodeURIComponent的使用场景
  • Misère Nim game
  • 支持高性能结构化数据提取的 Embedding 模型——NuExtract-v1.5
  • 【Python】遇到pandas 和numpy版本不兼容怎么办?
  • 船舶终端设备维修服务设计
  • uniapp开发APP后台保活机制
  • leetcode 3255 长度为 K 的子数组的能量值 II 中等
  • 五个高质量的视频素材下载网站,助力创作更高效
  • wxWidgets GUI设计教程 - 常用控件与复杂布局
  • 脉冲全闭环EtherCAT运动控制器的固件升级
  • linux驱动-i2c子系统框架学习(2)
  • 【测试语言篇二】Python进阶篇:lambda函数、异常和错误处理、Json处理、随机数、星号操作符
  • 钉钉调试微应用整理2
  • 海云安入选软件供应链安全十大代表厂商,软件供应链安全创新成果获认可
  • (十四)JavaWeb后端开发——MyBatis
  • 【Python】轻松解析JSON与XML:Python标准库的json与xml模块
  • 深度学习经典模型之Network in Network
  • 【单例模式】饿汉式与懒汉式以及线程安全