UNPKG

@xeokit/xeokit-sdk

Version:

3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision

1,032 lines (905 loc) 33.1 kB
/** * @private */ var K3D = {}; K3D.load = function(path, resp) { var request = new XMLHttpRequest(); request.open("GET", path, true); request.responseType = "arraybuffer"; request.onload = function(e){resp(e.target.response);}; request.send(); } K3D.save = function(buff, path) { var dataURI = "data:application/octet-stream;base64," + btoa(K3D.parse._buffToStr(buff)); window.location.href = dataURI; } K3D.clone = function(o) { return JSON.parse(JSON.stringify(o)); } K3D.bin = {}; K3D.bin.f = new Float32Array(1); K3D.bin.fb = new Uint8Array(K3D.bin.f.buffer); K3D.bin.rf = function(buff, off) { var f = K3D.bin.f, fb = K3D.bin.fb; for(var i=0; i<4; i++) fb[i] = buff[off+i]; return f[0]; } K3D.bin.rsl = function(buff, off) { return buff[off] | buff[off+1]<<8; } K3D.bin.ril = function(buff, off) { return buff[off] | buff[off+1]<<8 | buff[off+2]<<16 | buff[off+3]<<24; } K3D.bin.rASCII0 = function(buff, off) { var s = ""; while(buff[off]!=0) s += String.fromCharCode(buff[off++]); return s; } K3D.bin.wf = function(buff, off, v) { var f=new Float32Array(buff.buffer, off, 1); f[0]=v; } K3D.bin.wsl = function(buff, off, v) { buff[off]=v; buff[off+1]=v>>8; } K3D.bin.wil = function(buff, off, v) { buff[off]=v; buff[off+1]=v>>8; buff[off+2]=v>>16; buff[off+3]>>24; } K3D.parse = {}; K3D.parse._buffToStr = function(buff) { var a = new Uint8Array(buff); var s = ""; for(var i=0; i<a.length; i++) s = s.concat(String.fromCharCode(a[i])); return s; } K3D.parse._strToBuff = function(str) { var buf = new ArrayBuffer(str.length); var bufView = new Uint8Array(buf); for (var i=0; i<str.length; i++) bufView[i] = str.charCodeAt(i); return buf; } K3D.parse._readLine = function(a, off) // Uint8Array, offset { var s = ""; while(a[off] != 10) s += String.fromCharCode(a[off++]); return s; } K3D.parse.fromJSON = function(buff) { var json = JSON.parse(K3D.parse._buffToStr(buff)); return json; } K3D.parse.toJSON = function(object) { var str = JSON.stringify(object); return K3D.parse._strToBuff(str); } K3D.parse.fromOBJ = function(buff) { var res = {}; res.groups = {}; res.c_verts = []; res.c_uvt = []; res.c_norms = []; res.i_verts = []; res.i_uvt = []; res.i_norms = []; var cg = {from: 0, to:0}; // current group var off = 0; var a = new Uint8Array(buff); while(off < a.length) { var line = K3D.parse._readLine(a, off); off += line.length + 1; line = line.replace(/ +(?= )/g,''); line = line.replace(/(^\s+|\s+$)/g, ''); var cds = line.split(" "); if(cds[0] == "g") { cg.to = res.i_verts.length; if(res.groups[cds[1]] == null) res.groups[cds[1]] = {from:res.i_verts.length, to:0}; cg = res.groups[cds[1]]; } if(cds[0] == "v") { var x = parseFloat(cds[1]); var y = parseFloat(cds[2]); var z = parseFloat(cds[3]); res.c_verts.push(x,y,z); } if(cds[0] == "vt") { var x = parseFloat(cds[1]); var y = 1-parseFloat(cds[2]); res.c_uvt.push(x,y); } if(cds[0] == "vn") { var x = parseFloat(cds[1]); var y = parseFloat(cds[2]); var z = parseFloat(cds[3]); res.c_norms.push(x,y,z); } if(cds[0] == "f") { var v0a = cds[1].split("/"), v1a = cds[2].split("/"), v2a = cds[3].split("/"); var vi0 = parseInt(v0a[0])-1, vi1 = parseInt(v1a[0])-1, vi2 = parseInt(v2a[0])-1; var ui0 = parseInt(v0a[1])-1, ui1 = parseInt(v1a[1])-1, ui2 = parseInt(v2a[1])-1; var ni0 = parseInt(v0a[2])-1, ni1 = parseInt(v1a[2])-1, ni2 = parseInt(v2a[2])-1; var vlen = res.c_verts.length/3, ulen = res.c_uvt.length/2, nlen = res.c_norms.length/3; if(vi0<0) vi0 = vlen + vi0+1; if(vi1<0) vi1 = vlen + vi1+1; if(vi2<0) vi2 = vlen + vi2+1; if(ui0<0) ui0 = ulen + ui0+1; if(ui1<0) ui1 = ulen + ui1+1; if(ui2<0) ui2 = ulen + ui2+1; if(ni0<0) ni0 = nlen + ni0+1; if(ni1<0) ni1 = nlen + ni1+1; if(ni2<0) ni2 = nlen + ni2+1; res.i_verts.push(vi0, vi1, vi2); //cg.i_verts.push(vi0, vi1, vi2) res.i_uvt .push(ui0, ui1, ui2); //cg.i_uvt .push(ui0, ui1, ui2); res.i_norms.push(ni0, ni1, ni2); //cg.i_norms.push(ni0, ni1, ni2); if(cds.length == 5) { var v3a = cds[4].split("/"); var vi3 = parseInt(v3a[0])-1, ui3 = parseInt(v3a[1])-1, ni3 = parseInt(v3a[2])-1; if(vi3<0) vi3 = vlen + vi3+1; if(ui3<0) ui3 = ulen + ui3+1; if(ni3<0) ni3 = nlen + ni3+1; res.i_verts.push(vi0, vi2, vi3); //cg.i_verts.push(vi0, vi2, vi3); res.i_uvt .push(ui0, ui2, ui3); //cg.i_uvt .push(ui0, ui2, ui3); res.i_norms.push(ni0, ni2, ni3); //cg.i_norms.push(ni0, ni2, ni3); } } } cg.to = res.i_verts.length; return res; } K3D.parse.fromMD2 = function(buff) { buff = new Uint8Array(buff); var res = {}; var head = {}; //res.head = head; head.ident = K3D.bin.ril(buff, 0); /* magic number: "IDP2" */ head.version = K3D.bin.ril(buff, 4); /* version: must be 8 */ head.skinwidth = K3D.bin.ril(buff, 8); /* texture width */ head.skinheight = K3D.bin.ril(buff, 12); /* texture height */ head.framesize = K3D.bin.ril(buff, 16); /* size in bytes of a frame */ head.num_skins = K3D.bin.ril(buff, 20); /* number of skins */ head.num_vertices = K3D.bin.ril(buff, 24); /* number of vertices per frame */ head.num_st = K3D.bin.ril(buff, 28); /* number of texture coordinates */ head.num_tris = K3D.bin.ril(buff, 32); /* number of triangles */ head.num_glcmds = K3D.bin.ril(buff, 36); /* number of opengl commands */ head.num_frames = K3D.bin.ril(buff, 40); /* number of frames */ head.offset_skins = K3D.bin.ril(buff, 44); /* offset skin data */ head.offset_st = K3D.bin.ril(buff, 48); /* offset texture coordinate data */ head.offset_tris = K3D.bin.ril(buff, 52); /* offset triangle data */ head.offset_frames = K3D.bin.ril(buff, 56); /* offset frame data */ head.offset_glcmds = K3D.bin.ril(buff, 60); /* offset OpenGL command data */ head.offset_end = K3D.bin.ril(buff, 64); /* offset end of file */ var off = head.offset_st; res.c_uvt = []; for(var i=0; i<head.num_st; i++) { var x = K3D.bin.rsl(buff, off )/head.skinwidth; var y = K3D.bin.rsl(buff, off+2)/head.skinheight; res.c_uvt.push(x,y); off += 4; } var off = head.offset_tris; var vi = [], ti = []; res.i_verts = vi; res.i_uvt = ti; //res.tris = {i_verts : vi, i_uvt : ti}; for(var i=0; i<head.num_tris; i++) { vi.push(K3D.bin.rsl(buff, off ), K3D.bin.rsl(buff, off+2), K3D.bin.rsl(buff, off+4 )); ti.push(K3D.bin.rsl(buff, off+6), K3D.bin.rsl(buff, off+8), K3D.bin.rsl(buff, off+10)); off += 12; } var off = head.offset_skins; res.skins = []; for(var i=0; i<head.num_skins; i++) { res.skins.push(K3D.bin.rASCII0(buff, off)); off += 64; } var off = head.offset_frames; res.frames = []; var nms = K3D.parse.fromMD2._normals; for(var i=0; i<head.num_frames; i++) { var fr = {}; var sx = K3D.bin.rf(buff, off), sy = K3D.bin.rf(buff, off+4), sz = K3D.bin.rf(buff, off+8); off += 12; var tx = K3D.bin.rf(buff, off), ty = K3D.bin.rf(buff, off+4), tz = K3D.bin.rf(buff, off+8); off += 12; fr.name = K3D.bin.rASCII0(buff, off); off += 16; fr.verts = []; fr.norms = []; for(var j=0; j<head.num_vertices; j++) { fr.verts.push(buff[off]*sx+tx, buff[off+1]*sy+ty, buff[off+2]*sz+tz); fr.norms.push(nms[3*buff[off+3]], nms[3*buff[off+3]+1], nms[3*buff[off+3]+2]); off += 4; } res.frames.push(fr); } return res; } /* static MD2 normals */ K3D.parse.fromMD2._normals = [ -0.525731, 0.000000, 0.850651, -0.442863, 0.238856, 0.864188, -0.295242, 0.000000, 0.955423, -0.309017, 0.500000, 0.809017, -0.162460, 0.262866, 0.951056, 0.000000, 0.000000, 1.000000, 0.000000, 0.850651, 0.525731, -0.147621, 0.716567, 0.681718, 0.147621, 0.716567, 0.681718, 0.000000, 0.525731, 0.850651, 0.309017, 0.500000, 0.809017, 0.525731, 0.000000, 0.850651, 0.295242, 0.000000, 0.955423, 0.442863, 0.238856, 0.864188, 0.162460, 0.262866, 0.951056, -0.681718, 0.147621, 0.716567, -0.809017, 0.309017, 0.500000, -0.587785, 0.425325, 0.688191, -0.850651, 0.525731, 0.000000, -0.864188, 0.442863, 0.238856, -0.716567, 0.681718, 0.147621, -0.688191, 0.587785, 0.425325, -0.500000, 0.809017, 0.309017, -0.238856, 0.864188, 0.442863, -0.425325, 0.688191, 0.587785, -0.716567, 0.681718, -0.147621, -0.500000, 0.809017, -0.309017, -0.525731, 0.850651, 0.000000, 0.000000, 0.850651, -0.525731, -0.238856, 0.864188, -0.442863, 0.000000, 0.955423, -0.295242, -0.262866, 0.951056, -0.162460, 0.000000, 1.000000, 0.000000, 0.000000, 0.955423, 0.295242, -0.262866, 0.951056, 0.162460, 0.238856, 0.864188, 0.442863, 0.262866, 0.951056, 0.162460, 0.500000, 0.809017, 0.309017, 0.238856, 0.864188, -0.442863, 0.262866, 0.951056, -0.162460, 0.500000, 0.809017, -0.309017, 0.850651, 0.525731, 0.000000, 0.716567, 0.681718, 0.147621, 0.716567, 0.681718, -0.147621, 0.525731, 0.850651, 0.000000, 0.425325, 0.688191, 0.587785, 0.864188, 0.442863, 0.238856, 0.688191, 0.587785, 0.425325, 0.809017, 0.309017, 0.500000, 0.681718, 0.147621, 0.716567, 0.587785, 0.425325, 0.688191, 0.955423, 0.295242, 0.000000, 1.000000, 0.000000, 0.000000, 0.951056, 0.162460, 0.262866, 0.850651, -0.525731, 0.000000, 0.955423, -0.295242, 0.000000, 0.864188, -0.442863, 0.238856, 0.951056, -0.162460, 0.262866, 0.809017, -0.309017, 0.500000, 0.681718, -0.147621, 0.716567, 0.850651, 0.000000, 0.525731, 0.864188, 0.442863, -0.238856, 0.809017, 0.309017, -0.500000, 0.951056, 0.162460, -0.262866, 0.525731, 0.000000, -0.850651, 0.681718, 0.147621, -0.716567, 0.681718, -0.147621, -0.716567, 0.850651, 0.000000, -0.525731, 0.809017, -0.309017, -0.500000, 0.864188, -0.442863, -0.238856, 0.951056, -0.162460, -0.262866, 0.147621, 0.716567, -0.681718, 0.309017, 0.500000, -0.809017, 0.425325, 0.688191, -0.587785, 0.442863, 0.238856, -0.864188, 0.587785, 0.425325, -0.688191, 0.688191, 0.587785, -0.425325, -0.147621, 0.716567, -0.681718, -0.309017, 0.500000, -0.809017, 0.000000, 0.525731, -0.850651, -0.525731, 0.000000, -0.850651, -0.442863, 0.238856, -0.864188, -0.295242, 0.000000, -0.955423, -0.162460, 0.262866, -0.951056, 0.000000, 0.000000, -1.000000, 0.295242, 0.000000, -0.955423, 0.162460, 0.262866, -0.951056, -0.442863, -0.238856, -0.864188, -0.309017, -0.500000, -0.809017, -0.162460, -0.262866, -0.951056, 0.000000, -0.850651, -0.525731, -0.147621, -0.716567, -0.681718, 0.147621, -0.716567, -0.681718, 0.000000, -0.525731, -0.850651, 0.309017, -0.500000, -0.809017, 0.442863, -0.238856, -0.864188, 0.162460, -0.262866, -0.951056, 0.238856, -0.864188, -0.442863, 0.500000, -0.809017, -0.309017, 0.425325, -0.688191, -0.587785, 0.716567, -0.681718, -0.147621, 0.688191, -0.587785, -0.425325, 0.587785, -0.425325, -0.688191, 0.000000, -0.955423, -0.295242, 0.000000, -1.000000, 0.000000, 0.262866, -0.951056, -0.162460, 0.000000, -0.850651, 0.525731, 0.000000, -0.955423, 0.295242, 0.238856, -0.864188, 0.442863, 0.262866, -0.951056, 0.162460, 0.500000, -0.809017, 0.309017, 0.716567, -0.681718, 0.147621, 0.525731, -0.850651, 0.000000, -0.238856, -0.864188, -0.442863, -0.500000, -0.809017, -0.309017, -0.262866, -0.951056, -0.162460, -0.850651, -0.525731, 0.000000, -0.716567, -0.681718, -0.147621, -0.716567, -0.681718, 0.147621, -0.525731, -0.850651, 0.000000, -0.500000, -0.809017, 0.309017, -0.238856, -0.864188, 0.442863, -0.262866, -0.951056, 0.162460, -0.864188, -0.442863, 0.238856, -0.809017, -0.309017, 0.500000, -0.688191, -0.587785, 0.425325, -0.681718, -0.147621, 0.716567, -0.442863, -0.238856, 0.864188, -0.587785, -0.425325, 0.688191, -0.309017, -0.500000, 0.809017, -0.147621, -0.716567, 0.681718, -0.425325, -0.688191, 0.587785, -0.162460, -0.262866, 0.951056, 0.442863, -0.238856, 0.864188, 0.162460, -0.262866, 0.951056, 0.309017, -0.500000, 0.809017, 0.147621, -0.716567, 0.681718, 0.000000, -0.525731, 0.850651, 0.425325, -0.688191, 0.587785, 0.587785, -0.425325, 0.688191, 0.688191, -0.587785, 0.425325, -0.955423, 0.295242, 0.000000, -0.951056, 0.162460, 0.262866, -1.000000, 0.000000, 0.000000, -0.850651, 0.000000, 0.525731, -0.955423, -0.295242, 0.000000, -0.951056, -0.162460, 0.262866, -0.864188, 0.442863, -0.238856, -0.951056, 0.162460, -0.262866, -0.809017, 0.309017, -0.500000, -0.864188, -0.442863, -0.238856, -0.951056, -0.162460, -0.262866, -0.809017, -0.309017, -0.500000, -0.681718, 0.147621, -0.716567, -0.681718, -0.147621, -0.716567, -0.850651, 0.000000, -0.525731, -0.688191, 0.587785, -0.425325, -0.587785, 0.425325, -0.688191, -0.425325, 0.688191, -0.587785, -0.425325, -0.688191, -0.587785, -0.587785, -0.425325, -0.688191, -0.688191, -0.587785, -0.425325 ]; K3D.parse.fromCollada = function(buff) { var str = K3D.parse._buffToStr(buff); var xml = new DOMParser().parseFromString(str,"text/xml"); xml = xml.childNodes[0]; var resp = {}; //console.log(xml); var ass = xml.getElementsByTagName("asset" )[0]; var geo = xml.getElementsByTagName("library_geometries")[0]; var ima = xml.getElementsByTagName("library_images" )[0]; var mat = xml.getElementsByTagName("library_materials" )[0]; var eff = xml.getElementsByTagName("library_effects" )[0]; //console.log(xml); if(ass) resp.asset = K3D.parse.fromCollada._asset (ass); if(geo) resp.geometries = K3D.parse.fromCollada._libGeometries(geo); if(ima) resp.images = K3D.parse.fromCollada._libImages (ima); if(mat) resp.materials = K3D.parse.fromCollada._libMaterials (mat); if(eff) resp.effects = K3D.parse.fromCollada._libEffects (eff); return resp; } K3D.parse.fromCollada._asset = function(xml) { //console.log(xml); return { created : xml.getElementsByTagName("created" )[0].textContent, modified: xml.getElementsByTagName("modified")[0].textContent, up_axis : xml.getElementsByTagName("up_axis" )[0].textContent }; } K3D.parse.fromCollada._libGeometries = function(xml) { xml = xml.getElementsByTagName("geometry"); var res = []; for(var i=0; i<xml.length; i++) { var g = xml[i]; var o = K3D.parse.fromCollada._getMesh(g.getElementsByTagName("mesh")[0]); res.push(o); } return res; } K3D.parse.fromCollada._getMesh = function(mesh) { //console.log(mesh); var res = {}; var ss = mesh.getElementsByTagName("source"); var sources = res.sources = {}; for(var i=0; i<ss.length; i++) { var farr = ss[i].getElementsByTagName("float_array")[0].textContent.split(" "); var fl = farr.length - (farr[farr.length-1] == "" ? 1 : 0); var arr = new Array(fl); for(var j=0; j<fl; j++) arr[j] = parseFloat(farr[j]); sources[ss[i].getAttribute("id")] = arr; } res.triangles = []; var tgs = mesh.getElementsByTagName("triangles"); if(tgs == null) return res; for(var i=0; i<tgs.length; i++) { var t = {}; var tnode = tgs[i]; t.material = tnode.getAttribute("material"); var inputs = tnode.getElementsByTagName("input"); var inds = []; for(var j=0; j<inputs.length; j++) { var inp = inputs[j], arr = []; inds[parseInt(inp.getAttribute("offset"))] = arr; var par = inp.getAttribute("semantic"); t["s_"+par] = (par == "VERTEX") ? mesh.getElementsByTagName("vertices")[0].getElementsByTagName("input")[0].getAttribute("source").substring(1) : inp.getAttribute("source").substring(1); t["i_"+par] = arr; var psrc = sources[t["s_"+par]]; } var indices = tnode.getElementsByTagName("p")[0].textContent.split(" "); var inum = 3*Math.floor(indices.length/3); for(var j=0; j<inum; j++) inds[j%inputs.length].push(parseInt(indices[j])); /* if(t.s_VERTEX ) t.u_VERTEX = K3D.edit.unwrap(t.i_VERTEX , sources[t.s_VERTEX ], 3); if(t.s_TEXCOORD) t.u_TEXCOORD = K3D.edit.unwrap(t.i_TEXCOORD, sources[t.s_TEXCOORD], 2); if(t.s_NORMAL ) t.u_NORMAL = K3D.edit.unwrap(t.i_NORMAL , sources[t.s_NORMAL ], 3); //*/ //if(t.s_TEXCOORD) for(var j=1; j<t.u_TEXCOORD.length; j+=2) t.u_TEXCOORD[j] = 1 - t.u_TEXCOORD[j]; /* t.u_INDEX = new Array(t.i_VERTEX.length); for(var j=0; j<t.i_VERTEX.length; j++) t.u_INDEX[j] = j; */ res.triangles.push(t); } return res; } K3D.parse.fromCollada._libImages = function(xml) { xml = xml.getElementsByTagName("image"); var res = {}; for(var i=0; i<xml.length; i++) { res[xml[i].getAttribute("id")] = xml[i].getElementsByTagName("init_from")[0].textContent; } return res; } K3D.parse.fromCollada._libMaterials = function(xml) { xml = xml.getElementsByTagName("material"); var res = {}; for(var i=0; i<xml.length; i++) { res[xml[i].getAttribute("name")] = xml[i].getElementsByTagName("instance_effect")[0].getAttribute("url").substring(1); } return res; } K3D.parse.fromCollada._libEffects = function(xml) { xml = xml.getElementsByTagName("effect"); var res = {}; for(var i=0; i<xml.length; i++) { var eff = {}; var params = xml[i].getElementsByTagName("newparam"); for(var j=0; j<params.length; j++) { var srf = params[j].getElementsByTagName("surface")[0]; if(srf) eff.surface = srf.getElementsByTagName("init_from")[0].textContent; } res[xml[i].getAttribute("id")] = eff; } return res; } K3D.parse.from3DS = function(buff) { buff = new Uint8Array(buff); var res = {}; if(K3D.bin.rsl(buff, 0) != 0x4d4d) return null; var lim = K3D.bin.ril(buff, 2); var off = 6; while(off < lim) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log(cid.toString(16), lng); if(cid == 0x3d3d) res.edit = K3D.parse.from3DS._edit3ds(buff, off, lng); if(cid == 0xb000) res.keyf = K3D.parse.from3DS._keyf3ds(buff, off, lng); off += lng; } return res; } K3D.parse.from3DS._edit3ds = function(buff, coff, clng) // buffer, chunk offset, length { var res = {}; var off = coff+6; while(off < coff+clng) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log("\t", cid.toString(16), lng); if(cid == 0x4000) { if(res.objects==null) res.objects = []; res.objects.push(K3D.parse.from3DS._edit_object(buff, off, lng)); } //if(cid == 0xb000) res.KEYF3DS = K3D.parse.from3DS._keyf3ds(buff, off, lng); off += lng; } return res; } K3D.parse.from3DS._keyf3ds = function(buff, coff, clng) { var res = {}; var off = coff+6; while(off < coff+clng) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log("\t\t", cid.toString(16), lng); //if(cid == 0x4000) { res.objects.push(K3D.parse.from3DS._edit_object(buff, off, lng)); } if(cid == 0xb002) { if(res.desc==null) res.desc = []; res.desc.push(K3D.parse.from3DS._keyf_objdes(buff, off, lng)); } off += lng; } return res; } K3D.parse.from3DS._keyf_objdes = function(buff, coff, clng) { var res = {}; var off = coff+6; while(off < coff+clng) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log("\t\t\t", cid.toString(16), lng); if(cid == 0xb010) res.hierarchy = K3D.parse.from3DS._keyf_objhierarch(buff, off, lng); if(cid == 0xb011) res.dummy_name = K3D.bin.rASCII0(buff, off+6); off += lng; } return res; } K3D.parse.from3DS._keyf_objhierarch = function(buff, coff, clng) { var res = {}; var off = coff+6; res.name = K3D.bin.rASCII0(buff, off); off += res.name.length+1; res.hierarchy = K3D.bin.rsl(buff, off+4); return res; } K3D.parse.from3DS._edit_object = function(buff, coff, clng) // buffer, chunk offset, length { var res = {}; var off = coff+6; res.name = K3D.bin.rASCII0(buff, off); off += res.name.length+1; //console.log(res.name); while(off < coff+clng) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log("\t\t", cid.toString(16), lng); if(cid == 0x4100) res.mesh = K3D.parse.from3DS._obj_trimesh(buff, off, lng); //if(cid == 0xb000) res.KEYF3DS = K3D.parse.from3DS._keyf3ds(buff, off, lng); off += lng; } return res; } K3D.parse.from3DS._obj_trimesh = function(buff, coff, clng) // buffer, chunk offset, length { var res = {}; var off = coff+6; while(off < coff+clng) { var cid = K3D.bin.rsl(buff, off); var lng = K3D.bin.ril(buff, off+2); //console.log("\t\t\t", cid.toString(16), lng); if(cid == 0x4110) res.vertices = K3D.parse.from3DS._tri_vertexl (buff, off, lng); if(cid == 0x4120) res.indices = K3D.parse.from3DS._tri_facel1 (buff, off, lng); if(cid == 0x4140) res.uvt = K3D.parse.from3DS._tri_mappingcoors(buff, off, lng); if(cid == 0x4160) res.local = K3D.parse.from3DS._tri_local (buff, off, lng); off += lng; } return res; } K3D.parse.from3DS._tri_vertexl = function(buff, coff, clng) // buffer, chunk offset, length { var res = []; var off = coff+6; var n = K3D.bin.rsl(buff, off); off += 2; for(var i=0; i<n; i++) { res.push(K3D.bin.rf(buff, off )); res.push(K3D.bin.rf(buff, off+4)); res.push(K3D.bin.rf(buff, off+8)); off += 12; } return res; } K3D.parse.from3DS._tri_facel1 = function(buff, coff, clng) // buffer, chunk offset, length { var res = []; var off = coff+6; var n = K3D.bin.rsl(buff, off); off += 2; for(var i=0; i<n; i++) { res.push(K3D.bin.rsl(buff, off )); res.push(K3D.bin.rsl(buff, off+2)); res.push(K3D.bin.rsl(buff, off+4)); off += 8; } return res; } K3D.parse.from3DS._tri_mappingcoors = function(buff, coff, clng) // buffer, chunk offset, length { var res = []; var off = coff+6; var n = K3D.bin.rsl(buff, off); off += 2; for(var i=0; i<n; i++) { res.push( K3D.bin.rf(buff, off )); res.push(1-K3D.bin.rf(buff, off+4)); off += 8; } return res; } K3D.parse.from3DS._tri_local = function(buff, coff, clng) // buffer, chunk offset, length { var res = {}; var off = coff+6; res.X = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)]; off += 12; res.Y = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)]; off += 12; res.Z = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)]; off += 12; res.C = [K3D.bin.rf(buff, off), K3D.bin.rf(buff, off+4), K3D.bin.rf(buff, off+8)]; off += 12; return res; } K3D.parse.fromBIV = function(buff) { buff = new Uint8Array(buff); var res = {}; var head = {}; head.id = K3D.bin.ril(buff, 0); head.verS = K3D.bin.ril(buff, 4); head.texS = K3D.bin.ril(buff, 8); head.indS = K3D.bin.ril(buff, 12); head.verO = K3D.bin.ril(buff, 16); head.verL = K3D.bin.ril(buff, 20); head.texO = K3D.bin.ril(buff, 24); head.texL = K3D.bin.ril(buff, 28); head.indO = K3D.bin.ril(buff, 32); head.indL = K3D.bin.ril(buff, 36); if(head.verO != 0) res.vertices = K3D.parse.fromBIV._readFloats(buff, head.verO, head.verL); if(head.texO != 0) res.uvt = K3D.parse.fromBIV._readFloats(buff, head.texO, head.texL); if(head.indO != 0) res.indices = K3D.parse.fromBIV._readInts (buff, head.indO, head.indL, head.indS); return res; } K3D.parse.toBIV = function(obj) { var maxi = 0; for(var i=0; i<obj.indices.length; i++) maxi = Math.max(maxi, obj.indices[i]); var indS = 32; if(maxi<=0xffff) indS = 16; var len = 40; if(obj.vertices) len+=obj.vertices.length*4; if(obj.uvt ) len+=obj.uvt .length*4; if(obj.indices ) len+=obj.indices .length*indS/8; var buff = new Uint8Array(len); K3D.bin.wil(buff, 0, 0x6976616e); K3D.bin.wil(buff, 4, 32); K3D.bin.wil(buff, 8, 32); K3D.bin.wil(buff, 12, indS); var off = 40; if(obj.vertices) { K3D.bin.wil(buff, 16, off); K3D.bin.wil(buff, 20, 4*obj.vertices.length); K3D.parse.fromBIV._writeFloats(buff, off, obj.vertices); off += 4*obj.vertices.length; } if(obj.uvt) { K3D.bin.wil(buff, 24, off); K3D.bin.wil(buff, 28, 4*obj.uvt.length); K3D.parse.fromBIV._writeFloats(buff, off, obj.uvt); off += 4*obj.uvt.length; } if(obj.indices) { K3D.bin.wil(buff, 32, off); K3D.bin.wil(buff, 36, 4*obj.indices.length); K3D.parse.fromBIV._writeInts (buff, off, obj.indices, indS); } return buff.buffer; } K3D.parse.fromBIV._readFloats = function(buff, off, len) { var arr = []; for(var i=0; i<len/4; i++) arr.push( K3D.bin.rf(buff, off+4*i)); return arr; } K3D.parse.fromBIV._writeFloats = function(buff, off, arr) { for(var i=0; i<arr.length; i++) K3D.bin.wf(buff, off+4*i, arr[i]); } K3D.parse.fromBIV._readInts = function(buff, off, len, cs) { var arr = []; for(var i=0; i<len/4; i++) { if(cs==16) arr.push( K3D.bin.rsl(buff, off+2*i)); if(cs==32) arr.push( K3D.bin.ril(buff, off+4*i)); } return arr; } K3D.parse.fromBIV._writeInts = function(buff, off, arr, cs) { for(var i=0; i<arr.length; i++) { if(cs==16) K3D.bin.wsl(buff, off+2*i, arr[i]); if(cs==32) K3D.bin.wil(buff, off+4*i, arr[i]); } } K3D.gen = {}; K3D.gen.Plane = function(sw, sh, tsw, tsh) { if(!tsw) tsw = 1; if(!tsh) tsh = 1; var r = {verts:[], inds:[], uvt:[]}; var ssw = sw+1, ssh = sh+1 for(var i=0; i<ssh; i++) { for(var j=0; j<ssw; j++) { var x = -1 + j*(2/sw); var y = -1 + i*(2/sh); r.verts.push(x, y, 0); r.uvt.push(tsw*j/sw, tsh*i/sh); if(i<sh && j<sw) r.inds.push(i*ssw+j, i*ssw+j+1, (i+1)*ssw+j, i*ssw+j+1, (i+1)*ssw+j, (i+1)*ssw+j+1); } } return r; } K3D.gen.Cube = function() { var r = { verts:[ -1, 1,-1, 1, 1,-1, -1,-1,-1, 1,-1,-1, // front -1, 1, 1, 1, 1, 1, -1,-1, 1, 1,-1, 1, // back -1, 1, 1, -1, 1,-1, -1,-1, 1, -1,-1,-1, // left 1, 1, 1, 1, 1,-1, 1,-1, 1, 1,-1,-1, // right -1, 1,-1, 1, 1,-1, -1, 1, 1, 1, 1, 1, // top -1,-1,-1, 1,-1,-1, -1,-1, 1, 1,-1, 1 // bottom ], inds:[ 0,1,2, 1,2,3, 4,5,6, 5,6,7, 8,9,10, 9,10,11, 12,13,14, 13,14,15, 16,17,18, 17,18,19, 20,21,22, 21,22,23 ], uvt:[ 1/4,1/4, 2/4,1/4, 1/4,2/4, 2/4,2/4, // front 4/4,1/4, 3/4,1/4, 4/4,2/4, 3/4,2/4, // back 0/4,1/4, 1/4,1/4, 0/4,2/4, 1/4,2/4, // left 3/4,1/4, 2/4,1/4, 3/4,2/4, 2/4,2/4, // right 1/4,1/4, 2/4,1/4, 1/4,0/4, 2/4,0/4, // top 1/4,2/4, 2/4,2/4, 1/4,3/4, 2/4,3/4, // bottom ] }; return r; }; K3D.gen.Sphere = function(sx, sy){ var r = {verts:[], inds:[], uvt:[]}; var dx = 2*Math.PI/sx; var dy = Math.PI/sy; var nx = sx+1, ny = sy+1; for(var i=0; i<ny; i++) // rows { for(var j=0; j<nx; j++) // cols { var lat = -Math.PI/2 + i*Math.PI/sy; var lon = j*2*Math.PI/sx; var x = Math.cos(lat) * Math.cos(lon); var y = Math.sin(lat); var z = Math.cos(lat) * Math.sin(lon); r.verts.push(x,y,z); r.uvt.push(j/sx, i/sy); if(i<sy && j<sx) // 6 indices for 2 triangles r.inds.push(nx*i+j, nx*i+j+1, nx*(i+1)+j, nx*i+j+1, nx*(i+1)+j, nx*(i+1)+j+1); } } return r; }; K3D.mat = {}; K3D.mat.scale = function(x,y,z){ return [ x,0,0,0, 0,y,0,0, 0,0,z,0, 0,0,0,1 ]; }; K3D.mat.translate = function(x,y,z){ return [ 1,0,0,0, 0,1,0,0, 0,0,1,0, x,y,z,1 ]; }; K3D.mat.rotateDeg = function(x,y,z){ var r = Math.PI/180; return K3D.mat.rotate(x*r, y*r, z*r); }; K3D.mat.rotate = function(x,y,z){ var m = [ 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 ]; var a = x; // alpha var b = y; // beta var g = z; // gama var ca = Math.cos(a), cb = Math.cos(b), cg = Math.cos(g); var sa = Math.sin(a), sb = Math.sin(b), sg = Math.sin(g); m[0] = cb*cg; m[1] = -cb*sg; m[2 ] = sb; m[4] = (ca*sg+sa*sb*cg); m[5] = (ca*cg-sa*sb*sg); m[6 ] = -sa*cb; m[8] = (sa*sg-ca*sb*cg); m[9] = (sa*cg+ca*sb*sg); m[10] = ca*cb; return m; }; K3D.edit = {}; K3D.edit.interpolate = function(a, b, d, t){ for(var i=0; i<a.length; i++) d[i] = a[i] + t*(b[i] - a[i]); }; K3D.edit.transform = function(a, m){ for(var i=0; i<a.length; i+=3) { var x = a[i], y = a[i+1], z = a[i+2]; a[i+0] = m[0]*x + m[4]*y + m[8 ]*z + m[12]; a[i+1] = m[1]*x + m[5]*y + m[9 ]*z + m[13]; a[i+2] = m[2]*x + m[6]*y + m[10]*z + m[14]; } }; // starting indices, starting coordinates, coordinates per index K3D.edit.unwrap = function(ind, crd, cpi){ var ncrd = new Array(Math.floor(ind.length/3)*cpi); for(var i=0; i<ind.length; i++) { for(var j=0; j<cpi; j++) { ncrd[i*cpi+j] = crd[ind[i]*cpi+j]; } } return ncrd; }; // current indices, new indices, current array, coordinates per vertex K3D.edit.remap = function(ind, nind, arr, cpi){ var ncrd = new Array(arr.length); for(var i=0; i<ind.length; i++) { for(var j=0; j<cpi; j++) { ncrd[nind[i]*cpi+j] = arr[ind[i]*cpi+j]; } } return ncrd; }; K3D.utils = {}; K3D.utils.getAABB = function(vts) { var minx, miny, minz, maxx, maxy, maxz; minx = miny = minz = 999999999; maxx = maxy = maxz = -minx; for(var i=0; i<vts.length; i+=3) { var vx = vts[i+0]; var vy = vts[i+1]; var vz = vts[i+2]; if(vx<minx) minx = vx; if(vx>maxx) maxx = vx; if(vy<miny) miny = vy; if(vy>maxy) maxy = vy; if(vz<minz) minz = vz; if(vy>maxz) maxz = vz; } return {min:{x:minx, y:miny, z:minz}, max:{x:maxx, y:maxy, z:maxz}}; }; export {K3D};