在三个.js中定位和旋转网格

时间:2015-09-09 06:49:05

标签: javascript three.js

我正在尝试构建类似于此站点英雄单位的内容:http://www.nodeplus.com.cn/

我的方法是制作一个临时的2d画布,打印出我的信息,扫描像素,然后用它们将网格定位在3d空间中:

 // STEP 1: if a pixel is detected on every gridX / gridY step, put it in the pos array
          for (y = 0; y <= height; y += gridY) {
            for (x = 0; x <= width; x += gridX) {
              if (buffer32[y * width + x]) {
                positions.push({x: x, y: y});
              }
            }
          }
然后我将它们放在3d空间中

            for (i = 0; i < len; i++) {
              pos = positions[i];
              shape = new Shape({
                x: pos.x / 10,
                y: -pos.y / 10,
                z: Math.random() * 4
              });
              shape.init(scene);
              shapes.push(shape);
            }

这一切都很好,但是我希望它们能够定位在现场中心。 由于我扫描2d画布并从那里获取位置(从0,0开始)的方式,他们在3d空间中得到一些非常奇怪的定位有三个.js(因为我的像素定位像{x:1600, y:500}在更大的屏幕上)

我不得不放一个奇怪的相机。查看它的位置只是为了看它,如:

camera.position.set(100, 0, 80);
          camera.lookAt({
            x: 95,
            y: -50,
            z: scene.position.z
          });

这种方法现在适用,但对我来说这不是一个好选择。我想围绕字母旋转相机,不想围绕这样一个奇怪的位置旋转它。

您可以在此处查看代码:

&#13;
&#13;
var heroUnit = (function(self) {

        function Shape(pos) {
          this.pos = pos;
          this.mesh = null;
          this.radius = 2 + Math.random() * 2;
          this.speed = 0.4 + Math.random() * 0.4;
        }

        Shape.prototype.init = function(scene) {
          var geometry, material, mesh,
              v1, v2, v3;

          geometry = new THREE.Geometry();

          v1 = new THREE.Vector3(this.pos.x - this.radius / 2, this.pos.y - this.radius / 2, this.pos.z - this.radius / 2);
          v2 = new THREE.Vector3(this.pos.x + this.radius / 2, this.pos.y - this.radius / 2, this.pos.z - this.radius / 2);
          v3 = new THREE.Vector3(this.pos.x + this.radius / 2, this.pos.y + this.radius / 2, this.pos.z + this.radius / 2);

          geometry.vertices.push(v1);
          geometry.vertices.push(v2);
          geometry.vertices.push(v3);

          geometry.faces.push(new THREE.Face3(0, 1, 2));
          geometry.computeFaceNormals();

          material = new THREE.MeshLambertMaterial({color: Math.random() * 0xFFFFFF});
          mesh = new THREE.Mesh(geometry, material);

          this.mesh = mesh;

          this.mesh.receiveShadow = true;

          //this.mesh.scale.set(Math.random() * 20, Math.random() * 20, Math.random() * 20);
          this.mesh.rotation.set(0, 0, 0)
          scene.add(this.mesh);

        }

        var width, height,
            aspectRatio, pov,
            near, far,
            scene, camera,
            renderer, 
            effectPositions,
            shapes, light;

        function init(string) {
          // constants
          width = window.innerWidth;
          height = window.innerHeight;
          pov = 45;
          aspectRatio = width / height;
          near = 0.1;
          far = 1000;

          // three.js specific stuff
          scene = new THREE.Scene();
          camera = new THREE.PerspectiveCamera(pov, aspectRatio, near, far);
          renderer = new THREE.WebGLRenderer();
          light = new THREE.DirectionalLight(0x000000, 0.6);

          // containers
          effectPositions = getPixels(string);
          shapes = [];

          // set up light
          light.position.set(100, 0, 200);
          light.castShadow = true;
          scene.add(light);

          // set size to renderer, color it in dark blue & append it to dom
          renderer.setSize(width, height);
          renderer.setClearColor(0x17293a);
          document.body.appendChild(renderer.domElement);

          // set up camera
          camera.position.set(100, 0, 80);
          camera.lookAt({
            x: 50,
            y: -50,
            z: scene.position.z
          });
          scene.add(camera);

          generateShapes(effectPositions);

        }

        // generate 3d shapes according to our 2d positions array
        function generateShapes(positions) {
          var i, n, len, 
              pos, shape,
              maxIterations

          len = positions.length;
          maxIterations = 2;

          for (n = 0; n <= maxIterations; n++) {
            for (i = 0; i < len; i++) {
              pos = positions[i];
              shape = new Shape({
                x: pos.x / 10,
                y: -pos.y / 10,
                z: Math.random() * 4
              });
              shape.init(scene);
              shapes.push(shape);
            }
          }

        }

        // get 2d positions
        function getPixels(string) {
          var canvas, ctx, 
              idata, buffer32,
              x, y,
              gridX, gridY,
              positions;

          //make temp canvas on which to draw and get pixel data
          canvas = document.createElement('canvas');
          ctx = canvas.getContext('2d');
          positions = [];
          string = string.toUpperCase().split("").join(String.fromCharCode(8202));

          canvas.width = width;
          canvas.height = height;

          //document.body.appendChild(canvas);

          ctx.fillStyle = '#000';
          ctx.font = 'bold 260px Arial';
          ctx.fillText(string, width / 2 - ctx.measureText(string).width / 2, height / 2);

          idata = ctx.getImageData(0, 0, width, height);
          buffer32 = new Uint32Array(idata.data.buffer);
          gridX = gridY = 14;

          // if a pixel is detected on every gridX / gridY step, put it in the pos array
          for (y = 0; y <= height; y += gridY) {
            for (x = 0; x <= width; x += gridX) {
              if (buffer32[y * width + x]) {
                positions.push({x: x, y: y});
              }
            }
          }

          // return pos array
          return positions;

        }

        // render function
        function render(ts) {
          renderer.render(scene, camera);
          shapes.forEach(function(shape) {
          //    shape.mesh.position.x = shape.dist + (Math.sin(ts / 500)) * shape.speed;
          })
        }

        return {
          init: init,
          render: render
        }

      }(heroUnit || {}))

      // init our program
      heroUnit.init('100');

      // redraw each frame
      (function drawFrame(ts) {
        window.requestAnimationFrame(drawFrame);
        heroUnit.render(ts);
      }());
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.js"></script>
&#13;
&#13;
&#13;

任何想法和建议都欢迎,欢呼,

0 个答案:

没有答案