您的位置:首页 > 其它

Obj模型导入器实现

2015-12-01 16:51 274 查看
本文已弃更

注意:材质文件的读取还没有搞定,有空的时候更新。

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\n/g, "\n");        // 将整篇文档中的回车换行符替换成换行符
//obj = obj.replace(/\r/g, "\n");          // 将整篇文档中的回车符替换成换行符
//obj = obj.replace(/#+[^\n]*\n/g, "\n");  // 将整篇文档中的注释部分替换成换行符
//obj = obj.replace(/\\\n/g, "");          // 将整篇文档中每行最后的斜线和换行符与下一行连接

var objcmds = obj.split(/\s*\n+\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);
});
};
}();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: