Objモデルインポート実装


注意:マテリアルファイルの読み取りがまだ終わっていないので、空いているときに更新します.
void function () {
    function loadFile(url, syne, type, callback) {
        /// <summary>Ajax    </summary>
        /// <param name="url" type="String">    </param>
        /// <param name="syne" type="Boolean">      </param>
        /// <param name="type" type="String">Mime  </param>
        /// <param name="callback" type="Function">    </param>

        var xmlHttp = new XMLHttpRequest();
        if (syne == null) {
            syne = true;
        }

        if (type == null) {
            type = 'text/plain';
        }

        if (!("withCredentials" in xmlHttp)) {
            xmlHttp = new XDomainRequest();
            xmlHttp.onload = function () {
                callback(this.responseText);
            };
            xmlHttp.open("GET", url);
        } else {
            xmlHttp.open('GET', url, syne);

            //       HTTP   
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
        }

        //          responseType
        if (type.indexOf("text") < 0) {
            xmlHttp.responseType = type;
        }
        xmlHttp.onerror = function () {
            throw new Error("File \"" + url + "\" failed to load.");
        };
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState === 4) {
                if (xmlHttp.status == 404) {
                    this.onerror();
                }
                if (callback) {
                    if (type.indexOf("text") < 0) {
                        callback(xmlHttp.response);
                    } else {
                        callback(xmlHttp.responseText);
                    }
                }
                this.onreadystatechange = null;
                this.onerror = null;
                xmlHttp = null;
                callback = null;
            }
        };
        xmlHttp.send(null);
    };

    function hasNaN(o) {
        /// <summary>              NaN</summary>
        /// <param name="o" type="Object">      </param>

        for (var k in o) {
            if (NaN == o[k])
                return true;
        }
        return false;
    }

    window.objModelLoader = function (fileName, callback, gl) {
        /// <summary>  Obj    </summary>
        /// <param name="fileName" type="String">    </param>
        /// <param name="callback" type="Function">    </param>
        /// <param name="gl" type="WebGLContext">WebGL   </param>

        if (!gl) throw new Error("WebGL context not found.");

        var _this = this;

        //   Ajax  Obj      
        loadFile(fileName, true, null, function (obj) {

            //obj = obj.toString().trim();            //            
            //obj = obj.replace(/\r
/g, "
"); // //obj = obj.replace(/\r/g, "
"); // //obj = obj.replace(/#+[^
]*
/g, "
"); // //obj = obj.replace(/\\
/g, ""); // var objcmds = obj.split(/\s*
+\s*/); obj = function () { var model = { geometricVertices: [], textureVertices: [], vertexNormals: [], parameterSpaceVertices: [], groups: [] }; var curgroup = null; for (var i = 0; i < objcmds.length; i++) { var cmdwords = objcmds[i].split(/\s+/); var o; switch (cmdwords[0]) { case "v": if (4 > cmdwords.length || hasNaN(o = { x: parseFloat(cmdwords[1]), y: parseFloat(cmdwords[2]), z: parseFloat(cmdwords[3]) })) continue; model.geometricVertices.push(o); break; case "vt": if (3 > cmdwords.length || hasNaN(o = { u: parseFloat(cmdwords[1]), v: parseFloat(cmdwords[2]) })) continue; model.textureVertices.push(o); break; case "vn": if (4 > cmdwords.length || hasNaN(o = { x: parseFloat(cmdwords[1]), y: parseFloat(cmdwords[2]), z: parseFloat(cmdwords[3]) })) continue; model.vertexNormals.push(o); break; case "vp": if (4 > cmdwords.length || hasNaN(o = { x: parseFloat(cmdwords[1]), y: parseFloat(cmdwords[2]), z: parseFloat(cmdwords[3]) })) continue; model.parameterSpaceVertices.push(o); break; case "p": if (2 > cmdwords.length) continue; o = []; for (var j = 1; j < 2; j++) { o.push(parseInt(cmdwords[j])); } if (hasNaN(o)) continue; if (curgroup) curgroup.points.push(o); break; case "l": if (3 > cmdwords.length) continue; o = []; for (var j = 1; j < 3; j++) { o.push(parseInt(cmdwords[j])); } if (hasNaN(o)) continue; if (curgroup) curgroup.lines.push(o); break; case "f": if (4 > cmdwords.length) continue; o = []; for (var j = 1; j < 4; j++) { var m = cmdwords[j].match(/^(\d+)\/(\d+)\/(\d+)$/); if (null != m) { o.push({ idxVertex: m[1], idxTexture: m[2], idxNormals: m[3] }); continue; } o.push(parseInt(cmdwords[j])); } if (hasNaN(o)) continue; if (curgroup) curgroup.faces.push(o); break; case "g": if (2 > cmdwords.length) continue; model.groups.push(curgroup = { name: cmdwords[1], points: [], lines: [], faces: [] }); break; } } return model; }(); obj = function (obj) { var model = { materials: [], indices: [], vertexPositions: [], vertexNormals: [], vertexTextureCoords: [] }; var c = 0; for (var i = 0; i < obj.groups.length; i++) { var mapping = []; for (var j = 0; j < obj.groups[i].faces.length; j++) { for (var k = 0; k < obj.groups[i].faces[j].length; k++) { var o = obj.groups[i].faces[j][k]; var b = isNaN(o); var v = b ? o.idxVertex : o; var t = b ? o.idxTexture : 0.0; var n = b ? o.idxNormals : 0.0; var s = v + "/" + t + "/" + n; if (undefined == mapping[s]) { mapping[s] = { index: c++, vertex: 0 <= v - 1 ? obj.geometricVertices[v - 1] : null, texture: b && 0 <= t - 1 ? obj.textureVertices[t - 1] : null, normals: b && 0 <= n - 1 ? obj.vertexNormals[n - 1] : null }; model.vertexPositions.push(mapping[s].vertex.x); model.vertexPositions.push(mapping[s].vertex.y); model.vertexPositions.push(mapping[s].vertex.z); model.vertexNormals.push(mapping[s].normals.x); model.vertexNormals.push(mapping[s].normals.y); model.vertexNormals.push(mapping[s].normals.z); model.vertexTextureCoords.push(mapping[s].texture.u); model.vertexTextureCoords.push(mapping[s].texture.v); } model.indices.push(mapping[s].index); } } model.materials.push({ numindices: obj.groups[i].faces.length * 3 }); } model.vertexPositions = new Float32Array(model.vertexPositions); model.vertexNormals = new Float32Array(model.vertexNormals); model.indices = new Uint16Array(model.indices); return model; }(obj); // callback && callback(obj); }); }; }();