Files
armorpaint/Sources/arm/io/ExportObj.hx
T
luboslenco 30aff91780 Cleanup
2021-01-15 16:07:55 +01:00

165 lines
4.3 KiB
Haxe

package arm.io;
import haxe.io.Bytes;
import haxe.io.BytesOutput;
import kha.arrays.Int16Array;
class ExportObj {
public static function run(path: String, applyDisplacement = false) {
// var height = applyDisplacement ? Project.layers[0].texpaint_pack.getPixels() : null;
// var res = Project.layers[0].texpaint_pack.width;
var o = new BytesOutput();
o.bigEndian = false;
o.writeString("# armorpaint.org\n");
var poff = 0;
var noff = 0;
var toff = 0;
for (p in Project.paintObjects) {
var mesh = p.data.raw;
var inv = 1 / 32767;
var sc = p.data.scalePos * inv;
var posa = mesh.vertex_arrays[0].values;
var nora = mesh.vertex_arrays[1].values;
var texa = mesh.vertex_arrays[2].values;
var len = Std.int(posa.length / 4);
// Merge shared vertices and remap indices
var posa2 = new Int16Array(len * 3);
var nora2 = new Int16Array(len * 3);
var texa2 = new Int16Array(len * 2);
var posmap = new Map<Int, Int>();
var normap = new Map<Int, Int>();
var texmap = new Map<Int, Int>();
var pi = 0;
var ni = 0;
var ti = 0;
for (i in 0...len) {
var found = false;
for (j in 0...pi) {
if (posa2[j * 3 ] == posa[i * 4 ] &&
posa2[j * 3 + 1] == posa[i * 4 + 1] &&
posa2[j * 3 + 2] == posa[i * 4 + 2]) {
posmap.set(i, j);
found = true;
break;
}
}
if (!found) {
posmap.set(i, pi);
posa2[pi * 3 ] = posa[i * 4 ];
posa2[pi * 3 + 1] = posa[i * 4 + 1];
posa2[pi * 3 + 2] = posa[i * 4 + 2];
pi++;
}
found = false;
for (j in 0...ni) {
if (nora2[j * 3 ] == nora[i * 2 ] &&
nora2[j * 3 + 1] == nora[i * 2 + 1] &&
nora2[j * 3 + 2] == posa[i * 4 + 3]) {
normap.set(i, j);
found = true;
break;
}
}
if (!found) {
normap.set(i, ni);
nora2[ni * 3 ] = nora[i * 2 ];
nora2[ni * 3 + 1] = nora[i * 2 + 1];
nora2[ni * 3 + 2] = posa[i * 4 + 3];
ni++;
}
found = false;
for (j in 0...ti) {
if (texa2[j * 2 ] == texa[i * 2 ] &&
texa2[j * 2 + 1] == texa[i * 2 + 1]) {
texmap.set(i, j);
found = true;
break;
}
}
if (!found) {
texmap.set(i, ti);
texa2[ti * 2 ] = texa[i * 2 ];
texa2[ti * 2 + 1] = texa[i * 2 + 1];
ti++;
}
}
// if (applyDisplacement) {
// }
o.writeString("o " + p.name + "\n");
for (i in 0...pi) {
o.writeString("v ");
o.writeString(posa2[i * 3] * sc + "");
o.writeString(" ");
o.writeString(posa2[i * 3 + 2] * sc + "");
o.writeString(" ");
o.writeString(-posa2[i * 3 + 1] * sc + "");
o.writeString("\n");
}
for (i in 0...ni) {
o.writeString("vn ");
o.writeString(nora2[i * 3] * inv + "");
o.writeString(" ");
o.writeString(nora2[i * 3 + 2] * inv + "");
o.writeString(" ");
o.writeString(-nora2[i * 3 + 1] * inv + "");
o.writeString("\n");
}
for (i in 0...ti) {
o.writeString("vt ");
o.writeString(texa2[i * 2] * inv + "");
o.writeString(" ");
o.writeString(1.0 - texa2[i * 2 + 1] * inv + "");
o.writeString("\n");
}
var inda = mesh.index_arrays[0].values;
for (i in 0...Std.int(inda.length / 3)) {
var pi1 = posmap.get(inda[i * 3 ]) + 1 + poff;
var pi2 = posmap.get(inda[i * 3 + 1]) + 1 + poff;
var pi3 = posmap.get(inda[i * 3 + 2]) + 1 + poff;
var ni1 = normap.get(inda[i * 3 ]) + 1 + noff;
var ni2 = normap.get(inda[i * 3 + 1]) + 1 + noff;
var ni3 = normap.get(inda[i * 3 + 2]) + 1 + noff;
var ti1 = texmap.get(inda[i * 3 ]) + 1 + toff;
var ti2 = texmap.get(inda[i * 3 + 1]) + 1 + toff;
var ti3 = texmap.get(inda[i * 3 + 2]) + 1 + toff;
o.writeString("f ");
o.writeString(pi1 + "");
o.writeString("/");
o.writeString(ti1 + "");
o.writeString("/");
o.writeString(ni1 + "");
o.writeString(" ");
o.writeString(pi2 + "");
o.writeString("/");
o.writeString(ti2 + "");
o.writeString("/");
o.writeString(ni2 + "");
o.writeString(" ");
o.writeString(pi3 + "");
o.writeString("/");
o.writeString(ti3 + "");
o.writeString("/");
o.writeString(ni3 + "");
o.writeString("\n");
}
poff += pi;
noff += ni;
toff += ti;
}
if (!path.endsWith(".obj")) path += ".obj";
Krom.fileSaveBytes(path, o.getBytes().getData(), o.getBytes().length);
}
}