首页 > 其他分享 >WebGL_0020:threejs 加载glb模型,加载图片贴图,加载canvas贴图,创建精灵模型并贴图

WebGL_0020:threejs 加载glb模型,加载图片贴图,加载canvas贴图,创建精灵模型并贴图

时间:2024-09-05 17:36:43浏览次数:1  
标签:贴图 const color 模型 THREE child new newMat 加载

1,

import * as THREE from 'three';
import type { MapViewer } from '@/utils/map3d/mapViewer';
import { STATIC_URL } from '@/config';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

const getSpriteMaterial = (color: THREE.Color, text: string) => {
  const canvas = document.createElement('canvas');
  canvas.width = 64;
  canvas.height = 64;

  const context: any = canvas.getContext('2d');
  context.beginPath();
  context.arc(32, 32, 16, 0, 2 * Math.PI);
  context.closePath();
  context.fillStyle = color.getStyle();
  context.fill();

  if (text) {
    context.font = '24px Arial';
    context.textAlign = 'center';
    context.fillStyle = '#FFFFFF';
    context.fillText(text, 32, 41);
  }

  const texture = new THREE.CanvasTexture(canvas);

  return new THREE.SpriteMaterial({ map: texture });
};

//WG ADD 增加获取canvas贴图方法
const getCanvasTexture = (color: THREE.Color, text: string) => {
  const canvas = document.createElement('canvas');
  canvas.width = 64;
  canvas.height = 64;
  const context: any = canvas.getContext('2d');
  context.fillStyle = 'blue';
  context.fillRect(0, 0, 100, 100);
  if (text) {
    context.font = '30px Arial';
    context.textAlign = 'center';
    context.fillStyle = '#ffffff';
    context.fillText(text, 32, 41);
  }
  const texture = new THREE.CanvasTexture(canvas);
  texture.flipY = false;
  return texture;
};

const useViewHelper = (mapViewer: MapViewer) => {
  const viewer = mapViewer.viewer;
  const helperGroup = new THREE.Group();
  const interactiveObjects: Array<THREE.Object3D> = [];

  const color1 = new THREE.Color('#ff4000');
  const color2 = new THREE.Color('#0032ff');
  const color3 = new THREE.Color('#46ff00');
  const color4 = new THREE.Color('#888888');

  const width = 150;
  const offsetX = 300;
  const viewport = new THREE.Vector4();

  const domElement = viewer.renderer.domElement;

  // const orthoCamera = new THREE.OrthographicCamera(-2, 2, 2, -2, -10, 10);
  const orthoCamera = new THREE.OrthographicCamera(-2, 2, 2, -2, -2, 2);
  // const orthoCamera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);
  orthoCamera.position.set(0, 0, 0);
  //WG orthoCamera.rotation.order = 'ZXY';
  // orthoCamera.rotation.order = 'ZXY';
  // orthoCamera.rotation.x = Math.PI / 2;
  orthoCamera.lookAt(new THREE.Vector3(0, 0, -1));
  orthoCamera.updateMatrixWorld();

  const cameraChange = (e: any) => {
    // console.log(e.camera);
    orthoCamera.rotation.copy(e.camera.rotation);
    orthoCamera.updateMatrixWorld();
  };

  let handleMouseDown = (event: any) => {
    let mouse = new THREE.Vector2();

    const rect = domElement.getBoundingClientRect();
    const x = rect.left + domElement.clientWidth - width - offsetX;
    mouse.x = event.clientX - x;
    mouse.y = event.clientY - rect.top;

    if (mouse.x < 0 || mouse.y > width) return;

    mouse.x = (mouse.x / width) * 2 - 1;
    mouse.y = -(mouse.y / width) * 2 + 1;

    let raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, orthoCamera);
    raycaster.ray.origin.sub(orthoCamera.getWorldDirection(new THREE.Vector3()));

    let intersects = raycaster.intersectObjects(interactiveObjects);

    console.log(intersects);
    if (intersects.length > 0) {
      mapViewer.setViews(intersects[0].object.name);
    }
  };

  const renderHelper = () => {
    const x = domElement.offsetWidth - width - offsetX;
    const y = domElement.offsetHeight - width;

    viewer.renderer.getViewport(viewport);

    viewer.renderer.setViewport(x, y, width, width);

    viewer.renderer.render(helperGroup, orthoCamera);

    viewer.renderer.setViewport(viewport.x, viewport.y, viewport.z, viewport.w);
  };


  //WG ADD 增加加载模型的方法
  // function loadMod() {
  //   let terminalGeo: THREE.BufferGeometry | null = null;
  //   let gltfLoader = new GLTFLoader();
  //   let terminalMeh: THREE.Mesh | null = null;
  //   return new Promise(resovle => {
  //     gltfLoader.load(`${STATIC_URL}/model/terminal.glb`, (gltf) => {
  //       const model = gltf.scene.getObjectByName('平面') as THREE.Mesh;
  //       terminalGeo = model.geometry as THREE.BufferGeometry;
  //       const material = new THREE.MeshBasicMaterial({ color: '#e5380a' });
  //       terminalMeh = new THREE.Mesh(terminalGeo.clone(), material);
  //       helperGroup.add(terminalMeh);
  //       resovle(terminalMeh);
  //     });
  //   });
  // };
  // await loadMod();


  function create() {


    // const geometry = new THREE.BoxGeometry(0.8, 0.02, 0.02);
    // geometry.translate(0.4, 0, 0);
    // // X轴
    // const xAxis = new THREE.Mesh(
    //   geometry,
    //   new THREE.MeshBasicMaterial({
    //     color: color1,
    //     side: 2,
    //     depthWrite: false
    //   })
    // );

    // const posXAxisHelper = new THREE.Sprite(getSpriteMaterial(color1, 'X'));
    // posXAxisHelper.name = 'R';
    // posXAxisHelper.position.x = 0.8;
    // posXAxisHelper.scale.setScalar(0.4);
    // posXAxisHelper.updateMatrixWorld();

    // const negXAxisHelper = new THREE.Sprite(getSpriteMaterial(color4, '-X'));
    // negXAxisHelper.name = 'L';
    // negXAxisHelper.position.x = -0.8;
    // negXAxisHelper.scale.setScalar(0.4);
    // negXAxisHelper.updateMatrixWorld();

    // // Y轴
    // const yAxis = new THREE.Mesh(
    //   geometry,
    //   new THREE.MeshBasicMaterial({
    //     color: color2,
    //     side: 2,
    //     depthWrite: false
    //   })
    // );
    // yAxis.rotation.y = -Math.PI / 2;
    // yAxis.updateMatrixWorld();

    // const posYAxisHelper = new THREE.Sprite(getSpriteMaterial(color2, 'Y'));
    // posYAxisHelper.name = 'U';
    // posYAxisHelper.position.z = 0.8;
    // posYAxisHelper.scale.setScalar(0.4);
    // posYAxisHelper.updateMatrixWorld();

    // const negYAxisHelper = new THREE.Sprite(getSpriteMaterial(color4, '-Y'));
    // negYAxisHelper.name = 'F';
    // negYAxisHelper.position.z = -0.8;
    // negYAxisHelper.scale.setScalar(0.4);
    // negYAxisHelper.updateMatrixWorld();

    // // Z轴
    // const zAxis = new THREE.Mesh(
    //   geometry,
    //   new THREE.MeshBasicMaterial({
    //     color: color3,
    //     side: 2,
    //     depthWrite: false
    //   })
    // );
    // zAxis.rotation.z = Math.PI / 2;
    // zAxis.updateMatrixWorld();

    // const posZAxisHelper = new THREE.Sprite(getSpriteMaterial(color3, 'Z'));
    // posZAxisHelper.name = 'B';
    // posZAxisHelper.position.y = 0.8;
    // posZAxisHelper.scale.setScalar(0.4);
    // posZAxisHelper.updateMatrixWorld();

    // const negZAxisHelper = new THREE.Sprite(getSpriteMaterial(color4, '-Z'));
    // negZAxisHelper.name = 'D';
    // negZAxisHelper.position.y = -0.8;
    // negZAxisHelper.scale.setScalar(0.4);
    // negZAxisHelper.updateMatrixWorld();


    // let terminalGeo: THREE.BufferGeometry | null = null;
    // let gltfLoader = new GLTFLoader();
    // gltfLoader.load(`${STATIC_URL}/model/terminal.glb`, (gltf) => {
    //   const model = gltf.scene.getObjectByName('平面') as THREE.Mesh;
    //   terminalGeo = model.geometry as THREE.BufferGeometry;
    // });

    // if (terminalGeo) {
    //   const material = new THREE.MeshBasicMaterial({ color: '#e5380a' });
    //   const terminalMeh = new THREE.Mesh(terminalGeo.clone(), material);
    //   terminalMeh.addEventListener('drag', handleDrag);
    //   terminalMeh.addEventListener('mouseup', handleMouseup);
    //   terminals.push(terminalMeh);
    //   return terminalMeh;
    // }


    //WG ADD 调用加载模型方法
    // let terminalGeo: THREE.BufferGeometry | null = null;
    let gltfLoader = new GLTFLoader();
    // let terminalMeh: THREE.Mesh | null = null;
    gltfLoader.load(`${STATIC_URL}/model/navbox.glb`, (gltf) => {

      const model = gltf.scene;
      model.traverse((child) => {
        if (child instanceof THREE.Mesh) {

          // // 创建新的材质
          // const newMaterial = new THREE.MeshBasicMaterial({
          //   color: 0xffffff, // 设置你想要的颜色
          //   // map: new THREE.TextureLoader().load(`${STATIC_URL}/model/front.png`) // 设置纹理贴图
          //   map: getCanvasTexture(color4, '前')
          // });
          // // 赋予新的材质
          // child.material = newMaterial;

          let newMat: THREE.MeshBasicMaterial | null = null;
          let lmap: THREE.CanvasTexture | null = null;
          switch (child.name) {
            case 'Front_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: getCanvasTexture(color4, '上')
              });
              child.material = newMat;
              child.name = '上';
              interactiveObjects.push(child);
              break;
            case 'After_1':
              lmap = getCanvasTexture(color4, '下');
              lmap.rotation = THREE.MathUtils.degToRad(180);
              lmap.center.set(0.5, 0.5);
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: lmap
              });
              child.material = newMat;
              child.name = '下';
              interactiveObjects.push(child);
              break;
            case 'Left_1':
              lmap = getCanvasTexture(color4, '左');
              lmap.rotation = THREE.MathUtils.degToRad(90);
              lmap.center.set(0.5, 0.5);
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: lmap
              });
              child.material = newMat;
              child.name = '左';
              interactiveObjects.push(child);
              break;
            case 'Right_1':
              lmap = getCanvasTexture(color4, '右');
              lmap.rotation = THREE.MathUtils.degToRad(-90);
              lmap.center.set(0.5, 0.5);
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: lmap
              });
              child.material = newMat;
              child.name = '右';
              interactiveObjects.push(child);
              break;
            case 'Up_1':
              lmap = getCanvasTexture(color4, '前');
              lmap.rotation = THREE.MathUtils.degToRad(180);
              lmap.center.set(0.5, 0.5);
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: lmap
              });
              child.material = newMat;
              child.name = '前';
              interactiveObjects.push(child);
              break;
            case 'Lower_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xffffff,
                map: getCanvasTexture(color4, '后')
              });
              child.material = newMat;
              child.name = '后';
              interactiveObjects.push(child);
              break;



            case 'Horn_1_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '上角4';
              interactiveObjects.push(child);
              break;
            case 'Horn_2_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '上角3';
              interactiveObjects.push(child);
              break;
            case 'Horn_3_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '下角3';
              interactiveObjects.push(child);
              break;
            case 'Horn_4_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '下角4';
              interactiveObjects.push(child);
              break;
            case 'Horn_5_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '上角1';
              interactiveObjects.push(child);
              break;
            case 'Horn_6_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '上角2';
              interactiveObjects.push(child);
              break;
            case 'Horn_7_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;
              child.name = '下角2';
              interactiveObjects.push(child);
              break;
            case 'Horn_8_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0xFFFFFF,
                side: THREE.DoubleSide
              });
              child.material = newMat;

              child.name = '下角1';
              interactiveObjects.push(child);
              break;



            case 'Up_front_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '上边3';
              interactiveObjects.push(child);
              break;
            case 'Right_up_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '中边3';
              interactiveObjects.push(child);
              break;
            case 'Up_after_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '下边3';
              interactiveObjects.push(child);
              break;
            case 'Left_up_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '中边4';
              interactiveObjects.push(child);
              break;
            case 'Left_front_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '上边4';
              interactiveObjects.push(child);
              break;
            case 'Right_front_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '上边2';
              interactiveObjects.push(child);
              break;
            case 'Right_after_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '下边2';
              interactiveObjects.push(child);
              break;
            case 'Left_after_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '下边4';
              interactiveObjects.push(child);
              break;
            case 'Lower_front_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '上边1';
              interactiveObjects.push(child);
              break;
            case 'Right_lower_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '中边2';
              interactiveObjects.push(child);
              break;
            case 'Lower_after_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '下边1';
              interactiveObjects.push(child);
              break;
            case 'Left_lower_1':
              newMat = new THREE.MeshBasicMaterial({
                color: 0x5A5858
              });
              child.material = newMat;
              child.name = '中边1';
              interactiveObjects.push(child);
              break;
            
            default:
              break;
          }

        }
      });

      helperGroup.add(model);

    });

    viewer.addEventListener('camera_changed', cameraChange);

    viewer.addEventListener('render.pass.perspective_overlay', renderHelper);

    domElement.addEventListener('mousedown', handleMouseDown, false);
  }

  function dispose() {
    if (interactiveObjects.length > 0) {
      helperGroup.traverse((item: any) => {
        if (item.geometry) {
          item.geometry.dispose();
          item.material.map?.dispose();
          item.material.dispose();
        }
      });

      helperGroup.children.length = 0;
      interactiveObjects.length = 0;

      viewer.removeEventListener('camera_changed', cameraChange);
      viewer.removeEventListener('render.pass.perspective_overlay', renderHelper);

      domElement.removeEventListener('mousedown', handleMouseDown);
    }
  }

  return {
    create,
    dispose
  };
};

export { useViewHelper };

 

标签:贴图,const,color,模型,THREE,child,new,newMat,加载
From: https://www.cnblogs.com/eliteboy/p/18398922

相关文章

  • 【大模型专栏—百日文“新”】天下苦Transformer久矣
    大模型专栏介绍......
  • Biome-BGC生态系统模型与Python融合技术实践应用
    Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数,模拟日尺度碳、水和氮通量的有效模型,其研究的空间尺度可以从点尺度扩展到陆地生态系统。在Biome-BGC模型中,对于碳的生物量积累,采用光合酶促反应机理模型计算出每天的初级生产力(GPP),将生长呼吸和维持呼吸减去后的产物......
  • llama factory LoRA微调qwen大模型 | 新手炼丹记录(1)
            之前用本地机器微调qwen大模型,结果由于显存不够或者其他配置问题,总是无法正常训练,莫名其妙报错。只能去尝试一些参数很小的模型,qwen2:0.5b、gemma:2b之类的,实在不够看。    今天尝试使用了算力平台AutoDL算力云租赁计算资源来跑微调以及量化,尝试了qwe......
  • 三星的MobileQuant:将高性能语言模型带到你的口袋中
    大型语言模型(LLMs)在语言处理方面取得了显著成果,并广泛应用于各种场景。然而,在移动设备(如手机)上实现LLMs存在许多挑战,特别是在内存、能耗和计算需求方面的限制。这些制约因素阻碍了LLMs在此类设备上的广泛应用。一种有前景的解决方案是减少权重和激活的位宽,使8位激活成为在设备......
  • 2024 年 5 亿大模型新应用井喷即将到来,算力问题该如何解决?2024 年 5 亿大模型新应用井
    在科技飞速发展的2024年,我们正站在大模型应用爆发的前沿。预计将有5亿大模型新应用如雨后春笋般涌现,为各行各业带来前所未有的变革。然而,在这令人兴奋的前景背后,算力问题却成为了制约其发展的关键瓶颈。大模型的训练和运行需要巨大的计算资源,其对算力的需求呈指数级增长。传统......
  • AI 大模型催生的新职业,提示词工程师是什么?
    全方位解析“提示词工程师”。AI大模型技术正以前所未有的速度重塑我们的未来。它们不仅仅是冷冰冰的算法集合,更是拥有无限创造力的智能体。而在这个智能体的背后,有一群关键的角色——提示词工程师(PromptEngineer)。顾名思义,这类人是专门负责设计和优化AI大模型的提示词,......
  • 每一个企业,都值得拥有自己专属的AI大模型
    大模型技术的发展日新月异,模型参数规模越做越大,能处理的文本长度、多模态融合等方面也在快速演进。然而,如何将这些大模型的潜力在企业中落地应用,仍然是业界面临的一大挑战。企业业务场景千差万别,大模型必须经过针对性的训练和微调,才能有效适应不同企业的需求和业务流程。......
  • 大模型时代的开发者成长指南
    在近一年的时间里,ChatGPT的横空出世带来整个软件开发行业的一系列新变化。不论是个人、团队,还是公司的CXO们,都在关注生成式AI带来的效率提升。在产品研发方面,生成式AI(AIGC)已经开始影响产品生命周期的各个阶段。它可以用于生成候选产品设计,优化产品设计,提升产品测试......
  • 豆瓣评分7.9!AI大模型时代利器:LangChain入门指南
    2023年,LLM(大语言模型)井喷式爆发,尤其是GPT-4问世,一石激起千层浪,影响了整个人工智能领域,每个开发者都被“裹挟”着进入了LLM应用开发时代。在这样的大背景下,LangChain这个以LLM为核心的开发框架应运而生,进一步推动了这一领域的创新和发展。LangChain不仅可以用于开发......
  • 大模型微调方法和技术路线
    带你快速了解大模型微调原理目前传统的Fine-Tuning有两个痛点问题:降低语义差异(BridgethegapbetweenPre-trainingandFine-tuning):预训练任务主要以MaskedLanguageModeling(MLM)为主,而下游任务(DownStreamTask)则重新引入新的训练参数,因此两个阶段的目标通常有较大......