/* OpenMW - The completely unofficial reimplementation of Morrowind Copyright (C) 2008 Nicolay Korslund Email: < korslund@gmail.com > WWW: http://openmw.snaptoad.com/ This file (data.d) is part of the OpenMW package. OpenMW is distributed as free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License version 3 along with this program. If not, see http://www.gnu.org/licenses/ . */ module nif.data; import nif.record; class NiSourceTexture : Named { byte external; union { char[] filename; NiPixelData data; } /* Pixel layout 0 - Palettised 1 - High color 16 2 - True color 32 3 - Compressed 4 - Bumpmap 5 - Default */ int pixel; /* Mipmap format 0 - no 1 - yes 2 - default */ int mipmap; /* Alpha 0 - none 1 - binary 2 - smooth 3 - default (use material alpha, or multiply material with texture if present) */ int alpha; override: void sortOut(Record[] list) { super.sortOut(list); if(!external) data = lookup!(NiPixelData)(list); } void read() { super.read(); external = nifFile.getByteIs(0,1); debug(verbose) writefln("Use external file: ", external); if(external) { filename = nifFile.getString; debug(verbose) writefln("Filename: ", filename); } else { nifFile.wgetByteIs(1); debug(verbose) writef("Pixel Data "); getIndex(); } pixel = nifFile.getInt; mipmap = nifFile.getInt; alpha = nifFile.getIntIs(3); debug(verbose) { writefln("Pixel layout: ", pixel); writefln("Mipmap: ", mipmap); writefln("Alpha: ", alpha); } nifFile.wgetByteIs(1); } } // Common ancestor for several classes class ShapeData : Record { float[] vertices, normals, colors, uvlist; Vector center; float radius; override: void read() { super.read(); short verts = nifFile.getShort; debug(verbose) writefln("Vertices: ", verts); if(nifFile.getInt != 0) { debug(verbose) writefln("Reading vertices"); if(verts == 0) nifFile.warn("Empty vertex array"); vertices = nifFile.getArraySize!(float)(verts*3); } else nifFile.warn("No vertices found"); if(nifFile.getInt != 0) { debug(verbose) writefln("Reading normals"); normals = nifFile.getArraySize!(float)(verts*3); } center = nifFile.getVector(); radius = nifFile.getFloat(); debug(verbose) { writefln("Center: ", center.toString); writefln("Radius: ", radius); } if(nifFile.getInt != 0) { debug(verbose) writefln("Reading vertex colors"); colors = nifFile.getArraySize!(float)(verts*4); } short uvs = nifFile.getShort; debug(verbose) writefln("Number of UV sets: ", uvs); if(nifFile.getInt != 0) { if(uvs == 0) nifFile.warn("Empty UV list"); // Only the 6 first bits are used as a count, the rest are // (unknown) flags. if(uvs > 0b111111) { nifFile.warn("UV count contains (unknown) flags"); uvs = cast(short)(uvs & 0b111111); } uvlist = nifFile.getArraySize!(float)(uvs*verts*2); } else if(uvs != 0) nifFile.warn("UV list was unexpectedly missing"); } } class NiAutoNormalParticlesData : ShapeData { ushort activeCount; override: void read() { super.read(); nifFile.assertWarn(uvlist.length == 0, "UV coordinates are not expected in this record"); debug(verbose) writef("Active vertices: "); // Number of active vertices (always matches count?) activeCount = nifFile.wgetUshortIs(cast(ushort)(vertices.length/3)); nifFile.wgetFloat(); // Active radius (?) nifFile.wgetShort(); // Number of valid entries in the following arrays //writefln("%x", nifFile.position); if(nifFile.wgetInt == 0) nifFile.warn("Particle size list is missing"); else for(int i; i>3); debug(verbose) { writefln("Red mask %8xh", rmask); writefln("Green mask %8xh", gmask); writefln("Blue mask %8xh", bmask); writefln("Alpha mask %8xh", amask); writefln("Bits per pixel: ", bpp); writefln("Number of mipmaps: ", mips); writefln("Bytes per pixel: ", bytes); } for(int i; i=verts || sh < 0) nifFile.warn("Presumed vertex index was out of bounds"); s = nifFile.getArraySize!(short)(sh); } } } } class NiMorphData : Record { //float[] vertexList; override: void read() { super.read(); int morphCount = nifFile.getInt; int vertCount = nifFile.getInt; debug(verbose) { writefln("Number of morphs: ", morphCount); writefln("Vertices: ", vertCount); } nifFile.wgetByteIs(1); //nifFile.getIntIs(0); //nifFile.getIntIs(1); //vertexList = nifFile.getArraySize!(float)(3*vertCount); for(int i=0; i