Esempio n. 1
0
GLLMtlFile::GLLMtlFile(CFURLRef location)
{
	std::string filename = GLLStringFromFileURL(location);
	
	std::ifstream stream(filename.c_str());
	if (!stream) throw std::runtime_error("Could not open MTLLib file.");
	
	bool hasFirstMaterial = false;
	std::string materialName;
	Material *currentMaterial = new Material();
	
	while(stream.good())
	{
		std::string line;
		std::getline(stream, line);
		
		std::istringstream linestream(line);
		std::string token;
		linestream >> token;
		
		if (token == "newmtl")
		{
			if (!hasFirstMaterial)
			{
				// This is the first material. Just save the name.
				linestream >> materialName;
				hasFirstMaterial = true;
				currentMaterial->name = materialName;
			}
			else
			{
				// Old material ends here. Store it here; map copies it, so it can be overwritten now.
				currentMaterial->ambient[3] = currentMaterial->diffuse[3] = currentMaterial->specular[3] = 1.0f;
				materials[materialName] = currentMaterial;
				
				// Reset material
				currentMaterial = new Material();
				
				// Save new name
				linestream >> materialName;
				currentMaterial->name = materialName;
			}
		}
Esempio n. 2
0
GLLObjFile::GLLObjFile(CFURLRef location)
{
    std::string filename = GLLStringFromFileURL(location);
    
    int fdes = ::open(filename.c_str(), O_RDONLY);
    if (fdes < 0) {
        throw std::runtime_error("Could not open file");
    }
    
    struct stat statistics;
    if (fstat(fdes, &statistics) < 0) {
        close(fdes);
        throw std::runtime_error("Could not get file size");
    }
    
    const char *buffer = (const char *) mmap(nullptr, statistics.st_size, PROT_READ, MAP_PRIVATE, fdes, 0);
    close(fdes);
    const char *current = buffer;
    const char *end = &buffer[statistics.st_size];
    
    materialLibraryURLs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    std::string activeMaterial("");
    unsigned activeMaterialStart = 0;
    bool hasFirstMaterial = false;
    while(current != end)
    {
        while (current != end && (*current == ' ' || *current == '\n' || *current == '\r')) {
            current++;
        }
        if (current == end)
            break;
        
        switch (*current) {
            case 'f':
                parseFace(current, end);
                break;
            case 'v':
                current += 1;
                switch (*current) {
                    case 'n': // Normals
                        current += 1;
                        parseVector(current, end, normals, 3);
                        break;
                    case 't': // Tex coords
                        current += 1;
                        parseVector(current, end, texCoords, 2);
                        break;
                    case 'c': // Colors
                        current += 1;
                        parseVector(current, end, colors, 4);
                        break;
                    case ' ': // Vertex
                        parseVector(current, end, vertices, 3);
                        break;
                    default:
                        skipToEndOfLine(current, end);
                        break;
                }
                break;
            case 'm':
                if (followsString(current, end, "mtllib")) {
                    std::string mtllib = stringToEndOfLine(current, end);
                    
                    try
                    {
                        CFURLRef mtllibLocation = GLLCreateURLFromString(mtllib, location);
                        CFArrayAppendValue(materialLibraryURLs, mtllibLocation);
                        CFRelease(mtllibLocation);
                    }
                    catch (std::exception &e)
                    {
                        std::cerr << "Ignoring mtllib: " << e.what() << std::endl;
                    }
                } else {
                    skipToEndOfLine(current, end);
                }
                break;
            case 'u':
                if (followsString(current, end, "usemtl")) {
                    if (hasFirstMaterial)
                    {
                        // End previous material run
                        materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial));
                    }
                    else
                        hasFirstMaterial = true;
                    
                    current += 1;
                    activeMaterial = stringToEndOfLine(current, end);
                    activeMaterialStart = (unsigned) originalIndices.size();
                } else {
                    skipToEndOfLine(current, end);
                }
                break;
            case '#': // Comment
            default:
                skipToEndOfLine(current, end);
                break;
        }
    }
    munmap((void *) buffer, statistics.st_size);
    
    // Wrap up final material group
    materialRanges.push_back(MaterialRange(activeMaterialStart, (unsigned) originalIndices.size(), activeMaterial));
    
    fillIndices();
}