Last active
August 29, 2015 14:20
-
-
Save haxiomic/0a47f77b5cadc29e248c to your computer and use it in GitHub Desktop.
voxel flatten
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function createSliceTexture(vox:Vox, axis:Int = 0, ?params:TextureParams, maxW:Null<Int> = 4096, POT:Bool = true):SliceTexture{ | |
if(params == null) params = {}; | |
var defaultParams = { | |
channelType: GL.RGBA, | |
dataType: GL.UNSIGNED_BYTE, | |
filter: GL.LINEAR, | |
wrapS: GL.CLAMP_TO_EDGE, | |
wrapT: GL.CLAMP_TO_EDGE, | |
unpackAlignment: TextureTools.defaultParams.unpackAlignment | |
}; | |
//extend default params | |
for(f in Reflect.fields(defaultParams)) | |
if(!Reflect.hasField(params, f)) | |
Reflect.setField(params, f, Reflect.field(defaultParams, f)); | |
//clamp | |
axis = Math.floor(Math.min(3, Math.max(0, axis))); | |
//determine how to fit slices to texture | |
if(maxW == null){ | |
maxW = GL.getParameter(GL.MAX_TEXTURE_SIZE); | |
}else{ | |
maxW = Math.floor(Math.min(maxW, GL.getParameter(GL.MAX_TEXTURE_SIZE))); | |
} | |
//fit width first then fit height | |
var nSlices:Int = 0; | |
var sliceW:Int = 0; | |
var sliceH:Int = 0; | |
switch axis{ | |
case 0://xzy | |
nSlices = vox.size.x; | |
sliceW = vox.size.z; | |
sliceH = vox.size.y; | |
case 1://yxz | |
nSlices = vox.size.y; | |
sliceW = vox.size.x; | |
sliceH = vox.size.z; | |
case 2://zxy | |
nSlices = vox.size.z; | |
sliceW = vox.size.x; | |
sliceH = vox.size.y; | |
} | |
//how many slices can fit within maxW | |
//if remainder, what's the nearest ceiling POT? | |
var nCols:Int = Math.floor(maxW / sliceW); | |
var nRows:Int = Math.ceil(nSlices / nCols); | |
if(nRows <= 1) nCols = nSlices; | |
var width = nCols * sliceW; | |
var height = nRows * sliceH; | |
var textureWidth = POT ? MathTools.upperPowerOf2(width) : width; | |
var textureHeight = POT ? MathTools.upperPowerOf2(height) : height; | |
var texture = TextureTools.createTexture(textureWidth, textureHeight, params); | |
//generate texture | |
var nChannels:Int = switch params.channelType{ | |
case GL.RGBA: 4; | |
case GL.RGB: 3; | |
case GL.ALPHA: 1; | |
case GL.LUMINANCE: 1; | |
case GL.LUMINANCE_ALPHA: 2; | |
default: 4; | |
} | |
var pixelData = new Array<Int>(); | |
//write zeros | |
for(i in 0...textureWidth * textureHeight * nChannels){ | |
pixelData[i] = 0; | |
} | |
inline function getIndex(x:Int, y:Int):Int{ | |
return (y * textureWidth + x) * nChannels; | |
} | |
inline function setPixel(x:Int, y:Int, data:Array<Int>){ | |
var i = getIndex(x, y); | |
var j = 0; | |
while(j < nChannels){ | |
pixelData[i + j] = data[j]; | |
j++; | |
} | |
} | |
var col:VoxReader.RGBA; | |
/*inline*/ function getColorArray(v:VoxReader.Voxel):Array<Int>{ | |
col = vox.palette[v.colorIndex - 1]; | |
//@!tmp quick hack to reduce alpha without editing the .vox | |
var reducedAlpha = Math.round(col.a * 0.1); | |
return [col.r, col.g, col.b, reducedAlpha]; | |
} | |
var offsetX:Int, offsetY:Int, px:Int, py:Int, i:Int; | |
switch axis { | |
case 0: for(v in vox.voxels){ | |
offsetX = (v.x % nCols) * sliceW; | |
offsetY = Math.floor(v.x / nCols) * sliceH; | |
px = v.z + offsetX; | |
py = v.y + offsetY; | |
setPixel(px, py, getColorArray(v)); | |
} | |
case 1: for(v in vox.voxels){ | |
offsetX = (v.y % nCols) * sliceW; | |
offsetY = Math.floor(v.y / nCols) * sliceH; | |
px = v.x + offsetX; | |
py = v.z + offsetY; | |
setPixel(px, py, getColorArray(v)); | |
} | |
case 2: for(v in vox.voxels){ | |
offsetX = (v.z % nCols) * sliceW; | |
offsetY = Math.floor(v.z / nCols) * sliceH; | |
px = v.x + offsetX; | |
py = v.y + offsetY; | |
setPixel(px, py, getColorArray(v)); | |
} | |
} | |
//write data to texture | |
GL.bindTexture (GL.TEXTURE_2D, texture); | |
GL.texImage2D(GL.TEXTURE_2D, 0, params.channelType, textureWidth, textureHeight, 0, params.channelType, params.dataType, new Uint8Array(pixelData)); | |
GL.bindTexture(GL.TEXTURE_2D, null); | |
var info = { | |
sliceW: sliceW, | |
sliceH: sliceH, | |
sliceD: nSlices, | |
nSlicesPerRow: nCols, | |
nSlices: nSlices, | |
textureW: textureWidth, | |
textureH: textureHeight | |
}; | |
return { | |
texture: texture, | |
info: info | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment