<template>
    <div ref="threeContainer"></div>
</template>

<script setup>
import * as THREE from 'three';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { CSS3DObject, CSS3DRenderer } from 'three/examples/jsm/Addons.js';
import { onMounted, ref } from 'vue';

const threeContainer = ref(null);
let camera, scene, renderer, model, controls, cssRenderer;
let width = 1920;
let height = 1080;
let text = ref('标注1');
const init = () => {
    scene = new THREE.Scene();
    // scene.background = new THREE.Color(0x100c2a);//0x100c2a
    // scene.background.setAlpha(0);
    camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 2000);
    camera.position.set(40, 300, 200);

    renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
    });
    renderer.setSize(width, height);
    threeContainer.value.appendChild(renderer.domElement);

    cssRenderer = initLabelRenderer(threeContainer.value);
    const objLoader = new OBJLoader();
    let mtlLoader = new MTLLoader();
    mtlLoader.load('/src/assets/obj/goats_R&D.mtl', function (materials) {
        materials.preload();
        objLoader.setMaterials(materials);
        objLoader.load('/src/assets/obj/goats_R&D.obj', function (obj) {
            var scale = 0.07 / obj.scale.x;
            obj.scale.set(scale, scale, scale);
            model = obj;
            const box = new THREE.Box3().setFromObject(model);
            const size = box.getSize(new THREE.Vector3())
            // console.log(size,'-----');
            obj.position.set(-size.x * 0.5, -size.y * 0.1, -size.z * 0.5);
            obj.children.forEach((child) => {
                const c = child;
                const cm = c.material;
                cm.emissive = cm.color;
                cm.emissiveMap = cm.map;
            });
            addMarks(text.value);
            scene.add(model);
            animate();
        });
    });
    // loader.load(
    //   '/src/assets/obj/goats_R&D.obj',
    //   (obj) => {
    //     var scale = 0.1 / obj.scale.x;
    //     obj.scale.set(scale, scale, scale);
    //     model = obj;
    //     // 添加光照
    //     // scene.add(new THREE.AmbientLight(0x404040));
    //     scene.add(new THREE.DirectionalLight());
    //     scene.add(model);
    //   },
    //   (xhr) => {
    //     console.log((xhr.loaded / xhr.total * 100) + '% loaded');
    //   },
    //   (error) => {
    //     console.error('An error happened: ', error);
    //   }
    // );

    controls = new OrbitControls(camera, cssRenderer.domElement);
    controls.enableDamping = true;

    animate();
};

// 初始化标注渲染器
const initLabelRenderer = boxElement => {
    const labelRenderer = new CSS3DRenderer();
    labelRenderer.setSize(width, height);
    labelRenderer.domElement.style.position = 'absolute';
    labelRenderer.domElement.style.top = 0;
    boxElement.appendChild(labelRenderer.domElement);
    return labelRenderer;
};


function addMarks(text) {
    //把传入的标注文字通过 canvas 修改为可以添加到场景中的 texture
    const offScreenCanvas = document.createElement('canvas');
    const offScreenCtx = offScreenCanvas.getContext('2d');
    // 配置字体、大小、颜色等
    offScreenCtx.font = '16px 黑体';
    const txt = text;
    const textWidth = offScreenCtx.measureText(txt).width;
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    if (ctx !== null) {
        // pixelRatio: 像素密度
        canvas.width = (5 + textWidth + 5) * 2;
        canvas.height = 18 * 2;
        ctx.setTransform(2, 0, 0, 2, 0, 0);
        ctx.font = '16px 黑体';
        ctx.fillStyle = '#fff'; //标注背景颜色
        ctx.fillRect(0, 0, 5 + textWidth + 5, 18);
        ctx.fillStyle = '#000'; //标注字体颜色
        ctx.fillText(txt, 5, 16);
    }

    // 将标注变成可以添加到场景中的 texture 对象
    const texture = new THREE.CanvasTexture(canvas);


    var geometry2 = new THREE.BufferGeometry();
    var material = new THREE.LineBasicMaterial({ vertexColors: true });
    var color1 = new THREE.Color(0xffffff), color2 = new THREE.Color(0xffffff);
    //定义第一条线
    var p3 = new THREE.Vector3(0, 50, 40);
    var p4 = new THREE.Vector3(4, 23.5, 10);
    const points = [];
    points.push(p3);
    points.push(p4);
    // geometry2.vertices.push(p3);
    // geometry2.vertices.push(p4);
    // geometry2.colors.push(color1, color2);
    geometry2.setFromPoints(points);
    //把线条添加到场景中
    var line2 = new THREE.Line(geometry2, material, THREE.LinePieces);
    scene.add(line2);
    //定义第一个标签
    /**精灵图 */
    // var spriteMaterial2 = new THREE.SpriteMaterial({ map: texture, color: 0xffffff });
    // var sprite2 = new THREE.Sprite(spriteMaterial2);
    // sprite2.position.set(0, 50, 40);
    // sprite2.scale.set(15, 5, 0);
    // scene.add(sprite2);


    /** CSS3D */
    const label = new CSS3DObject(document.createElement('div'));
    label.position.set(0, 50, 40);
    label.scale.set(0.5, 0.5, 0.5);
    label.element.style.backgroundColor = '#fff';
    label.element.innerText = text;
    scene.add(label);
    // 调整显示方向
    // 假设我们要将HTML元素旋转90度绕Y轴，使其从正前方指向右方
    label.rotation.set(-Math.PI / 4,0,  0);

    //定义标记点
    var radius = 0.5, segemnt = 16, rings = 16;
    var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x9afc00 });
    var sphere101 = new THREE.Mesh(new THREE.SphereGeometry(radius, segemnt, rings), sphereMaterial);
    sphere101.position.set(4, 23.5, 10);
    scene.add(sphere101);

    // var group = new THREE.Object3D();
    // group.add(line2);
    // group.add(sphere101);
    // group.add(sprite2);
    // scene.add(group);


}

const animate = () => {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
    cssRenderer.render(scene, camera);
    controls.update();
};

onMounted(() => {
    init();

    window.addEventListener('resize', onWindowResize);
});

const onWindowResize = () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
};

onMounted(() => {
    window.removeEventListener('resize', onWindowResize);
});
</script>

<style>
#threeContainer {
    width: 1920px;
    height: 1080px;
    /* 根据需要调整位置 */
    overflow: hidden;
}
</style>