Пример #1
0
long KRTextureKTX::getMemRequiredForSize(int max_dim)
{
    int target_dim = max_dim;
    if(target_dim < m_min_lod_max_dim) target_dim = target_dim;
    
    // Determine how much memory will be consumed
    
	int width = m_header.pixelWidth;
	int height = m_header.pixelHeight;
    long memoryRequired = 0;
    
    for(std::list<KRDataBlock *>::iterator itr = m_blocks.begin(); itr != m_blocks.end(); itr++) {
        KRDataBlock *block = *itr;
        if(width <= target_dim && height <= target_dim) {
            memoryRequired += block->getSize();
        }
		
        width = width >> 1;
        if(width < 1) {
            width = 1;
        }
        height = height >> 1;
        if(height < 1) {
            height = 1;
        }
	}
    
    return memoryRequired;
}
Пример #2
0
bool KRResource::save(const std::string& path)
{
    KRDataBlock data;
    if(save(data)) {
        return data.save(path);
    } else {
        return false;
    }
}
Пример #3
0
bool KRBundle::save(KRDataBlock &data) {
    if(m_pData->getSize() > KRENGINE_KRBUNDLE_HEADER_SIZE * 2) {
        // Only output krbundles that contain files
        data.append(*m_pData);
    }
    return true;
}
Пример #4
0
bool KRAnimation::save(KRDataBlock &data) {
    tinyxml2::XMLDocument doc;
    tinyxml2::XMLElement *animation_node =  doc.NewElement( "animation" );
    doc.InsertEndChild(animation_node);
    animation_node->SetAttribute("loop", m_loop ? "true" : "false");
    animation_node->SetAttribute("auto_play", m_auto_play ? "true" : "false");
    animation_node->SetAttribute("duration", m_duration);
    animation_node->SetAttribute("start_time", m_start_time);
    
    for(unordered_map<std::string, KRAnimationLayer *>::iterator itr = m_layers.begin(); itr != m_layers.end(); ++itr){
        (*itr).second->saveXML(animation_node);
    }
    
    tinyxml2::XMLPrinter p;
    doc.Print(&p);
    data.append((void *)p.CStr(), strlen(p.CStr())+1);
    
    return true;
}
Пример #5
0
std::vector<KRResource *> KRResource::LoadObj(KRContext &context, const std::string& path)
{
    std::vector<KRResource *> resources;
    
    KRMesh *new_mesh = new KRMesh(context, KRResource::GetFileBase(path));
    resources.push_back(new_mesh);
    
    KRMesh::mesh_info mi;
    
    std::vector<std::string> material_names_t;
    
    KRDataBlock data;
    
    char szSymbol[500][256];
    
    int *pFaces = NULL;
    
    vector<KRMesh::pack_material *> m_materials;
    
    if(data.load(path)) {
        //  -----=====----- Get counts -----=====----- 
        
        int cVertexData = 0;
        
        
        int cFaces = 1;
        int cMaterialFaceStart = 1;
        
        char *pScan = (char *)data.getStart();
        char *pEnd = (char *)data.getEnd();
        while(pScan < pEnd) {
            
            // Scan through whitespace
            while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) {
                pScan++;
            }
            
            if(*pScan == '#') {
                // Line is a comment line
                
                // Scan to the end of the line
                while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') {
                    pScan++;
                }
            } else {
                int cSymbols = 0;
                while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') {
                    
                    char *pDest = szSymbol[cSymbols++];
                    while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') {
                        *pDest++ = *pScan++;
                    }
                    *pDest = '\0';
                    
                    // Scan through whitespace, but don't advance to next line
                    while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) {
                        pScan++;
                    }
                }
                
                if(strcmp(szSymbol[0], "v") == 0) {
                    // Vertex (v)
                } else if(strcmp(szSymbol[0], "vt") == 0) {
                    // Vertex Texture UV Coordinate (vt)
                } else if(strcmp(szSymbol[0], "vn") == 0) {
                    // Vertex Normal (vn)
                } else if(strcmp(szSymbol[0], "f") == 0) {
                    // Face (f)
                    int cFaceVertexes = (cSymbols - 3) * 3; // 3 vertexes per triangle.  Triangles have 4 symbols.  Quads have 5 symbols and generate two triangles.
                    cVertexData += cFaceVertexes; 
                    cFaces += cFaceVertexes * 3 + 1; // Allocate space for count of vertices, Vertex Index, Texture Coordinate Index, and Normal Index
                    
                } else if(strcmp(szSymbol[0], "usemtl") == 0) {
                    // Use Material (usemtl)
                    if(cMaterialFaceStart - cFaces > 0) {
                        cFaces++;
                        
                    }
                    material_names_t.push_back(std::string(szSymbol[1]));
                }
                
            }
        }
        
        
        //  -----=====-----  Populate vertexes and faces -----=====----- 
        
        int *pFaces = (int *)malloc(sizeof(int *) * (cFaces + 1));
        assert(pFaces != NULL);
        
        std::vector<KRVector3> indexed_vertices;
        std::vector<KRVector2> indexed_uva;
        std::vector<KRVector3> indexed_normals;
        
        int *pFace = pFaces;
        int *pMaterialFaces = pFace++;
        *pMaterialFaces = 0;
        
        
        
        
        // --------
        
        pScan = (char *)data.getStart();
        while(pScan < pEnd) {
            
            // Scan through whitespace
            while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t' || *pScan == '\r' || *pScan == '\n')) {
                pScan++;
            }
            
            if(*pScan == '#') {
                // Line is a comment line
                
                // Scan to the end of the line
                while(pScan < pEnd && *pScan != '\r' && *pScan != '\n') {
                    pScan++;
                }
            } else {
                int cSymbols = 0;
                while(pScan < pEnd && *pScan != '\n' && *pScan != '\r') {
                    
                    char *pDest = szSymbol[cSymbols++];
                    while(pScan < pEnd && *pScan != ' ' && *pScan != '\n' && *pScan != '\r') {
                        *pDest++ = *pScan++;
                    }
                    *pDest = '\0';
                    
                    // Scan through whitespace, but don't advance to next line
                    while(pScan < pEnd && (*pScan == ' ' || *pScan == '\t')) {
                        pScan++;
                    }
                }
                
                if(strcmp(szSymbol[0], "v") == 0) {
                    // Vertex (v)
                    float x, y, z;
                    char *pChar = szSymbol[1];
                    x = strtof(pChar, &pChar);
                    pChar = szSymbol[2];
                    y = strtof(pChar, &pChar);
                    pChar = szSymbol[3];
                    z = strtof(pChar, &pChar);
                    indexed_vertices.push_back(KRVector3(x,y,z));
                } else if(strcmp(szSymbol[0], "vt") == 0) {
                    // Vertex Texture UV Coordinate (vt)
                    char *pChar = szSymbol[1];
                    float u,v;
                    
                    u = strtof(pChar, &pChar);
                    pChar = szSymbol[2];
                    v = strtof(pChar, &pChar);                            
                    indexed_uva.push_back(KRVector2(u,v));
                } else if(strcmp(szSymbol[0], "vn") == 0) {
                    // Vertex Normal (vn)
                    float x,y,z;
                    char *pChar = szSymbol[1];
                    x = strtof(pChar, &pChar);
                    pChar = szSymbol[2];
                    y = strtof(pChar, &pChar);
                    pChar = szSymbol[3];
                    z = strtof(pChar, &pChar);
                    indexed_normals.push_back(KRVector3(x,y,z));
                } else if(strcmp(szSymbol[0], "f") == 0) {
                    // Face (f)
                    int cFaceVertices = cSymbols - 1;
                    
                    *pFace++ = cFaceVertices;
                    for(int iSymbol=1; iSymbol < cSymbols; iSymbol++) {
                        char *pChar = szSymbol[iSymbol];
                        if(*pChar == '.' || (*pChar >= '0' && *pChar <= '9')) {
                            *pFace++ = strtol(pChar, &pChar, 10) - 1; // Vertex Index
                            
                            if(*pChar == '/') {
                                pChar++;
                                if(*pChar == '/') {
                                    *pFace++ = -1;
                                } else {
                                    *pFace++ = strtol(pChar, &pChar, 10) - 1; // Texture Coordinate Index
                                }
                            } else {
                                *pFace++ = -1;
                            }
                            
                            if(*pChar == '/') {
                                pChar++;
                                if(*pChar == '/') {
                                    *pFace++ = -1;
                                } else {
                                    *pFace++ = strtol(pChar, &pChar, 10) - 1; // Normal Index
                                }
                            } else {
                                *pFace++ = -1;
                            }
                            while(*pChar == '/') {
                                pChar++;
                                strtol(pChar, &pChar, 10);
                            }
                        }
                    }
                    
                    
                } else if(strcmp(szSymbol[0], "usemtl") == 0) {
                    // Use Material (usemtl)
                    if(pFace - pMaterialFaces > 1) {
                        *pMaterialFaces = pFace - pMaterialFaces - 1;
                        pMaterialFaces = pFace++;
                    }
                }
            }
        }
        
        
        *pMaterialFaces = pFace - pMaterialFaces - 1;
        *pFace++ = 0;
        
        
        int iVertex = 0;
        
        
        std::vector<std::string>::iterator material_itr = material_names_t.begin();
        KRMesh::pack_material *pMaterial = new KRMesh::pack_material();
        pMaterial->start_vertex = iVertex;
        pMaterial->vertex_count = 0;
        memset(pMaterial->szName, 256, 0);
        if(material_itr < material_names_t.end()) {
            strncpy(pMaterial->szName, (*material_itr++).c_str(), 256);
        }
        m_materials.push_back(pMaterial);
        
        
        pFace = pFaces;
        while(*pFace != 0 && iVertex < cVertexData) {
            pMaterial->start_vertex = iVertex;
            
            int *pMaterialEndFace = pFace + *pFace++;
            while(pFace < pMaterialEndFace  && iVertex < cVertexData) {
                int cFaceVertexes = *pFace;
                KRVector3 firstFaceVertex;
                KRVector3 prevFaceVertex;
                KRVector3 firstFaceNormal;
                KRVector3 prevFaceNormal;
                KRVector2 firstFaceUva;
                KRVector2 prevFaceUva;
                for(int iFaceVertex=0; iFaceVertex < cFaceVertexes; iFaceVertex++) {
                    if(iFaceVertex > 2) {
                        // There have already been 3 vertices.  Now we need to split the quad into a second triangle composed of the 1st, 3rd, and 4th vertices
                        iVertex+=2;
                        
                        mi.vertices.push_back(firstFaceVertex);
                        mi.uva.push_back(firstFaceUva);
                        mi.normals.push_back(firstFaceNormal);
                        
                        mi.vertices.push_back(prevFaceVertex);
                        mi.uva.push_back(prevFaceUva);
                        mi.normals.push_back(prevFaceNormal);
                    }
                    KRVector3 vertex = indexed_vertices[pFace[iFaceVertex*3+1]];
                    KRVector2 new_uva;
                    if(pFace[iFaceVertex*3+2] >= 0) {
                        new_uva = indexed_uva[pFace[iFaceVertex*3+2]];
                    }
                    KRVector3 normal;
                    if(pFace[iFaceVertex*3+3] >= 0){
                        KRVector3 normal = indexed_normals[pFace[iFaceVertex*3+3]];
                    }
                    
                    mi.vertices.push_back(vertex);
                    mi.uva.push_back(new_uva);
                    mi.normals.push_back(normal);
                    
                    if(iFaceVertex==0) {
                        firstFaceVertex = vertex;
                        firstFaceUva = new_uva;
                        firstFaceNormal = normal;
                    }
                    prevFaceVertex = vertex;
                    prevFaceUva = new_uva;
                    prevFaceNormal = normal;
                    
                    iVertex++;
                }
                pFace += cFaceVertexes * 3 + 1;
            }
            pMaterial->vertex_count = iVertex - pMaterial->start_vertex;
            if(*pFace != 0) {
                pMaterial = new KRMesh::pack_material();
                pMaterial->start_vertex = iVertex;
                pMaterial->vertex_count = 0;
                memset(pMaterial->szName, 256, 0);
                
                if(material_itr < material_names_t.end()) {
                    strncpy(pMaterial->szName, (*material_itr++).c_str(), 256);
                }
                m_materials.push_back(pMaterial);
            }
        }
        
        for(int iMaterial=0; iMaterial < m_materials.size(); iMaterial++) {
            KRMesh::pack_material *pNewMaterial = m_materials[iMaterial];
            if(pNewMaterial->vertex_count > 0) {
                mi.material_names.push_back(std::string(pNewMaterial->szName));
                mi.submesh_starts.push_back(pNewMaterial->start_vertex);
                mi.submesh_lengths.push_back(pNewMaterial->vertex_count);
            }
            delete pNewMaterial;
        }
        
        // TODO: Bones not yet supported for OBJ
//        std::vector<std::string> bone_names;
//        std::vector<KRMat4> bone_bind_poses;
//        std::vector<std::vector<int> > bone_indexes;
//        std::vector<std::vector<float> > bone_weights;
//        
//        std::vector<__uint16_t> vertex_indexes;
//        std::vector<std::pair<int, int> > vertex_index_bases;
        
        mi.format = KRMesh::KRENGINE_MODEL_FORMAT_TRIANGLES;
        new_mesh->LoadData(mi, true, false);
    }
    
    if(pFaces) {
        free(pFaces);
    }
    
    return resources;
}
Пример #6
0
bool KRMaterial::save(KRDataBlock &data) {
    std::stringstream stream;
    stream.precision(std::numeric_limits<long double>::digits10);
    stream.setf(std::ios::fixed,std::ios::floatfield);
    
    stream << "newmtl " << m_name;
    stream << "\nka " << m_ambientColor.x << " " << m_ambientColor.y << " " << m_ambientColor.z;
    stream << "\nkd " << m_diffuseColor.x << " " << m_diffuseColor.y << " " << m_diffuseColor.z;
    stream << "\nks " << m_specularColor.x << " " << m_specularColor.y << " " << m_specularColor.z;
    stream << "\nkr " << m_reflectionColor.x << " " << m_reflectionColor.y << " " << m_reflectionColor.z;
    stream << "\nTr " << m_tr;
    stream << "\nNs " << m_ns;
    if(m_ambientMap.size()) {
        stream << "\nmap_Ka " << m_ambientMap << ".pvr -s " << m_ambientMapScale.x << " " << m_ambientMapScale.y << " -o " << m_ambientMapOffset.x << " " << m_ambientMapOffset.y;
    } else {
        stream << "\n# map_Ka filename.pvr -s 1.0 1.0 -o 0.0 0.0";
    }
    if(m_diffuseMap.size()) {
        stream << "\nmap_Kd " << m_diffuseMap << ".pvr -s " << m_diffuseMapScale.x << " " << m_diffuseMapScale.y << " -o " << m_diffuseMapOffset.x << " " << m_diffuseMapOffset.y;
    } else {
        stream << "\n# map_Kd filename.pvr -s 1.0 1.0 -o 0.0 0.0";
    }
    if(m_specularMap.size()) {
        stream << "\nmap_Ks " << m_specularMap << ".pvr -s " << m_specularMapScale.x << " " << m_specularMapScale.y << " -o " << m_specularMapOffset.x << " " << m_specularMapOffset.y << "\n";
    } else {
        stream << "\n# map_Ks filename.pvr -s 1.0 1.0 -o 0.0 0.0";
    }
    if(m_normalMap.size()) {
        stream << "\nmap_Normal " << m_normalMap << ".pvr -s " << m_normalMapScale.x << " " << m_normalMapScale.y << " -o " << m_normalMapOffset.x << " " << m_normalMapOffset.y;
    } else {
        stream << "\n# map_Normal filename.pvr -s 1.0 1.0 -o 0.0 0.0";
    }
    if(m_reflectionMap.size()) {
        stream << "\nmap_Reflection " << m_reflectionMap << ".pvr -s " << m_reflectionMapScale.x << " " << m_reflectionMapScale.y << " -o " << m_reflectionMapOffset.x << " " << m_reflectionMapOffset.y;
    } else {
        stream << "\n# map_Reflection filename.pvr -s 1.0 1.0 -o 0.0 0.0";
    }
    if(m_reflectionCube.size()) {
        stream << "\nmap_ReflectionCube " << m_reflectionCube << ".pvr";
    } else {
        stream << "\n# map_ReflectionCube cubemapname";
    }
    switch(m_alpha_mode) {
        case KRMATERIAL_ALPHA_MODE_OPAQUE:
            stream << "\nalpha_mode opaque";
            break;
        case KRMATERIAL_ALPHA_MODE_TEST:
            stream << "\nalpha_mode test";
            break;
        case KRMATERIAL_ALPHA_MODE_BLENDONESIDE:
            stream << "\nalpha_mode blendoneside";
            break;
        case KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE:
            stream << "\nalpha_mode blendtwoside";
            break;
    }
    stream << "\n# alpha_mode opaque, test, blendoneside, or blendtwoside";
    
    stream << "\n";
    data.append(stream.str());

    return true;
}