Comparing version 0.0.2 to 0.0.3
{ | ||
"name": "voxel-toy", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Tool for converting .vox files to other useful formats", | ||
@@ -29,2 +29,3 @@ "main": "src/index.js", | ||
"args": "^5.0.1", | ||
"lodash": "^4.17.11", | ||
"vox-reader": "^1.0.0" | ||
@@ -31,0 +32,0 @@ }, |
@@ -25,4 +25,4 @@ #!/usr/bin/env node | ||
const voxBuffer = await readBuffer(voxFile); | ||
const voxels = parseVoxels(voxBuffer); | ||
const t3dText = convertToT3D(voxels, size); | ||
const voxelData = parseVoxels(voxBuffer); | ||
const t3dText = convertToT3D(voxelData, size); | ||
const t3dFile = changeExtension(voxFile, ".t3d"); | ||
@@ -29,0 +29,0 @@ |
159
src/t3d.js
@@ -1,2 +0,4 @@ | ||
const box = ({ x, y, z, vertexOffset, name }) => { | ||
const _ = require("lodash"); | ||
const box = ({ x, y, z, offsetX, offsetY, offsetZ, name }) => { | ||
return ` | ||
@@ -13,10 +15,10 @@ Begin Actor Class=Brush Name=${name} Archetype=Brush'/Script/Engine.Default__Brush' | ||
Begin Object Name="CubeBuilder_0" | ||
Vertices(0)=(X=-${vertexOffset},Y=-${vertexOffset},Z=-${vertexOffset}) | ||
Vertices(1)=(X=-${vertexOffset},Y=-${vertexOffset},Z=${vertexOffset}) | ||
Vertices(2)=(X=-${vertexOffset},Y=${vertexOffset},Z=-${vertexOffset}) | ||
Vertices(3)=(X=-${vertexOffset},Y=${vertexOffset},Z=${vertexOffset}) | ||
Vertices(4)=(X=${vertexOffset},Y=-${vertexOffset},Z=-${vertexOffset}) | ||
Vertices(5)=(X=${vertexOffset},Y=-${vertexOffset},Z=${vertexOffset}) | ||
Vertices(6)=(X=${vertexOffset},Y=${vertexOffset},Z=-${vertexOffset}) | ||
Vertices(7)=(X=${vertexOffset},Y=${vertexOffset},Z=${vertexOffset}) | ||
Vertices(0)=(X=-${offsetX},Y=-${offsetY},Z=-${offsetZ}) | ||
Vertices(1)=(X=-${offsetX},Y=-${offsetY},Z=${offsetZ}) | ||
Vertices(2)=(X=-${offsetX},Y=${offsetY},Z=-${offsetZ}) | ||
Vertices(3)=(X=-${offsetX},Y=${offsetY},Z=${offsetZ}) | ||
Vertices(4)=(X=${offsetX},Y=-${offsetY},Z=-${offsetZ}) | ||
Vertices(5)=(X=${offsetX},Y=-${offsetY},Z=${offsetZ}) | ||
Vertices(6)=(X=${offsetX},Y=${offsetY},Z=-${offsetZ}) | ||
Vertices(7)=(X=${offsetX},Y=${offsetY},Z=${offsetZ}) | ||
Polys(0)=(VertexIndices=(0,1,3,2),Direction=1) | ||
@@ -41,60 +43,60 @@ Polys(1)=(VertexIndices=(2,3,7,6),Direction=1) | ||
Begin Polygon | ||
Origin -${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Origin -${offsetX},-${offsetY},-${offsetZ} | ||
Normal -1,+0,+0 | ||
TextureU +0,+1,+0 | ||
TextureV +0,+0,-1 | ||
Vertex -${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex -${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex -${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex -${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex -${offsetX},-${offsetY},-${offsetZ} | ||
Vertex -${offsetX},-${offsetY},+${offsetZ} | ||
Vertex -${offsetX},+${offsetY},+${offsetZ} | ||
Vertex -${offsetX},+${offsetY},-${offsetZ} | ||
End Polygon | ||
Begin Polygon | ||
Origin -${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Origin -${offsetX},+${offsetY},-${offsetZ} | ||
Normal +0,+1,+0 | ||
TextureU +1,-0,+0 | ||
TextureV +0,+0,-1 | ||
Vertex -${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex -${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex -${offsetX},+${offsetY},-${offsetZ} | ||
Vertex -${offsetX},+${offsetY},+${offsetZ} | ||
Vertex +${offsetX},+${offsetY},+${offsetZ} | ||
Vertex +${offsetX},+${offsetY},-${offsetZ} | ||
End Polygon | ||
Begin Polygon | ||
Origin +${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Origin +${offsetX},+${offsetY},-${offsetZ} | ||
Normal +1,+0,+0 | ||
TextureU +0,-1,+0 | ||
TextureV +0,+0,-1 | ||
Vertex +${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex +${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex +${offsetX},+${offsetY},-${offsetZ} | ||
Vertex +${offsetX},+${offsetY},+${offsetZ} | ||
Vertex +${offsetX},-${offsetY},+${offsetZ} | ||
Vertex +${offsetX},-${offsetY},-${offsetZ} | ||
End Polygon | ||
Begin Polygon | ||
Origin +${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Origin +${offsetX},-${offsetY},-${offsetZ} | ||
Normal +0,-1,+0 | ||
TextureU -1,-0,-0 | ||
TextureV +0,+0,-1 | ||
Vertex +${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex +${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex -${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex -${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex +${offsetX},-${offsetY},-${offsetZ} | ||
Vertex +${offsetX},-${offsetY},+${offsetZ} | ||
Vertex -${offsetX},-${offsetY},+${offsetZ} | ||
Vertex -${offsetX},-${offsetY},-${offsetZ} | ||
End Polygon | ||
Begin Polygon | ||
Origin -${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Origin -${offsetX},+${offsetY},+${offsetZ} | ||
Normal +0,+0,+1 | ||
TextureU +1,+0,+0 | ||
TextureV +0,+1,+0 | ||
Vertex -${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex -${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},-${vertexOffset},+${vertexOffset} | ||
Vertex +${vertexOffset},+${vertexOffset},+${vertexOffset} | ||
Vertex -${offsetX},+${offsetY},+${offsetZ} | ||
Vertex -${offsetX},-${offsetY},+${offsetZ} | ||
Vertex +${offsetX},-${offsetY},+${offsetZ} | ||
Vertex +${offsetX},+${offsetY},+${offsetZ} | ||
End Polygon | ||
Begin Polygon | ||
Origin -${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Origin -${offsetX},-${offsetY},-${offsetZ} | ||
Normal +0,+0,-1 | ||
TextureU +1,+0,+0 | ||
TextureV +0,-1,+0 | ||
Vertex -${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex -${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex +${vertexOffset},+${vertexOffset},-${vertexOffset} | ||
Vertex +${vertexOffset},-${vertexOffset},-${vertexOffset} | ||
Vertex -${offsetX},-${offsetY},-${offsetZ} | ||
Vertex -${offsetX},+${offsetY},-${offsetZ} | ||
Vertex +${offsetX},+${offsetY},-${offsetZ} | ||
Vertex +${offsetX},-${offsetY},-${offsetZ} | ||
End Polygon | ||
@@ -109,2 +111,3 @@ End PolyList | ||
ActorLabel="${name}" | ||
FolderPath="VoxelToyGeometry" | ||
End Actor | ||
@@ -114,12 +117,66 @@ `; | ||
const convertToT3D = (voxels, size = 200) => { | ||
const vertexOffset = size * 0.5; | ||
const positions = voxels.children.find(x => x.id == "XYZI"); | ||
const boxes = positions.data.values.map(({ x, y, z }, idx) => | ||
const merge = (voxels, axis) => { | ||
const lastIdx = voxels.length - 1; | ||
const last = voxels[lastIdx]; | ||
return Object.assign(last, { | ||
x: (voxels[0].x + voxels[lastIdx].x) * 0.5, | ||
y: (voxels[0].y + voxels[lastIdx].y) * 0.5, | ||
z: (voxels[0].z + voxels[lastIdx].z) * 0.5, | ||
[`side${axis.toUpperCase()}`]: voxels[lastIdx][axis] - voxels[0][axis] + 1 | ||
}); | ||
}; | ||
const optimize = (voxels, axis, canMerge = (a, b) => true) => { | ||
const groups = _.groupBy(voxels, vox => | ||
["x", "y", "z"] | ||
.filter(k => k != axis) | ||
.map(k => vox[k]) | ||
.join("-") | ||
); | ||
const results = []; | ||
Object.keys(groups).forEach(key => { | ||
const sorted = _.sortBy(groups[key], vox => vox[axis]); | ||
const mergeable = _.reduce( | ||
sorted, | ||
(acc, current) => { | ||
const arr = acc[acc.length - 1]; | ||
const previous = arr[arr.length - 1]; | ||
if (!previous) arr.push(current); | ||
else if ( | ||
current[axis] - previous[axis] == 1 && | ||
canMerge(previous, current) | ||
) | ||
arr.push(current); | ||
else acc.push([current]); | ||
return acc; | ||
}, | ||
[[]] | ||
); | ||
mergeable.forEach(arr => results.push(merge(arr, axis))); | ||
}); | ||
return results; | ||
}; | ||
const convertToT3D = (voxelData, size = 200) => { | ||
let voxels = voxelData.children.find(x => x.id == "XYZI").data.values; | ||
voxels = voxels.map(vox => Object.assign(vox, { sideX: 1, sideY: 1, sideZ: 1})); | ||
voxels = optimize(voxels, "z"); | ||
voxels = optimize(voxels, "y", (a, b) => a.sideZ == b.sideZ); | ||
voxels = optimize(voxels, "x", (a, b) => a.sideZ == b.sideZ && a.sideY == b.sideY); | ||
const boxes = voxels.map((vox, idx) => | ||
box({ | ||
x: x * size, | ||
y: y * size, | ||
z: z * size, | ||
name: `Box${idx}`, | ||
vertexOffset | ||
x: vox.x * size, | ||
y: vox.y * size, | ||
z: vox.z * size, | ||
offsetX: vox.sideX * size * 0.5, | ||
offsetY: vox.sideY * size * 0.5, | ||
offsetZ: vox.sideZ * size * 0.5, | ||
name: `Box${idx}` | ||
}) | ||
@@ -130,5 +187,5 @@ ); | ||
Begin Map | ||
Begin Level | ||
${boxes.join("\n")} | ||
End Level | ||
Begin Level | ||
${boxes.join("\n")} | ||
End Level | ||
End Map | ||
@@ -135,0 +192,0 @@ `.trim(); |
13253
260
3
+ Addedlodash@^4.17.11
+ Addedlodash@4.17.21(transitive)