Exemplo n.º 1
0
GLUSAPI GLUSvoid GLUSAPIENTRY glusQuaternionRotateRzRyRxf(GLUSfloat quaternion[4], const GLUSfloat anglez, const GLUSfloat angley, const GLUSfloat anglex)
{
    GLUSfloat rotZ[4];
    GLUSfloat rotY[4];
    GLUSfloat rotX[4];

    glusQuaternionRotateRzf(rotZ, anglez);
    glusQuaternionRotateRyf(rotY, angley);
    glusQuaternionRotateRxf(rotX, anglex);

    glusQuaternionMultiplyQuaternionf(quaternion, rotZ, rotY);
    glusQuaternionMultiplyQuaternionf(quaternion, quaternion, rotX);
}
Exemplo n.º 2
0
/*
 * @author Pablo Alonso-Villaverde Roza
 * @author Norbert Nopper
 */
GLUSboolean GLUSAPIENTRY glusCreateTorusf(GLUSshape* shape, const GLUSfloat innerRadius, const GLUSfloat outerRadius, const GLUSushort numberSlices, const GLUSushort numberStacks)
{
    // s, t = parametric values of the equations, in the range [0,1]
    GLUSfloat s = 0;
    GLUSfloat t = 0;

    // sIncr, tIncr are increment values aplied to s and t on each loop iteration to generate the torus
    GLUSfloat sIncr;
    GLUSfloat tIncr;

    // to store precomputed sin and cos values
    GLUSfloat cos2PIs, sin2PIs, cos2PIt, sin2PIt;

    GLUSuint numberVertices;
    GLUSuint numberIndices;

    // used later to help us calculating tangents vectors
    GLUSfloat helpVector[3] = { 0.0f, 1.0f, 0.0f };
    GLUSfloat helpQuaternion[4];
    GLUSfloat helpMatrix[16];

    // indices for each type of buffer (of vertices, indices, normals...)
    GLUSuint indexVertices, indexNormals, indexTangents, indexTexCoords;
    GLUSuint indexIndices;

    // loop counters
    GLUSuint sideCount, faceCount;

    // used to generate the indices
    GLUSuint v0, v1, v2, v3;

    GLUSfloat torusRadius = (outerRadius - innerRadius) / 2.0f;
    GLUSfloat centerRadius = outerRadius - torusRadius;

    numberVertices = (numberStacks + 1) * (numberSlices + 1);
    numberIndices = numberStacks * numberSlices * 2 * 3; // 2 triangles per face * 3 indices per triangle

    if (numberSlices < 3 || numberStacks < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES)
    {
        return GLUS_FALSE;
    }

    if (!shape)
    {
        return GLUS_FALSE;
    }
    glusInitShapef(shape);

    shape->numberVertices = numberVertices;
    shape->numberIndices = numberIndices;

    shape->vertices = (GLUSfloat*) malloc(4 * numberVertices * sizeof(GLUSfloat));
    shape->normals = (GLUSfloat*) malloc(3 * numberVertices * sizeof(GLUSfloat));
    shape->tangents = (GLUSfloat*) malloc(3 * numberVertices * sizeof(GLUSfloat));
    shape->texCoords = (GLUSfloat*) malloc(2 * numberVertices * sizeof(GLUSfloat));
    shape->indices = (GLUSushort*) malloc(numberIndices * sizeof(GLUSushort));

    if (!glusCheckShapef(shape))
    {
        glusDestroyShapef(shape);

        return GLUS_FALSE;
    }

    sIncr = 1.0f / (GLUSfloat) numberSlices;
    tIncr = 1.0f / (GLUSfloat) numberStacks;

    // generate vertices and its attributes
    for (sideCount = 0; sideCount <= numberSlices; ++sideCount, s += sIncr)
    {
        // precompute some values
        cos2PIs = (GLUSfloat) cosf(2.0f * GLUS_PI * s);
        sin2PIs = (GLUSfloat) sinf(2.0f * GLUS_PI * s);

        t = 0.0f;
        for (faceCount = 0; faceCount <= numberStacks; ++faceCount, t += tIncr)
        {
            // precompute some values
            cos2PIt = (GLUSfloat) cosf(2.0f * GLUS_PI * t);
            sin2PIt = (GLUSfloat) sinf(2.0f * GLUS_PI * t);

            // generate vertex and stores it in the right position
            indexVertices = ((sideCount * (numberStacks + 1)) + faceCount) * 4;
            shape->vertices[indexVertices + 0] = (centerRadius + torusRadius * cos2PIt) * cos2PIs;
            shape->vertices[indexVertices + 1] = (centerRadius + torusRadius * cos2PIt) * sin2PIs;
            shape->vertices[indexVertices + 2] = torusRadius * sin2PIt;
            shape->vertices[indexVertices + 3] = 1.0f;

            // generate normal and stores it in the right position
            // NOTE: cos (2PIx) = cos (x) and sin (2PIx) = sin (x) so, we can use this formula
            //       normal = {cos(2PIs)cos(2PIt) , sin(2PIs)cos(2PIt) ,sin(2PIt)}
            indexNormals = ((sideCount * (numberStacks + 1)) + faceCount) * 3;
            shape->normals[indexNormals + 0] = cos2PIs * cos2PIt;
            shape->normals[indexNormals + 1] = sin2PIs * cos2PIt;
            shape->normals[indexNormals + 2] = sin2PIt;

            // generate texture coordinates and stores it in the right position
            indexTexCoords = ((sideCount * (numberStacks + 1)) + faceCount) * 2;
            shape->texCoords[indexTexCoords + 0] = s;
            shape->texCoords[indexTexCoords + 1] = t;

            // use quaternion to get the tangent vector
            glusQuaternionRotateRzf(helpQuaternion, 360.0f * s);
            glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion);

            indexTangents = ((sideCount * (numberStacks + 1)) + faceCount) * 3;

            glusMatrix4x4MultiplyVector3f(&shape->tangents[indexTangents], helpMatrix, helpVector);
        }
    }

    // generate indices
    indexIndices = 0;
    for (sideCount = 0; sideCount < numberSlices; ++sideCount)
    {
        for (faceCount = 0; faceCount < numberStacks; ++faceCount)
        {
            // get the number of the vertices for a face of the torus. They must be < numVertices
            v0 = ((sideCount * (numberStacks + 1)) + faceCount);
            v1 = (((sideCount + 1) * (numberStacks + 1)) + faceCount);
            v2 = (((sideCount + 1) * (numberStacks + 1)) + (faceCount + 1));
            v3 = ((sideCount * (numberStacks + 1)) + (faceCount + 1));

            // first triangle of the face, counter clock wise winding
            shape->indices[indexIndices++] = v0;
            shape->indices[indexIndices++] = v1;
            shape->indices[indexIndices++] = v2;

            // second triangle of the face, counter clock wise winding
            shape->indices[indexIndices++] = v0;
            shape->indices[indexIndices++] = v2;
            shape->indices[indexIndices++] = v3;
        }
    }

    if (!glusFinalizeShapef(shape))
    {
        glusDestroyShapef(shape);

        return GLUS_FALSE;
    }

    return GLUS_TRUE;
}