Ejemplo n.º 1
0
vector<KeyFrame>
ModelLoaderMD2::loadKeyFrames(const FileName &fileName,
                              const FileName &skinName,
                              TextureFactory &textureFactory) const {
	FILE *stream=0;
	
//	fopen_s(&stream, fileName.c_str(), "rb");
	stream = fopen(fileName.c_str(), "rb");
	
	VERIFY(stream && !ferror(stream), "MD2 failed to open: "+fileName.str());
	
	Header header = readHeader(stream);
	Skin *skins = readSkins(stream, header);
	TexCoord *texCoords = readTexCoords(stream, header);
	Triangle *triangles = readTriangles(stream, header);
	Frame *frames = readFrames(stream, header);
	
	fclose(stream);
	
	Material skin;
	
	if (header.numOfSkins>0) {
		skin.setTexture(textureFactory.load(FileName((const char*)skins[0].name)));
	} else {
		skin.setTexture(textureFactory.load(skinName));
	}
	
	vector<KeyFrame> keyFrames = buildKeyFrames(fileName,
	                             skin,
	                             header,
	                             texCoords,
	                             triangles,
	                             frames);
	                             
	delete [] skins;
	delete [] texCoords;
	delete [] triangles;
	delete [] frames;
	
	return keyFrames;
}
Ejemplo n.º 2
0
static void readTrimesh(const uint8_t* ptr, a3dsObjectDataT* obj) {
    chunkT* chunk = (chunkT*)ptr;
    ptr = chunk->data;

    assert(chunk->id == 0x4100);

    assert(obj->mesh == NULL);
    obj->mesh = calloc(1, sizeof(a3dsMeshDataT));
    obj->mesh->num_verts = (-1);

    void* chunk_end = (uint8_t*)chunk + chunk->length;
    while (ptr < chunk_end) {
        chunk = (chunkT*)ptr;

             if (chunk->id == 0x4110) readVertCoords(ptr, obj->mesh);
        else if (chunk->id == 0x4120) readTriIndices(ptr, obj->mesh);
        else if (chunk->id == 0x4140) readTexCoords (ptr, obj->mesh);

        ptr = (uint8_t*)chunk + chunk->length;
    }
}
Ejemplo n.º 3
0
CModelFile* CModelReader::read()
{
    atUint32 magic = base::readUint32();

    if (magic != 0xDEADBABE)
    {
        Athena::io::MemoryWriter tmp;
        decompressFile(tmp, base::data(), base::length());

        if (tmp.length() > 0x10)
            base::setData(tmp.data(), tmp.length());

        magic = base::readUint32();
    }

    if (magic != 0xDEADBABE /*&& magic != 0x9381000A*/)
        THROW_INVALID_DATA_EXCEPTION("Not a valid CMDL magic, expected 0xDEADBABE got 0x%.8X\n", magic);
    atUint32 version;
    if (magic != 0x9381000A)
        version = base::readUint32();
    else
        version = CModelFile::DKCR;

    if (!(version >= CModelFile::MetroidPrime1 && version <= CModelFile::DKCR))
        THROW_INVALID_DATA_EXCEPTION("Only Metroid Prime 1 to 3 models are supported got v%i\n", version);

    try
    {
        m_result = new CModelFile;
        m_result->m_version = (CModelFile::Version)version;
        m_result->m_flags = base::readUint32();
        m_result->m_boundingBox.min.x = base::readFloat();
        m_result->m_boundingBox.min.y = base::readFloat();
        m_result->m_boundingBox.min.z = base::readFloat();
        m_result->m_boundingBox.max.x = base::readFloat();
        m_result->m_boundingBox.max.y = base::readFloat();
        m_result->m_boundingBox.max.z = base::readFloat();

        atUint32 sectionCount = base::readUint32();
        atInt32 materialCount = base::readInt32();

        m_sectionSizes.resize(sectionCount);

        if (m_result->m_flags & 0x10)
        {
            base::readUint32();
            atUint32 visGroupCount = base::readUint32();
            while((visGroupCount--) > 0)
            {
                atUint32 len = base::readUint32();
                base::readString(len);
            }

            base::readUint32();
            base::readUint32();
            base::readUint32();
            base::readUint32();
            base::readUint32();
        }

        m_result->m_materialSets.resize(materialCount);
        for (atUint32 i = 0; i < sectionCount; i++)
            m_sectionSizes[i] = base::readUint32();

        base::seekAlign32();

        const atUint32 sectionBias = ((m_result->m_version == CModelFile::DKCR || m_result->m_version == CModelFile::MetroidPrime3)
                                      ? 1 : materialCount);

        Athena::io::MemoryReader sectionReader(new atUint8[2], 2);
        sectionReader.setEndian(endian());
        for (atUint32 i = 0; i < sectionCount; i++)
        {
            if (m_sectionSizes[i] == 0)
                continue;

            if (materialCount > 0)
            {
                if (m_result->m_version != CModelFile::DKCR && m_result->m_version != CModelFile::MetroidPrime3)
                {
                    atUint8* data = base::readUBytes(m_sectionSizes[i]);
                    CMaterialReader reader(data, m_sectionSizes[i]);
                    CMaterialSet materialSet;
                    switch(m_result->m_version)
                    {
                        case CModelFile::MetroidPrime1:
                            materialSet = reader.read(CMaterial::MetroidPrime1);
                            break;
                        case CModelFile::MetroidPrime2:
                            materialSet = reader.read(CMaterial::MetroidPrime2);
                            break;
                        default:
                            break;
                    }

                    m_result->m_materialSets[i] = materialSet;
                    materialCount--;
                    continue;
                }
                else
                {
                    atUint8* data = base::readUBytes(m_sectionSizes[i]);
                    CMaterialReader reader(data, m_sectionSizes[i]);
                    atUint32 setIdx = 0;
                    while ((materialCount--) > 0)
                    {
                        CMaterialSet& materialSet = m_result->m_materialSets[setIdx];
                        switch(m_result->m_version)
                        {
                            case CModelFile::MetroidPrime3:
                                materialSet = reader.read(CMaterial::MetroidPrime3);
                                break;
                            case CModelFile::DKCR:
                                materialSet = reader.read(CMaterial::DKCR);
                            default:
                                break;
                        }
                        setIdx++;
                    }
                    continue;
                }
            }
            else
            {
                SectionType section = (SectionType)(i - sectionBias);
                atUint8* data = base::readUBytes(m_sectionSizes[i]);
                sectionReader.setData(data, m_sectionSizes[i]);
                switch(section)
                {
                    case SectionType::Vertices:
                    {
                        if (m_result->m_flags & 0x20)
                            readVertices(sectionReader, true);
                        else
                            readVertices(sectionReader);
                    }
                        break;
                    case SectionType::Normals:
                        readNormals(sectionReader);
                        break;
                    case SectionType::Colors:
                        readColors(sectionReader);
                        break;
                    case SectionType::TexCoord0:
                        readTexCoords(0, sectionReader);
                        break;
                    case SectionType::TexCoord1orMeshOffsets:
                    {
                        if (m_result->m_flags & EFormatFlags::TexCoord1 || m_result->m_version == CModelFile::DKCR)
                            readTexCoords(1, sectionReader);
                        else
                            readMeshOffsets(sectionReader);
                        break;
                    }
                    case SectionType::MeshInfo:
                    {
                        if (m_meshOffsets.size() == 0)
                        {
                            readMeshOffsets(sectionReader);
                            break;
                        }
                    }
                    default:
                        if ((i - sectionBias) >= 5)
                            readMesh(sectionReader);
                        break;
                }
            }
        }
    }
    catch(...)
    {
        delete m_result;
        m_result = nullptr;
        throw;
    }

    return m_result;
}