コード例 #1
0
bool EdgeHash::operator==(const EdgeHash& rhs)
{
    // return true for any edge that has vertices in equivilant positions
    return ( fuzzyEq( vertices + indices[0], rhs.vertices + rhs.indices[0] ) &&
             fuzzyEq( vertices + indices[1], rhs.vertices + rhs.indices[1] ) ) ||
           ( fuzzyEq( vertices + indices[0], rhs.vertices + rhs.indices[1] ) &&
             fuzzyEq( vertices + indices[1], rhs.vertices + rhs.indices[0] ) );
}
コード例 #2
0
ファイル: LineSegment.cpp プロジェクト: Cryptoh/server
Vector2 LineSegment2D::closestPoint(const Vector2& Q) const {
    // Two constants that appear in the result
    const Vector2 k1(m_origin - Q);
    const Vector2& k2 = m_direction;
    
    if (fuzzyEq(m_length, 0)) {
        // This line segment has no length
        return m_origin;
    }

    // Time [0, 1] at which we hit the closest point travelling from p0 to p1.
    // Derivation can be obtained by minimizing the expression
    //     ||P0 + (P1 - P0)t - Q||.
    const float t = -k1.dot(k2) / (m_length * m_length);

    if (t < 0) {
        // Clipped to low end point
        return m_origin;
    } else if (t > 1) {
        // Clipped to high end point
        return m_origin + m_direction;
    } else {
        // Subsitute into the line equation to find 
        // the point on the segment.
        return m_origin + k2 * t;
    }
}
コード例 #3
0
ファイル: MeshAlg.cpp プロジェクト: Demigodess/Darkcore
void MeshAlg::identifyBackfaces(
    const Array<Vector3>&           vertexArray,
    const Array<MeshAlg::Face>&     faceArray,
    const Vector4&                  HP,
    Array<bool>&                    backface,
    const Array<Vector3>&           faceNormals) {

    Vector3 P = HP.xyz();

    backface.resize(faceArray.size());

    if (fuzzyEq(HP.w, 0.0)) {
        // Infinite case
        for (int f = faceArray.size() - 1; f >= 0; --f) {
            const Vector3& N = faceNormals[f];
            backface[f] = N.dot(P) < 0;
        }
    } else {
        // Finite case
        for (int f = faceArray.size() - 1; f >= 0; --f) {
            const MeshAlg::Face& face = faceArray[f];
            const Vector3& v0 = vertexArray[face.vertexIndex[0]];
            const Vector3& N = faceNormals[f];

            backface[f] = N.dot(P - v0) < 0;
        }
    }
}
コード例 #4
0
ファイル: tAny.cpp プロジェクト: elfprince13/G3D10
static void testCast() {
    {
        Any a(3);
        int x = int(a.number());
        testAssert(x == 3);
    }
    {
        Any a(3);
        int x = a;
        testAssert(x == 3);
    }
    {
        Any a(3.1);
        double x = a;
        testAssert(x == 3.1);
    }
    {
        Any a(3.1f);
        float x = a;
        testAssert(fuzzyEq(x, 3.1f));
    }
    {
        Any a(true);
        bool x = a;
        testAssert(x == true);
    }
    {
        Any a("hello");
        String x = a;
        testAssert(x == "hello");
    }
}
コード例 #5
0
Welder::Welder(    
    const Array<Vector3>& _oldVertexArray,
    Array<Vector3>&       _newVertexArray,
    Array<int>&           _toNew,
    Array<int>&           _toOld,
    double                _radius) :
    oldVertexArray(_oldVertexArray),
    newVertexArray(_newVertexArray),
    toNew(_toNew),
    toOld(_toOld),
    radius(_radius) {

    // Compute a scale factor that moves the range
    // of all ordinates to [0, 1]
    Vector3 minBound = Vector3::inf();
    Vector3 maxBound = -minBound;

    for (int i = 0; i < oldVertexArray.size(); ++i) {
        minBound = minBound.min(oldVertexArray[i]);
        maxBound = maxBound.max(oldVertexArray[i]);
    }

    offset = minBound;
    scale  = maxBound - minBound;
    for (int i = 0; i < 3; ++i) {
        // The model might have zero extent along some axis
        if (fuzzyEq(scale[i], 0.0)) {
            scale[i] = 1.0;
        } else {
            scale[i] = 1.0 / scale[i];
        }
    }
}
コード例 #6
0
ファイル: tMatrix3.cpp プロジェクト: luaman/g3d-cpp
static void testEuler() {
    float x = 1;
    float y = 2;
    float z = -3;

    float x2, y2, z2;

    Matrix3 rX = Matrix3::fromAxisAngle(Vector3::unitX(), x);
    Matrix3 rY = Matrix3::fromAxisAngle(Vector3::unitY(), y);
    Matrix3 rZ = Matrix3::fromAxisAngle(Vector3::unitZ(), z);
    Matrix3 rot = rZ * rX * rY;
    rot.toEulerAnglesZXY(x2, y2, z2);
    debugAssert(fuzzyEq(x, x2));
    debugAssert(fuzzyEq(y, y2));
    debugAssert(fuzzyEq(z, z2));
}
コード例 #7
0
Edge* Geometry::getEdges(void)
{
    if( !_numVertices ) return NULL;
    if( _edges.size() ) return &_edges[0];    

    Table<EdgeHash,int> edgeTable;
    for( int i=0; i<_numTriangles; i++ ) 
    {
        // make sure this is not a degenerate triangle
        // (ie the vertices are so close the triangle is extremely small)
        assert( !fuzzyEq( _vertices + _triangles[i].vertexId[0],  _vertices + _triangles[i].vertexId[1] ) );
        assert( !fuzzyEq( _vertices + _triangles[i].vertexId[1],  _vertices + _triangles[i].vertexId[2] ) );
        assert( !fuzzyEq( _vertices + _triangles[i].vertexId[0],  _vertices + _triangles[i].vertexId[2] ) );

        // add three edges for each face
        addEdge( edgeTable, _edges, _triangles[i].vertexId[0], _triangles[i].vertexId[1], i );
        addEdge( edgeTable, _edges, _triangles[i].vertexId[1], _triangles[i].vertexId[2], i );
        addEdge( edgeTable, _edges, _triangles[i].vertexId[0], _triangles[i].vertexId[2], i );
    }

    return &_edges[0]; 
}
コード例 #8
0
void Geometry::addEdge(Table<EdgeHash,int>& edgeTable, std::vector<Edge>& edgeVector, int v0, int v1, int face)
{    
    EdgeHash edgeKey( v0, v1, _vertices );

    if( edgeTable.containsKey(edgeKey) ) 
    {
        // if this is the second face referencing this edge
        int edgeIndex = edgeTable[edgeKey];
        Edge& existingEdge = edgeVector[edgeIndex];

        // make sure the vertices are wound correctly
        // (ie in opposite directions for the two different faces)
        assert( fuzzyEq( _vertices + existingEdge.vertexId[0], _vertices + v1 ) );
        assert( fuzzyEq( _vertices + existingEdge.vertexId[1], _vertices + v0 ) );

        // make sure this is only the second face to reference this edge
        assert( existingEdge.triangleId[0] >= 0 );
        assert( existingEdge.triangleId[0] != face );
        assert( existingEdge.triangleId[1] == -1 );

        // set second face
        existingEdge.triangleId[1] = face;
    } 
    else 
    {
        // if this is the first face referencing this edge
        Edge newEdge;
        newEdge.vertexId[0] = v0;
        newEdge.vertexId[1] = v1;
        newEdge.triangleId[0] = face;
        newEdge.triangleId[1] = -1;
        // add edge to lookup table and array
        edgeTable.set( edgeKey, edgeVector.size() );
        edgeVector.push_back(newEdge);
    }
}
コード例 #9
0
ファイル: tGChunk.cpp プロジェクト: luaman/g3d-cpp
void testGChunk() {
    printf("GChunk ");

    enum {HEADER, NAME, BODY, NUM, DATA};
    {
        BinaryOutput b("file.dat", G3D_LITTLE_ENDIAN);

        {
            GChunk c(b, HEADER);

            {
                GChunk c(b, NAME, STRING_BINFMT);
                b.writeString("abcdefg");
                c.finish(b);
            }
            c.finish(b);
        }

        {
            GChunk c(b, BODY);

            {
                GChunk c(b, NUM, INT32_BINFMT);
                b.writeInt32(10);
                c.finish(b);
            }

            {
                GChunk c(b, DATA, FLOAT32_BINFMT);
                for (int i = 0; i < 10; ++i) {
                    b.writeFloat32(sqrt((double)i));
                }
                c.finish(b);
            }
            c.finish(b);
        }

        b.commit();
    }

    {

        BinaryInput b("file.dat", G3D_LITTLE_ENDIAN);

        {
            GChunk c(b, HEADER);

            {
                GChunk c(b, NAME, STRING_BINFMT);
                debugAssert(c.count == -1);
                alwaysAssertM(b.readString() == "abcdefg", "");
                c.finish(b);
            }
            c.finish(b);
        }

        {
            GChunk c(b, BODY);

            {
                GChunk c(b, NUM, INT32_BINFMT);
                debugAssert(c.count == 1);
                alwaysAssertM(b.readInt32() == 10, "");
                c.finish(b);
            }

            {
                GChunk c(b, DATA, FLOAT32_BINFMT);
                debugAssert(c.count == 10);
                for (int i = 0; i < 10; ++i) {
                    alwaysAssertM(fuzzyEq(b.readFloat32(), sqrt((double)i)),
                        "Data in chunk corrupted");
                }
                c.finish(b);
            }
            c.finish(b);
        }
    }

    printf("passed\n");
}
コード例 #10
0
ファイル: tMatrix.cpp プロジェクト: luaman/g3d-cpp
void testMatrix() {
    printf("Matrix ");
    // Zeros
    {
        Matrix M(3, 4);
        debugAssert(M.rows() == 3);
        debugAssert(M.cols() == 4);
        debugAssert(M.get(0, 0) == 0);
        debugAssert(M.get(1, 1) == 0);
    }

    // Identity
    {
        Matrix M = Matrix::identity(4);
        debugAssert(M.rows() == 4);
        debugAssert(M.cols() == 4);
        debugAssert(M.get(0, 0) == 1);
        debugAssert(M.get(0, 1) == 0);
    }

    // Add
    {
        Matrix A = Matrix::random(2, 3);
        Matrix B = Matrix::random(2, 3);
        Matrix C = A + B;
    
        for (int r = 0; r < 2; ++r) {
            for (int c = 0; c < 3; ++c) {
                debugAssert(fuzzyEq(C.get(r, c), A.get(r, c) + B.get(r, c)));
            }
        }
    }

    // Matrix multiply
    {
        Matrix A(2, 2);
        Matrix B(2, 2);

        A.set(0, 0, 1); A.set(0, 1, 3);
        A.set(1, 0, 4); A.set(1, 1, 2);

        B.set(0, 0, -6); B.set(0, 1, 9);
        B.set(1, 0, 1); B.set(1, 1, 7);

        Matrix C = A * B;

        debugAssert(fuzzyEq(C.get(0, 0), -3));
        debugAssert(fuzzyEq(C.get(0, 1), 30));
        debugAssert(fuzzyEq(C.get(1, 0), -22));
        debugAssert(fuzzyEq(C.get(1, 1), 50));
    }

    // Transpose
    {
        Matrix A(2, 2);

        A.set(0, 0, 1); A.set(0, 1, 3);
        A.set(1, 0, 4); A.set(1, 1, 2);

        Matrix C = A.transpose();

        debugAssert(fuzzyEq(C.get(0, 0), 1));
        debugAssert(fuzzyEq(C.get(0, 1), 4));
        debugAssert(fuzzyEq(C.get(1, 0), 3));
        debugAssert(fuzzyEq(C.get(1, 1), 2));

        A = Matrix::random(3, 4);
        A = A.transpose();

        debugAssert(A.rows() == 4);        
        debugAssert(A.cols() == 3);
    }

    // Copy-on-mutate
    {

        Matrix::debugNumCopyOps = Matrix::debugNumAllocOps = 0;

        Matrix A = Matrix::identity(2);

        debugAssert(Matrix::debugNumAllocOps == 1);
        debugAssert(Matrix::debugNumCopyOps == 0);

        Matrix B = A;
        debugAssert(Matrix::debugNumAllocOps == 1);
        debugAssert(Matrix::debugNumCopyOps == 0);

        B.set(0,0,4);
        debugAssert(B.get(0,0) == 4);
        debugAssert(A.get(0,0) == 1);
        debugAssert(Matrix::debugNumAllocOps == 2);
        debugAssert(Matrix::debugNumCopyOps == 1);
    }

    // Inverse
    {
        Matrix A(2, 2);

        A.set(0, 0, 1); A.set(0, 1, 3);
        A.set(1, 0, 4); A.set(1, 1, 2);

        Matrix C = A.inverse();

        debugAssert(fuzzyEq(C.get(0, 0), -0.2));
        debugAssert(fuzzyEq(C.get(0, 1), 0.3));
        debugAssert(fuzzyEq(C.get(1, 0), 0.4));
        debugAssert(fuzzyEq(C.get(1, 1), -0.1));
    }

    {
        Matrix A = Matrix::random(10, 10);
        Matrix B = A.inverse();

        B = B * A;

        for (int r = 0; r < B.rows(); ++r) {
            for (int c = 0; c < B.cols(); ++c) {

                float v = B.get(r, c);
                // The precision isn't great on our inverse, so be tolerant
                if (r == c) {
                    debugAssert(abs(v - 1) < 1e-4);
                } else {
                    debugAssert(abs(v) < 1e-4);
                }
                (void)v;
            }
        }
    }

    // Negate
    {
        Matrix A = Matrix::random(2, 2);
        Matrix B = -A;

        for (int r = 0; r < A.rows(); ++r) {
            for (int c = 0; c < A.cols(); ++c) {
                debugAssert(B.get(r, c) == -A.get(r, c));
            }
        }
    }

    // Transpose
    {
        Matrix A = Matrix::random(3,2);
        Matrix B = A.transpose();
        debugAssert(B.rows() == A.cols());
        debugAssert(B.cols() == A.rows());

        for (int r = 0; r < A.rows(); ++r) {
            for (int c = 0; c < A.cols(); ++c) {
                debugAssert(B.get(c, r) == A.get(r, c));
            }
        }
    }

    // SVD
    {
        Matrix A = Matrix(3, 3);
        A.set(0, 0,  1.0);  A.set(0, 1,  2.0);  A.set(0, 2,  1.0);
        A.set(1, 0, -3.0);  A.set(1, 1,  7.0);  A.set(1, 2, -6.0);
        A.set(2, 0,  4.0);  A.set(2, 1, -4.0);  A.set(2, 2, 10.0);
        A = Matrix::random(27, 15);

        Array<float> D;
        Matrix U, V;

        A.svd(U, D, V);

        // Verify that we can reconstruct
        Matrix B = U * Matrix::fromDiagonal(D) * V.transpose();

        Matrix test = abs(A - B) < 0.1f;

//        A.debugPrint("A");
//        U.debugPrint("U");
//        D.debugPrint("D");
//        V.debugPrint("V");
//        (U * D * V.transpose()).debugPrint("UDV'");

        debugAssert(test.allNonZero());

        float m = (A - B).norm() / A.norm();
        debugAssert(m < 0.01f);
        (void)m;
    }

    /*
    Matrix a(3, 5);
    a.set(0,0, 1);  a.set(0,1, 2); a.set(0,2,  3); a.set(0,3, 4);  a.set(0,4,  5);
    a.set(1,0, 3);  a.set(1,1, 5); a.set(1,2,  3); a.set(1,3, 1);  a.set(1,4,  2);
    a.set(2,0, 1);  a.set(2,1, 1); a.set(2,2,  1); a.set(2,3, 1);  a.set(2,4,  1);

    Matrix b = a;
    b.set(0,0, 1.8124); b.set(0,1,    0.5341); b.set(0,2,    2.8930); b.set(0,3,    5.2519); b.set(0,4,    4.8829);
    b.set(1,0, 2.5930); b.set(1,1,   2.6022); b.set(1,2,    4.2760); b.set(1,3,    5.9497); b.set(1,4,    6.3751);

    a.debugPrint("a");
    a.debugPrint("b");

    Matrix H = b * a.pseudoInverse();
    H.debugPrint("H");
    */


    printf("passed\n");
}