UV Text Explore

ctx – Canvas

UV Mapping Example

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Verge3D - uv mapping tests</title>
    <meta charset=utf-8 />
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  </head>
 
  <body>
 
    <script src="build/v3d.js"></script>
    <script src="UVsDebug.js"></script>
 
    <script>
      /*
       * This is to help debug UVs problems in geometry,
       * as well as allow a new user to visualize what UVs are about.
       */
      function test(name, geometry) {
        var d = document.createElement('div');
        d.innerHTML = '<br><br>' + name + '<br>';
        d.appendChild(v3d.UVsDebug(geometry));
        document.body.appendChild(d);
      }
      var points = [];
      for (var i = 0; i < 10; i++) {
        points.push(new v3d.Vector2(Math.sin(i * 0.2) * 15 + 50, (i - 5) * 2));
      }
      //
      test('new v3d.PlaneBufferGeometry(100, 100, 4, 4)', new v3d.PlaneBufferGeometry(100, 100, 4, 4));
      test('new v3d.SphereBufferGeometry(75, 12, 6)', new v3d.SphereBufferGeometry(75, 12, 6));
      test('new v3d.IcosahedronBufferGeometry(30, 1)', new v3d.IcosahedronBufferGeometry(30, 1));
      test('new v3d.OctahedronBufferGeometry(30, 2)', new v3d.OctahedronBufferGeometry(30, 2));
      test('new v3d.CylinderBufferGeometry(25, 75, 100, 10, 5)', new v3d.CylinderBufferGeometry(25, 75, 100, 10, 5));
      test('new v3d.BoxBufferGeometry(100, 100, 100, 4, 4, 4)', new v3d.BoxBufferGeometry(100, 100, 100, 4, 4, 4));
      test('new v3d.LatheBufferGeometry(points, 8)', new v3d.LatheBufferGeometry(points, 8));
      test('new v3d.TorusBufferGeometry(50, 20, 8, 8)', new v3d.TorusBufferGeometry(50, 20, 8, 8));
      test('new v3d.TorusKnotBufferGeometry(50, 10, 12, 6)', new v3d.TorusKnotBufferGeometry(50, 10, 12, 6));
    </script>
 
  </body>
 
</html>

UVsDebug.js

/*
 * @author zz85 / http://github.com/zz85
 * @author WestLangley / http://github.com/WestLangley
 * @author Mugen87 / https://github.com/Mugen87
 *
 * tool for "unwrapping" and debugging three.js geometries UV mapping
 *
 * Sample usage:
 *    document.body.appendChild(v3d.UVsDebug(new v3d.SphereBufferGeometry(10, 10, 10, 10));
 *
 */

v3d.UVsDebug = function(geometry, size) {

    // handles wrapping of uv.x > 1 only

    var abc = 'abc';
    var a = new v3d.Vector2();
    var b = new v3d.Vector2();

    var uvs = [
        new v3d.Vector2(),
        new v3d.Vector2(),
        new v3d.Vector2()
    ];

    var face = [];

    var canvas = document.createElement('canvas');
    var width = size || 1024; // power of 2 required for wrapping
    var height = size || 1024;
    canvas.width = width;
    canvas.height = height;

    var ctx = canvas.getContext('2d');
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'rgba(0, 0, 0, 1.0)';
    ctx.textAlign = 'center';

    // paint background white

    ctx.fillStyle = 'rgba(255, 255, 255, 1.0)';
    ctx.fillRect(0, 0, width, height);

    if (geometry.isGeometry) {

        var faces = geometry.faces;
        var uvSet = geometry.faceVertexUvs[0];

        for (var i = 0, il = uvSet.length; i < il; i++) {

            var face = faces[i];
            var uv = uvSet[i];

            face[0] = face.a;
            face[1] = face.b;
            face[2] = face.c;

            uvs[0].copy(uv[0]);
            uvs[1].copy(uv[1]);
            uvs[2].copy(uv[2]);

            processFace(face, uvs, i);

        }

    } else {

        var index = geometry.index;
        var uvAttribute = geometry.attributes.uv;

        if (index) {

            // indexed geometry

            for (var i = 0, il = index.count; i < il; i += 3) {

                face[0] = index.getX(i);
                face[1] = index.getX(i + 1);
                face[2] = index.getX(i + 2);

                uvs[0].fromBufferAttribute(uvAttribute, face[0]);
                uvs[1].fromBufferAttribute(uvAttribute, face[1]);
                uvs[2].fromBufferAttribute(uvAttribute, face[2]);

                processFace(face, uvs, i);

            }

        } else {

            // non-indexed geometry

            for (var i = 0, il = uvAttribute.count; i < il; i += 3) {

                face[0] = i;
                face[1] = i + 1;
                face[2] = i + 2;

                uvs[0].fromBufferAttribute(uvAttribute, face[0]);
                uvs[1].fromBufferAttribute(uvAttribute, face[1]);
                uvs[2].fromBufferAttribute(uvAttribute, face[2]);

                processFace(face, uvs, i);

            }

        }

    }

    return canvas;

    function processFace(face, uvs, index) {

        // draw contour of face

        ctx.beginPath();

        a.set(0, 0);

        for (var j = 0, jl = uvs.length; j < jl; j ++) {

            var uv = uvs[j];

            a.x += uv.x;
            a.y += uv.y;

            if (j === 0) {

                ctx.moveTo(uv.x * width, (1 - uv.y) * height);

            } else {

                ctx.lineTo(uv.x * width, (1 - uv.y) * height);

            }

        }

        ctx.closePath();
        ctx.stroke();

        // calculate center of face

        a.divideScalar(uvs.length);

        // label the face number

        ctx.font = '12pt Arial bold';
        ctx.fillStyle = 'rgba(0, 0, 0, 1.0)';
        ctx.fillText(index, a.x * width, (1 - a.y) * height);

        if (a.x > 0.95) {

            // wrap x // 0.95 is arbitrary

            ctx.fillText(index, (a.x % 1) * width, (1 - a.y) * height);

        }

        //

        ctx.font = '8pt Arial bold';
        ctx.fillStyle = 'rgba(0, 0, 0, 1.0)';

        // label uv edge orders

        for (j = 0, jl = uvs.length; j < jl; j ++) {

            var uv = uvs[j];
            b.addVectors(a, uv).divideScalar(2);

            var vnum = face[j];
            ctx.fillText(abc[j] + vnum, b.x * width, (1 - b.y) * height);

            if (b.x > 0.95) {

                // wrap x

                ctx.fillText(abc[j] + vnum, (b.x % 1) * width, (1 - b.y) * height);

            }

        }

    }

};
<!DOCTYPE html>
<html>
<body>

<h2>Using the XMLHttpRequest object</h2>

<button type="button" onclick="loadXMLDoc()">Change Content</button>

<p id="demo"></p>

<script>
function loadXMLDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "xmlhttp_info.txt", true);
  xhttp.send();
}
</script>

</body>
</html>


// Synchronously read a text file from the web server with Ajax
//
// The filePath is relative to the web page folder.
// Example:   myStuff = loadFile("Chuuk_data.txt");
//
// You can also pass a full URL, like http://sealevel.info/Chuuk1_data.json, but there
// might be Access-Control-Allow-Origin issues. I found it works okay in Firefox, Edge,
// or Opera, and works in IE 11 if the server is configured properly, but in Chrome it only
// works if the domains exactly match (and note that "xyz.com" & "www.xyz.com" don't match).
// Otherwise Chrome reports an error:
//
//   No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sealevel.info' is therefore not allowed access.
//
// That happens even when "Access-Control-Allow-Origin *" is configured in .htaccess,
// and even though I verified the headers returned (you can use a header-checker site like
// http://www.webconfs.com/http-header-check.php to check it). I think it's a Chrome bug.
function loadFile(filePath) {
  var result = null;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open("GET", filePath, false);
  xmlhttp.send();
  if (xmlhttp.status==200) {
    result = xmlhttp.responseText;
  }
  return result;
}
function processFile(inputFile) {
    var fs = require('fs'),
        readline = require('readline'),
        instream = fs.createReadStream(inputFile),
        outstream = new (require('stream'))(),
        rl = readline.createInterface(instream, outstream);
     
    rl.on('line', function (line) {
        console.log(line);
    });
    
    rl.on('close', function (line) {
        console.log(line);
        console.log('done reading file.');
    });
}
processFile('/path/to/a/input/file.txt');