Esempio n. 1
0
bool Any::operator==(const Any& x) const {
    beforeRead();
    x.beforeRead();
    if (m_type != x.m_type) {
        return false;
    }

    switch (m_type) {
    case NONE:
        return true;

    case BOOLEAN:
        return (m_simpleValue.b == x.m_simpleValue.b);

    case NUMBER:
        return (m_simpleValue.n == x.m_simpleValue.n);

    case STRING:
        debugAssert(m_data != NULL);
        return (*(m_data->value.s) == *(x.m_data->value.s));

    case TABLE: {
        if (size() != x.size()) {
            return false;
        }
        debugAssert(m_data != NULL);
        if (m_data->name != x.m_data->name) {
            return false;
        }
        Table<std::string, Any>& cmptable  = *(  m_data->value.t);
        Table<std::string, Any>& xcmptable = *(x.m_data->value.t);
        for (Table<std::string,Any>::Iterator it1 = cmptable.begin(), it2 = xcmptable.begin();
             it1 != cmptable.end() && it2 != xcmptable.end();
             ++it1, ++it2) {
             if (*it1 != *it2) {
                return false;
             }
        }
        return true;
    }

    case ARRAY: {
        if (size() != x.size()) {
            return false;
        }
        debugAssert(m_data != NULL);
        if (m_data->name != x.m_data->name) {
            return false;
        }

        Array<Any>& cmparray  = *(  m_data->value.a);
        Array<Any>& xcmparray = *(x.m_data->value.a);

        for (int ii = 0; ii < size(); ++ii) {
            if (cmparray[ii] != xcmparray[ii]) {
                return false;
            }
        }
        return true;
    }

    default:
        alwaysAssertM(false, "Unknown type.");
        return false;
    }    // switch (m_type)

}
Esempio n. 2
0
void Any::resize(int n) {
    beforeRead();
    alwaysAssertM(n >= 0, "Cannot resize less than 0.");
    verifyType(ARRAY);
    m_data->value.a->resize(n);
}
Esempio n. 3
0
uint32 Crypto::crc32(const void* byte, size_t numBytes) {
    alwaysAssertM(numBytes < 0xFFFFFFFF, "Not implemented for arrays larger than 2^32 bytes");
    return ::crc32(::crc32(0, Z_NULL, 0), static_cast<const Bytef *>(byte), (int)numBytes);
}
Esempio n. 4
0
std::string System::findDataFile
(const std::string&  full,
 bool                errorIfNotFound) {

    // Places where specific files were most recently found.  This is
    // used to cache seeking of common files.
    static Table<std::string, std::string> lastFound;

    // First check if the file exists as requested.  This will go
    // through the FileSystemCache, so most calls do not touch disk.
    if (fileExists(full)) {
        return full;
    }

    // Now check where we previously found this file.
    std::string* last = lastFound.getPointer(full);
    if (last != NULL) {
        if (fileExists(*last)) {
            // Even if cwd has changed the file is still present.
            // We won't notice if it has been deleted, however.
            return *last;
        } else {
            // Remove this from the cache it is invalid
            lastFound.remove(full);
        }
    }

    // Places to look
    static Array<std::string> directoryArray;

    if (directoryArray.size() == 0) {
        // Initialize the directory array
        RealTime t0 = System::time();

        Array<std::string> baseDirArray;

        std::string initialAppDataDir(instance().m_appDataDir);
        
        baseDirArray.append("");
        if (! initialAppDataDir.empty()) {
            baseDirArray.append(initialAppDataDir);
        }

        const char* g3dPath = getenv("G3DDATA");

        if (g3dPath && (initialAppDataDir != g3dPath)) {
            baseDirArray.append(g3dPath);
        }

        static const std::string subdirs[] = 
            {"font", "gui", "SuperShader", "cubemap", "icon", "material", "image", "md2", "md3", "ifs", "3ds", "sky", ""};
        for (int j = 0; j < baseDirArray.size(); ++j) {
            std::string d = baseDirArray[j];
            if (fileExists(d)) {
                directoryArray.append(d);
                for (int i = 0; ! subdirs[i].empty(); ++i) {
                    const std::string& p = pathConcat(d, subdirs[i]);
                    if (fileExists(p)) {
                        directoryArray.append(p);
                    }
                }
            }
        }

        logLazyPrintf("Initializing System::findDataFile took %fs\n", System::time() - t0);
    }

    for (int i = 0; i < directoryArray.size(); ++i) {
        const std::string& p = pathConcat(directoryArray[i], full);
        if (fileExists(p)) {
            lastFound.set(full, p);
            return p;
        }
    }

    if (errorIfNotFound) {
        // Generate an error message
        std::string locations;
        for (int i = 0; i < directoryArray.size(); ++i) {
            locations += pathConcat(directoryArray[i], full) + "\n";
        }
        alwaysAssertM(false, "Could not find '" + full + "' in:\n" + locations);
    }

    // Not found
    return "";
}
Esempio n. 5
0
//===========================================
//TextContent
//===========================================
void ImageContent::init(const TiXmlElement* root)
{
    string name = root->ValueStr();

    if (name == "Image") {
        string left_name = root->Attribute("filename");
        left_name = Story::resolve_rel_path(left_name);


        try {
            left = the_app.tex_mgr.loadTexture(left_name);
            if (left.isNull()) {
                msgBox("Image file \"" + left_name + "\" was not found");
                return;
            }
        } catch (GImage::Error& err) {
            left = NULL;
            msgBox("Image file \"" + left_name + "\" is invalid and could not be loaded");
            return;
        }

        is_stereo = false;

        width = left->texelWidth();
        height = left->texelHeight();

    } else if (name == "StereoImage") {
        string left_name = root->Attribute("left-image");
        left_name = Story::resolve_rel_path(left_name);

        try {
            left = the_app.tex_mgr.loadTexture(left_name);
            if (left.isNull()) {
                msgBox("Image file \"" + left_name + "\" was not found");
                return;
            }
        } catch (GImage::Error& err) {
            left = NULL;
            msgBox("Image file \"" + left_name + "\" is invalid and could not be loaded");
            return;
        }

        width = left->texelWidth();
        height = left->texelHeight();

        string right_name = root->Attribute("right-image");
        right_name = Story::resolve_rel_path(right_name);

        try {
            right = the_app.tex_mgr.loadTexture(right_name);
            if (right.isNull()) {
                msgBox("Image file \"" + right_name + "\" was not found");
                return;
            }
        } catch (GImage::Error& err) {
            right = NULL;
            msgBox("Image file \"" + right_name + "\" is invalid and could not be loaded");
            return;
        }


        is_stereo = true;

        if (right->texelWidth() != width) {
            msgBox("Width of \"" + left_name + "\" does not match width of \"" + right_name + "\".\nThe widths of left and right image must be the same");
            return;
        }

        if (right->texelHeight() != height) {
            msgBox("Height of \"" + left_name + "\" does not match height of \"" + right_name + "\".\nThe heights of left and right image must be the same");
            return;
        }
    } else {
        alwaysAssertM(0, "Invalid Image Element");
    }

    //scale height to image proportions
    height_ratio = height / width;

    //scale *= 2.f;
    float max_scale = 1.f;

    if (height > width) {
        width *= (max_scale / height);
        height = max_scale;
    } else {
        height *= (max_scale / width);
        width = max_scale;
    }

//  float width = scale;
//  float height = height_ratio * scale;

    float min_x = -width * .5;
    float max_x = width * .5;
    float min_y = -height * .5;
    float max_y = height * .5;

    local_bbox.set(Vector3(min_x, min_y, 0), Vector3(max_x, max_y, 0.02));
    update_bbox();

    verts.append(Vector3(min_x, max_y, 0));
    verts.append(Vector3(min_x, min_y, 0));
    verts.append(Vector3(max_x, min_y, 0));
    verts.append(Vector3(max_x, max_y, 0));

    coords.append(Vector2(0, 0));
    coords.append(Vector2(0, 1));
    coords.append(Vector2(1, 1));
    coords.append(Vector2(1, 0));

    valid = true;
}
Esempio n. 6
0
void ArticulatedModel::initOBJ(const std::string& filename, const Preprocess& preprocess) {
    Stopwatch loadTimer;

    TextInput::Settings set;
    set.cppBlockComments = false;
    set.cppLineComments = false;
    set.otherCommentCharacter = '#';
    set.generateNewlineTokens = true;

    // Notes on OBJ file format.  See also:
    //
    // -  http://www.martinreddy.net/gfx/3d/OBJ.spec
    // -  http://en.wikipedia.org/wiki/Obj
    // -  http://www.royriggs.com/obj.html
    //
    // OBJ indexing is 1-based.
    // Line breaks are significant.
    // The first token on a line indicates the contents of the line.
    //
    // Faces contain separate indices for normals and texcoords.
    // We load the raw vertices and then form our own optimized
    // gl indices from them.
    //
    // Negative indices are relative to the last coordinate seen.

    // Raw arrays with independent indexing, as imported from the file
    Array<Vector3> rawVertex;
    Array<Vector3> rawNormal;
    Array<Vector2> rawTexCoord;

    // part.geometry.vertexArray[i] = rawVertex[cookVertex[i]];
    Array<int>      cookVertex;
    Array<int>      cookNormal;
    Array<int>      cookTexCoord;

    // Put everything into a single part
    // Convert to a Part
    Part& part = partArray.next();

    part.cframe = CoordinateFrame();
    part.name = "root";
    part.parent = -1;

    // v,t,n repeated for each vertex
    Array<int>     faceTempIndex;

    // Count of errors from mismatched texcoord and vertex
    int texCoordChanged = 0;
    int normalChanged = 0;

    Table<std::string, Material::Ref> materialLibrary;
    Table<std::string, TriListSpec*> groupTable;

    TriListSpec* currentTriList = NULL;
    int numTris = 0;

    const Matrix3 normalXform = preprocess.xform.upper3x3().transpose().inverse();

    const std::string& basePath = FilePath::parent(FileSystem::resolve(filename));

    {
        TextInput ti(filename, set);
        while (ti.hasMore()) {
            // Consume comments/newlines
            while (ti.hasMore() && (ti.peek().type() == Token::NEWLINE)) {
                // Consume the newline
                ti.read();
            }

            if (! ti.hasMore()) {
                break;
            }

            // Process one line
            const std::string& cmd = ti.readSymbol();

            if (cmd == "mtllib") {

                // Specify material library
                const std::string& mtlFilename = ti.readUntilNewlineAsString();
                loadMTL(FilePath::concat(basePath, mtlFilename), materialLibrary, preprocess);

            } else if (cmd == "g") {

                // New trilist
                const std::string& name = ti.readUntilNewlineAsString();
                if (! groupTable.containsKey(name)) {
                    currentTriList = new TriListSpec();
                    currentTriList->name = name;
                    groupTable.set(name, currentTriList);
                } else {
                    currentTriList = groupTable[name];
                }


            } else if (cmd == "usemtl") {
                if (currentTriList) {
                    currentTriList->materialName = ti.readUntilNewlineAsString();
                }
            } else if (cmd == "v") {
                rawVertex.append(readVertex(ti, preprocess.xform));
            } else if (cmd == "vt") {
                // Texcoord
                Vector2& t = rawTexCoord.next();
                t.x = ti.readNumber();
                t.y = 1.0f - ti.readNumber();
            } else if (cmd == "vn") {
                // Normal
                rawNormal.append(readNormal(ti, normalXform));
            } else if ((cmd == "f") && currentTriList) {
                // Face

                // Read each vertex
                while (ti.hasMore() && (ti.peek().type() != Token::NEWLINE)) {

                    // Read one 3-part index
                    int v = ti.readNumber();
                    if (v < 0) {
                        v = rawVertex.size() + 1 + v;
                    }

                    int n = 0;
                    int t = 0;

                    if (ti.peek().type() == Token::SYMBOL) {
                        ti.readSymbol("/");
                        if (ti.peek().type() == Token::NUMBER) {
                            t = ti.readNumber();
                            if (t < 0) {
                                t = rawTexCoord.size() + 1 + t;
                            }
                        }
                        if (ti.peek().type() == Token::SYMBOL) {
                            ti.readSymbol("/");
                            if (ti.peek().type() == Token::NUMBER) {
                                n = ti.readNumber();
                                if (n < 0) {
                                    n = rawNormal.size() + 1 + n;
                                }
                            }
                        }
                    }

                    // Switch to zero-based indexing
                    --v;
                    --n;
                    --t;

                    faceTempIndex.append(v, t, n);
                }

                alwaysAssertM(faceTempIndex.size() >= 3*3, "Face with fewer than three vertices in model.");
                numTris += (faceTempIndex.size()/3) - 2;
                // The faceTempIndex is now a triangle fan.  Convert it to a triangle list and use unique vertices
                for (int i = 2; i < faceTempIndex.size()/3; ++i) {
                    // Always start with vertex 0
                    cookVertex.append(faceTempIndex[0]);
                    cookTexCoord.append(faceTempIndex[1]);
                    cookNormal.append(faceTempIndex[2]);

                    // The vertex just before the one we're adding
                    int j = (i - 1) * 3;
                    cookVertex.append(faceTempIndex[j]);
                    cookTexCoord.append(faceTempIndex[j+1]);
                    cookNormal.append(faceTempIndex[j+2]);

                    // The vertex we're adding
                    j = i * 3;
                    cookVertex.append(faceTempIndex[j]);
                    cookTexCoord.append(faceTempIndex[j+1]);
                    cookNormal.append(faceTempIndex[j+2]);

                    // Update the index array to contain the three vertices we just added
                    currentTriList->cpuIndex.append(cookVertex.size() - 3, cookVertex.size() - 2, cookVertex.size() - 1);
                }

                faceTempIndex.fastClear();

            }

            // Read until the end of the line
            while (ti.hasMore() && (ti.read().type() != Token::NEWLINE));
        }
    }

    debugPrintf("Creating TriLists\n");

    // Copy geometry
    const int N = cookVertex.size();
    part.geometry.vertexArray.resize(N);
    for (int i = 0; i < N; ++i) {
        part.geometry.vertexArray[i] = rawVertex[cookVertex[i]];
    }

    // Optional normals
    if (rawNormal.size() > 0) {
        part.geometry.normalArray.resize(N);
        for (int i = 0; i < N; ++i) {
            part.geometry.normalArray[i] = rawNormal[cookNormal[i]];
        }
    }

    // Optional texcoords
    if (rawTexCoord.size() > 0) {
        part.texCoordArray.resize(N);
        for (int i = 0; i < N; ++i) {
            part.texCoordArray[i] = rawTexCoord[cookTexCoord[i]];
        }
    }

    // Create trilists
    for (Table<std::string, TriListSpec*>::Iterator it = groupTable.begin(); it.hasMore(); ++it) {
        TriListSpec* s = it->value;

        Material::Ref material;
        if (materialLibrary.containsKey(s->materialName)) {
            material = materialLibrary[s->materialName];
        } else {
            material = Material::createDiffuse(Color3::white() * 0.8f);
            debugPrintf("Warning: unrecognized material: %s\n", s->materialName.c_str());
        }

        Part::TriList::Ref triList = part.newTriList(material);
        triList->twoSided = false;
        triList->indexArray = s->cpuIndex;
    }
    groupTable.deleteValues();
    groupTable.clear();

    debugPrintf("Done loading.  %d vertices, %d faces, %d frames\n\n", cookVertex.size(), numTris, N);
    loadTimer.after("Loading");
}