package com.vitco.importer; import com.vitco.util.file.FileIn; import com.vitco.util.file.RandomAccessFileIn; import java.awt.*; import java.io.File; import java.io.IOException; import java.math.BigInteger; /** * Kvx importer */ public class KvxImporter extends AbstractImporter { // constructor public KvxImporter(File file, String name) throws IOException { super(file, name); } @Override protected boolean read(FileIn fileIn, RandomAccessFileIn raf) throws IOException { fileIn.readIntRev(); //int numbytes = fileIn.readIntRev(); // read the dimensions int sx = fileIn.readIntRev(); int sy = fileIn.readIntRev(); int sz = fileIn.readIntRev(); if (sx == 0 || sy == 0 || sz == 0) { return false; } // read center (discards precision) int cx = Math.round(fileIn.readIntRev()/256f); int cy = Math.round(fileIn.readIntRev()/256f); int cz = Math.round(fileIn.readIntRev()/256f); // read the amounts in the different dimensions int sumxoffset = 0; int sumxyoffset = 0; // contains the offsets int[] xoffset = new int[sx + 1]; int[][] xyoffset = new int[sx][sy + 1]; // read the xoffset int prevx = fileIn.readIntRev(); xoffset[0] = prevx; for (int x = 1; x <= sx; x++) { int xoffSum = fileIn.readIntRev(); int xoff = xoffSum - prevx; sumxoffset += xoff; prevx = xoffSum; xoffset[x] = xoffSum; } // read the xyoffset for (int x = 0; x < sx; x++) { int prevxy = 0; for (int y = 0; y <= sy; y++) { int xyoffSum = fileIn.readShortRevUnsigned(); int xyoff = xyoffSum - prevxy; sumxyoffset += xyoff; prevxy = xyoffSum; xyoffset[x][y] = xyoffSum; } } // sanity checks if (sumxoffset != sumxyoffset) { return false; } if (xoffset[0] != (sx+1)*4 + sx*(sy+1)*2) { return false; } // Read the color palette (always at the end of the file) raf.seek(raf.length() - 768); int[] colPalette = new int[256]; for (int i = 0; i < 256; i++) { int r = Math.min(255, Math.max(0, Math.round((raf.read() * 255) / 63f))); int g = Math.min(255, Math.max(0, Math.round((raf.read() * 255) / 63f))); int b = Math.min(255, Math.max(0, Math.round((raf.read() * 255) / 63f))); colPalette[i] = new Color(r, g, b).getRGB(); } int lastZ = 0; int lastCol = 0; // read the voxel data for (int x = 0; x < sx; x++) { for (int y = 0; y < sy; y++) { int start = xyoffset[x][y]; int end = xyoffset[x][y+1]; while (start < end) { // read header bytes int zpos = fileIn.readByteUnsigned(); int zlen = fileIn.readByteUnsigned(); int visfaces = fileIn.readByteUnsigned(); for (int i = 0; i < zlen; i++) { // read color->voxel mapping and add lastCol = colPalette[fileIn.readByteUnsigned()]; addVoxel(x - cx, zpos + i - cz, -y + cy, lastCol); } start += zlen + 3; // fill in voxels "in between" BigInteger bigInteger = BigInteger.valueOf(visfaces); if (!bigInteger.testBit(4)) { for (int i = lastZ + 1; i < zpos; i++) { addVoxel(x - cx, i - cz, -y + cy, lastCol); } } if (!bigInteger.testBit(5)) { lastZ = zpos + zlen - 1; } } } } return true; } }