0

我正在使用 WebGL 项目在全球范围内绘制线。它正在使用three.js,绘图正常进行,我无法弄清楚如何标记绘图开始和结束的点。如果可能的话,有人可以帮助我吗?如果有人可以提供帮助,我将不胜感激。代码如下:

<script>
        var planetTilt = latlngDeg2rad(23.5);
        console.log(planetTilt);
        var planetRadius = 6378;
        var rotationSpeed = 0;
        var cloudsScale = 1.02;
        var height = window.innerHeight;
        var width = window.innerWidth;
        var camera, controls, scene, renderer, geometry, meshPlanet, meshClouds;
        var clock = new THREE.Clock();
        var cameraZoomFactor = 6;
        var displayHelp = false;
        var curZoom = 100;
        var markerGeom;
        var markerMaterial;
        var stats;

        function onWindowResize(event) {
            width = window.innerWidth;
            height = window.innerHeight;

            renderer.setSize(width, height);

            camera.aspect = width / height;
            camera.updateProjectionMatrix();

            controls.screen.width = width;
            controls.screen.height = height;

            camera.radius = (width + height) / 4;
        }

        function init() {
            if (!Detector.webgl) Detector.addGetWebGLMessage();

            scene = new THREE.Scene();

            renderer = new THREE.WebGLRenderer({
                clearAlpha: 1,
                clearColor: 0x000000,
                antialias: true
            });
            renderer.setSize(width, height);
            renderer.sortObjects = true;
            renderer.autoClear = false;
            renderer.gammaInput = true;
            renderer.gammaOutput = true;

            renderer.domElement.style.position = 'absolute';
            var container = document.getElementById('container');
            container.appendChild(renderer.domElement);

            camera = new THREE.PerspectiveCamera(25, width / height, 50, 1e7);
            camera.position.z = planetRadius * cameraZoomFactor;
            scene.add(camera);

            controls = new THREE.TrackballControls(camera, renderer.domElement);
            controls.rotateSpeed = 0.3;
            controls.noZoom = true;
            controls.noPan = true;
            controls.staticMoving = false;
            controls.dynamicDampingFactor = 0.4;

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.bottom = '0px';
            stats.domElement.style.right = '0px';

            document.body.appendChild( stats.domElement );

            var dirLight = new THREE.DirectionalLight(0xFFFFFF);
            dirLight.position.set(1, 0, 1)
                .normalize();
            scene.add(dirLight);
            var camLight = new THREE.DirectionalLight(0xffffff);
            camera.add(camLight);

            var ambientLight = new THREE.AmbientLight(0x999999);
            scene.add(ambientLight);

            var planet = new cpPlanet({
                planet_radius: planetRadius,
                planet_tilt_rad: planetTilt,
                planet_cloud_texture: "common/textures/cloud.png",
                planet_surface_texture: "common/textures/earth_surface.jpg",
                planet_normals_texture: "common/textures/earth_normals.jpg",
                planet_specular_texture: "common/textures/earth_specular.jpg",
                planet_geom_segments: 64,
                planet_geom_rings: 64,
                use_surface_shader: true,
                create_combined_mesh: false
            });

            meshPlanet = planet.surface_mesh;
            scene.add(meshPlanet);

            meshClouds = planet.cloud_mesh;
            scene.add(meshClouds);

            // markers and tracks
            var marker_radius = 32;
            var marker_color = 0xff0000;
            markerGeom = new THREE.SphereGeometry(marker_radius, 5, 5);
            markerMaterial = new THREE.MeshPhongMaterial({
                ambient: 0x030303,
                color: marker_color,
                specular: 0x990000,
                shininess: 80,
                shading: THREE.SmoothShading
            });

            // need to update a bunch of stuff when window size changes
            window.addEventListener('resize', onWindowResize, false);
        }

        function animate() {
            requestAnimationFrame(animate);

            var delta = clock.getDelta();

            meshPlanet.rotation.y += rotationSpeed * rotationSpeed * delta;
            meshClouds.rotation.y += rotationSpeed * 1.25 * rotationSpeed * delta;

            controls.update();

            TWEEN.update();

            stats.update();

            renderer.clear();
            renderer.render(scene, camera);
        }

        function addData(locs) {

            var index = Math.floor(Math.random() * locs.length) - 1;
            var start_lat = locs[index].lat;
            var start_lng = locs[index].lng;

            var data_size = 1;
            var start = Math.floor(Math.random() * locs.length) - 1;
            if (start + data_size > locs.length) {
                start = locs.length - data_size - 1;
            }

            var hue = Math.random();

            var i;
            for (i = start; i < start + data_size; i++) {
                var obj = locs[i];
                if (i != index) {
                    addTrack(25.2697, 55.3095, 28.6667, 77.2167, planetRadius, hue+.5);//delhi
                    addMarker(28.6667, 77.2167, planetRadius);
                    addTrack(25.2697, 55.3095, 35.6833, 51.4167, planetRadius, hue+.5);//terhan
                    addMarker(35.6833, 51.4167, planetRadius);
                    addTrack(25.2697, 55.3095, 51.0000, 9.0000, planetRadius, hue+.5);//germany
                    addMarker(51.0000, 9.0000, planetRadius);
                    addTrack(25.2697, 55.3095, 33.6667, 73.1667, planetRadius, hue+.5);//Islamabad
                    addMarker(33.6667, 73.1667, planetRadius);
                    addTrack(25.2697, 55.3095, 31.2000, 121.5000, planetRadius, hue+.5);//Shanghai,
                    addMarker(31.2000, 121.5000, planetRadius);

                }
            }
        }

        function zoomToStart() {
            new TWEEN.Tween({
                scale: 1
            })
                .to({
                scale: 100
            }, 2500)
                .easing(TWEEN.Easing.Elastic.InOut)
                .onUpdate(function () {
                var true_scale = this.scale / 100;
                meshPlanet.scale.set(true_scale, true_scale, true_scale);
                meshClouds.scale.set(true_scale * cloudsScale, true_scale * cloudsScale, true_scale * cloudsScale);
            })
                .start();
        }

        function addMarker(lat, lng, radius) {
            var marker_mesh = new THREE.Mesh(markerGeom, markerMaterial);
            var marker_position = latlngPosFromLatLng(lat, lng, radius);

            marker_mesh.position.x = marker_position.x;
            marker_mesh.position.y = marker_position.y;
            marker_mesh.position.z = marker_position.z;

            marker_mesh.name = "trackmarker";
            meshPlanet.add(marker_mesh);
        }

        function addTrackLine(spline, hue) {
            var num_control_points = 32;
            var i;
            var colors = [];
            var geometry = new THREE.Geometry();
            var pos;

            for (i = 0; i < num_control_points; i++) {
                var index = i / num_control_points;
                pos = spline.getPoint(index);

                colors[i] = new THREE.Color(0xffffff);
                colors[i].setHSV(hue, (1.0 - i / num_control_points), 1.0);

                geometry.vertices.push(new THREE.Vector3(pos.x, pos.y, pos.z));
            }
            pos = spline.getPoint(1.0);
            geometry.vertices.push(new THREE.Vector3(pos.x, pos.y, pos.z));

            geometry.colors = colors;

            var material = new THREE.LineBasicMaterial({
                color: 0xffffff,
                opacity: 1,
                linewidth: 2
            });
            material.vertexColors = true;

            var line = new THREE.Line(geometry, material);
            line.name = "trackline";
            meshPlanet.add(line);
        }

        function addTrack(start_lat, start_lng, end_lat, end_lng, radius, hue) {
            var num_control_points = 8;
            var max_altitude = 500 + Math.random() * 1200;

            var points = [];
            var i;
            for (i = 0; i < num_control_points + 1; i++) {
                var arc_angle = i * 180.0 / num_control_points;
                var arc_radius = radius + (Math.sin(latlngDeg2rad(arc_angle))) * max_altitude;
                var latlng = latlngInterPoint(start_lat, start_lng, end_lat, end_lng, i / num_control_points);
                var pos = latlngPosFromLatLng(latlng.lat, latlng.lng, arc_radius);

                points.push(new THREE.Vector3(pos.x, pos.y, pos.z));
            }

            var spline = new THREE.SplineCurve3(points);

            addTrackLine(spline, hue);
        }








/*
        var deleteMe = [];

        function newDataCallback(node) {
            if (node instanceof THREE.Line && node.name == "trackline") {
                deleteMe.push(node);
            }
            if (node instanceof THREE.Mesh && node.name == "trackmarker") {
                deleteMe.push(node);
            }
        }

*/

        window.onload = function () {
            if (!Detector.webgl) {
                Detector.addGetWebGLMessage();
                return;
            }

            init();

            var num_new_data_adds = 1;
            for (var i = 0; i < num_new_data_adds; ++i) {
                addData(locations);
            }

            zoomToStart();

            animate();
        }
    </script>

主要功能有,addData、addMarker、addTrack、addTrackline。有人可以帮我用标签画线吗?我不知道如何标记这些线的起点和终点。

示例项目可以在这里看到: http: //callum.com/sandbox/webglex/connected_planet/

4

1 回答 1

0

在 WebGL 3d 场景中创建标签有点棘手。基本思想是使用 html 和 css(或 2dcanvas/svg,我更喜欢 svg)来绘制标签。例如创建一个带有文本的 div。比你应该根据场景对象定位它。为此,您可以使用投影仪和取消投影 3d 世界中对象的位置到您的 html 2d 层,然后使用 top/left 属性在 html/svg 层中定位标签。如果有很多标签,这种方法会相当慢。另一种方法是使用 3d 变换并在此处描述。此外,您应该应用一些技巧来隐藏位于场景对象后面的标签。

于 2013-05-28T07:46:41.843 回答