2023-08-29 19:26:18 +02:00
|
|
|
function readObj(path) {
|
2022-12-12 09:08:03 +01:00
|
|
|
if(!file_exists(path)) return noone;
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
var _VB = [];
|
|
|
|
var _VBT = [];
|
2022-12-12 09:08:03 +01:00
|
|
|
var _VBN = [];
|
2022-01-13 05:24:03 +01:00
|
|
|
var mats = [];
|
2022-12-12 09:08:03 +01:00
|
|
|
var matIndex = [];
|
2023-08-22 11:51:45 +02:00
|
|
|
var tris = [];
|
2023-02-14 11:40:24 +01:00
|
|
|
var mtlPath = "";
|
2022-12-18 03:20:38 +01:00
|
|
|
var use_normal = true;
|
2023-08-22 11:51:45 +02:00
|
|
|
var v = ds_list_create();
|
|
|
|
var vt = ds_list_create();
|
|
|
|
var vn = ds_list_create();
|
|
|
|
var f = ds_list_create();
|
|
|
|
var ft = ds_list_create();
|
|
|
|
var fn = ds_list_create();
|
|
|
|
var tri = 0;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
|
|
|
var file = file_text_open_read(path);
|
2023-08-22 20:10:09 +02:00
|
|
|
while(!file_text_eof(file)) { #region reading file
|
2022-01-13 05:24:03 +01:00
|
|
|
var l = file_text_readln(file);
|
2023-08-22 11:51:45 +02:00
|
|
|
l = string_trim(l);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
var sep = string_split(l, " ");
|
|
|
|
if(array_length(sep) == 0) continue;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
|
|
|
switch(sep[0]) {
|
|
|
|
case "v" :
|
2023-08-22 11:51:45 +02:00
|
|
|
ds_list_add(v, [ toNumber(sep[1]), toNumber(sep[2]), toNumber(sep[3]) ]);
|
2022-01-13 05:24:03 +01:00
|
|
|
break;
|
|
|
|
case "vt" :
|
2023-08-29 19:26:18 +02:00
|
|
|
var _u = toNumber(sep[1]);
|
|
|
|
var _v = toNumber(sep[2]);
|
|
|
|
|
|
|
|
ds_list_add(vt, [ _u, _v ]);
|
2022-12-12 09:08:03 +01:00
|
|
|
break;
|
|
|
|
case "vn" :
|
2023-08-30 16:40:45 +02:00
|
|
|
var _nx = toNumber(sep[1]);
|
|
|
|
var _ny = toNumber(sep[2]);
|
|
|
|
var _nz = toNumber(sep[3]);
|
|
|
|
var _di = sqrt(_nx * _nx + _ny * _ny + _nz * _nz);
|
|
|
|
|
|
|
|
_nx /= _di;
|
|
|
|
_ny /= _di;
|
|
|
|
_nz /= _di;
|
|
|
|
|
|
|
|
ds_list_add(vn, [ _nx, _ny, _nz ]);
|
2022-01-13 05:24:03 +01:00
|
|
|
break;
|
|
|
|
case "f" :
|
2023-08-22 11:51:45 +02:00
|
|
|
var _len = array_length(sep);
|
|
|
|
var _f = array_create(_len - 1);
|
|
|
|
var _ft = array_create(_len - 1);
|
|
|
|
var _fn = array_create(_len - 1);
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
for( var i = 1; i < _len; i++ ) {
|
|
|
|
var _sp = string_split(sep[i], "/");
|
2023-05-03 21:42:17 +02:00
|
|
|
if(array_length(_sp) < 2) continue;
|
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
_f[i - 1] = toNumber(array_safe_get(_sp, 0, 1));
|
|
|
|
_ft[i - 1] = toNumber(array_safe_get(_sp, 1, 1));
|
|
|
|
_fn[i - 1] = toNumber(array_safe_get(_sp, 2, 1));
|
2023-02-14 11:40:24 +01:00
|
|
|
|
|
|
|
if(array_length(_sp) < 3) use_normal = false;
|
2022-12-18 03:20:38 +01:00
|
|
|
}
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
tri += _len - 2;
|
|
|
|
ds_list_add(f, _f ); //get position
|
|
|
|
ds_list_add(ft, _ft); //get texture map
|
|
|
|
ds_list_add(fn, _fn); //get normal
|
2022-01-13 05:24:03 +01:00
|
|
|
break;
|
|
|
|
case "usemtl" :
|
2023-02-14 11:40:24 +01:00
|
|
|
var mname = "";
|
|
|
|
for( var i = 1; i < array_length(sep); i++ )
|
|
|
|
mname += (i == 1? "" : " ") + sep[i];
|
|
|
|
mname = string_trim(mname);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
|
|
|
array_push_unique(mats, mname);
|
|
|
|
array_push(matIndex, array_find(mats, mname));
|
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
if(!ds_list_empty(f)) {
|
2022-01-13 05:24:03 +01:00
|
|
|
array_push(_VB, f);
|
|
|
|
array_push(_VBT, ft);
|
2022-12-12 09:08:03 +01:00
|
|
|
array_push(_VBN, fn);
|
2023-08-22 11:51:45 +02:00
|
|
|
array_push(tris, tri);
|
|
|
|
f = ds_list_create();
|
|
|
|
ft = ds_list_create();
|
|
|
|
fn = ds_list_create();
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
2023-08-22 11:51:45 +02:00
|
|
|
|
|
|
|
tri = 0;
|
2022-01-13 05:24:03 +01:00
|
|
|
break;
|
2023-02-14 11:40:24 +01:00
|
|
|
case "mtllib" :
|
|
|
|
mtlPath = "";
|
|
|
|
for( var i = 1; i < array_length(sep); i++ )
|
|
|
|
mtlPath += (i == 1? "" : " ") + sep[i];
|
|
|
|
mtlPath = string_trim(mtlPath);
|
|
|
|
break;
|
|
|
|
case "o" :
|
|
|
|
//print("Reading vertex group: " + sep[1])
|
|
|
|
break;
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
|
|
|
}
|
2023-08-22 11:51:45 +02:00
|
|
|
|
|
|
|
if(!ds_list_empty(f)) {
|
2022-01-13 05:24:03 +01:00
|
|
|
array_push(_VB, f);
|
|
|
|
array_push(_VBT, ft);
|
2022-12-12 09:08:03 +01:00
|
|
|
array_push(_VBN, fn);
|
2023-08-22 11:51:45 +02:00
|
|
|
array_push(tris, tri);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
|
|
|
file_text_close(file);
|
2023-08-22 20:10:09 +02:00
|
|
|
#endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
if(use_normal) vn[| 0] = [ 0, 0, 0 ];
|
|
|
|
|
2023-08-22 20:10:09 +02:00
|
|
|
//var txt = "OBJ summary";
|
|
|
|
//txt += $"\n\tVerticies : {ds_list_size(v)}";
|
|
|
|
//txt += $"\n\tTexture Verticies : {ds_list_size(vt)}";
|
|
|
|
//txt += $"\n\tNormal Verticies : {ds_list_size(vn)}";
|
|
|
|
//txt += $"\n\tVertex groups : {array_length(_VB)}";
|
|
|
|
//txt += $"\n\tTriangles : {tris}";
|
|
|
|
//print(txt);
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2022-12-12 09:08:03 +01:00
|
|
|
#region centralize vertex
|
2023-08-22 11:51:45 +02:00
|
|
|
var _bmin = v[| 0];
|
|
|
|
var _bmax = v[| 0];
|
2022-12-12 09:08:03 +01:00
|
|
|
var cv = [0, 0, 0];
|
2023-08-22 11:51:45 +02:00
|
|
|
var vertex = ds_list_size(v);
|
|
|
|
|
2022-12-12 09:08:03 +01:00
|
|
|
for( var i = 0; i < vertex; i++ ) {
|
2023-08-22 11:51:45 +02:00
|
|
|
var _v = v[| i];
|
2022-12-12 09:08:03 +01:00
|
|
|
cv[0] += _v[0];
|
|
|
|
cv[1] += _v[1];
|
|
|
|
cv[2] += _v[2];
|
2023-08-22 11:51:45 +02:00
|
|
|
|
|
|
|
_bmin = [
|
|
|
|
min(_bmin[0], _v[0]),
|
|
|
|
min(_bmin[1], _v[1]),
|
|
|
|
min(_bmin[2], _v[2]),
|
|
|
|
];
|
|
|
|
_bmax = [
|
|
|
|
max(_bmax[0], _v[0]),
|
|
|
|
max(_bmax[1], _v[1]),
|
|
|
|
max(_bmax[2], _v[2]),
|
|
|
|
];
|
2022-12-12 09:08:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
cv[0] /= vertex;
|
|
|
|
cv[1] /= vertex;
|
|
|
|
cv[2] /= vertex;
|
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
for( var i = 0, n = ds_list_size(v); i < n; i++ ) {
|
|
|
|
v[| i][0] -= cv[0];
|
|
|
|
v[| i][1] -= cv[1];
|
|
|
|
v[| i][2] -= cv[2];
|
2022-12-12 09:08:03 +01:00
|
|
|
}
|
2023-08-22 11:51:45 +02:00
|
|
|
|
|
|
|
var _size = new __vec3(
|
|
|
|
_bmax[0] - _bmin[0],
|
|
|
|
_bmax[1] - _bmin[1],
|
|
|
|
_bmax[2] - _bmin[2],
|
|
|
|
);
|
2022-12-12 09:08:03 +01:00
|
|
|
#endregion
|
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
#region vertex buffer creation
|
|
|
|
var _vblen = array_length(_VB);
|
2023-08-22 20:10:09 +02:00
|
|
|
var VBS = array_create(_vblen);
|
|
|
|
var V = array_create(_vblen);
|
2022-12-12 09:08:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
for(var i = 0; i < _vblen; i++) {
|
|
|
|
var VB = vertex_create_buffer();
|
|
|
|
vertex_begin(VB, global.VF_POS_NORM_TEX_COL);
|
|
|
|
var face = _VB[i];
|
|
|
|
var facet = _VBT[i];
|
|
|
|
var facen = _VBN[i];
|
|
|
|
var tri = tris[i];
|
2022-12-12 09:08:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
var _flen = ds_list_size(face);
|
2023-08-23 20:01:09 +02:00
|
|
|
var _v = ds_list_create();
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
for(var j = 0; j < _flen; j++) {
|
|
|
|
var _f = face[| j];
|
|
|
|
var _ft = facet[| j];
|
|
|
|
var _fn = facen[| j];
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
var _vlen = array_length(_f);
|
|
|
|
var _pf = array_create(_vlen);
|
|
|
|
var _pft = array_create(_vlen);
|
|
|
|
var _pfn = array_create(_vlen);
|
|
|
|
|
|
|
|
for( var k = 0; k < _vlen; k++ ) {
|
|
|
|
var _vPindex = _f[k] - 1;
|
|
|
|
_pf[k] = v[| _vPindex];
|
|
|
|
|
|
|
|
var _vNindex = _fn[k] - 1;
|
|
|
|
_pfn[k] = vn[| _vNindex];
|
|
|
|
|
|
|
|
var _vTindex = _ft[k] - 1;
|
|
|
|
_pft[k] = vt[| _vTindex];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(_vlen >= 3) {
|
|
|
|
vertex_add_pntc(VB, _pf[0], _pfn[0], _pft[0]);
|
|
|
|
vertex_add_pntc(VB, _pf[2], _pfn[2], _pft[2]);
|
2023-08-23 20:01:09 +02:00
|
|
|
vertex_add_pntc(VB, _pf[1], _pfn[1], _pft[1]);
|
2023-08-22 11:51:45 +02:00
|
|
|
|
2023-08-29 14:33:44 +02:00
|
|
|
ds_list_add(_v, new __vertex(_pf[0][0], _pf[0][1], _pf[0][2]).setNormal(_pfn[0][0], _pfn[0][1]).setUV(_pft[0][0], _pft[0][1]));
|
|
|
|
ds_list_add(_v, new __vertex(_pf[2][0], _pf[2][1], _pf[2][2]).setNormal(_pfn[2][0], _pfn[2][1]).setUV(_pft[2][0], _pft[2][1]));
|
|
|
|
ds_list_add(_v, new __vertex(_pf[1][0], _pf[1][1], _pf[1][2]).setNormal(_pfn[1][0], _pfn[1][1]).setUV(_pft[1][0], _pft[1][1]));
|
2023-08-22 11:51:45 +02:00
|
|
|
}
|
2023-08-22 20:10:09 +02:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
if(_vlen >= 4) {
|
|
|
|
vertex_add_pntc(VB, _pf[0], _pfn[0], _pft[0]);
|
|
|
|
vertex_add_pntc(VB, _pf[3], _pfn[3], _pft[3]);
|
2023-08-23 20:01:09 +02:00
|
|
|
vertex_add_pntc(VB, _pf[2], _pfn[2], _pft[2]);
|
2023-08-22 11:51:45 +02:00
|
|
|
|
2023-08-29 14:33:44 +02:00
|
|
|
ds_list_add(_v, new __vertex(_pf[0][0], _pf[0][1], _pf[0][2]).setNormal(_pfn[0][0], _pfn[0][1]).setUV(_pft[0][0], _pft[0][1]));
|
|
|
|
ds_list_add(_v, new __vertex(_pf[3][0], _pf[3][1], _pf[3][2]).setNormal(_pfn[3][0], _pfn[3][1]).setUV(_pft[3][0], _pft[3][1]));
|
|
|
|
ds_list_add(_v, new __vertex(_pf[2][0], _pf[2][1], _pf[2][2]).setNormal(_pfn[2][0], _pfn[2][1]).setUV(_pft[2][0], _pft[2][1]));
|
2023-08-22 11:51:45 +02:00
|
|
|
}
|
2023-02-14 11:40:24 +01:00
|
|
|
}
|
2023-08-22 20:10:09 +02:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
vertex_end(VB);
|
|
|
|
vertex_freeze(VB);
|
|
|
|
|
|
|
|
VBS[i] = VB;
|
2023-08-23 20:01:09 +02:00
|
|
|
V[i] = ds_list_to_array(_v);
|
|
|
|
ds_list_destroy(_v);
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|
2023-08-22 11:51:45 +02:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region clean
|
|
|
|
array_foreach(_VB, function(val, ind) { ds_list_destroy(val); });
|
|
|
|
array_foreach(_VBT, function(val, ind) { ds_list_destroy(val); });
|
|
|
|
array_foreach(_VBN, function(val, ind) { ds_list_destroy(val); });
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-08-22 11:51:45 +02:00
|
|
|
ds_list_destroy(v);
|
|
|
|
ds_list_destroy(vn);
|
|
|
|
ds_list_destroy(vt);
|
|
|
|
#endregion
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-02-14 11:40:24 +01:00
|
|
|
return {
|
2023-08-22 20:10:09 +02:00
|
|
|
vertex: V,
|
|
|
|
vertex_groups: VBS,
|
|
|
|
object_counts: _vblen,
|
2023-08-22 11:51:45 +02:00
|
|
|
|
2023-02-14 11:40:24 +01:00
|
|
|
materials: mats,
|
|
|
|
material_index: matIndex,
|
|
|
|
use_normal: use_normal,
|
|
|
|
mtl_path: mtlPath,
|
2023-08-22 11:51:45 +02:00
|
|
|
model_size: _size,
|
2023-02-14 11:40:24 +01:00
|
|
|
};
|
2022-01-13 05:24:03 +01:00
|
|
|
}
|