Ejemplo n.º 1
0
bool CalculatePolygonNormalFlat(float* position, float* buffer, int bufferLength, int elementSize, int polygonVertices)
{
    for (int i = 0; i < bufferLength; i += (elementSize * polygonVertices))
    {
        float v1[3], v2[3], n[3], sum[] = {0.0f, 0.0f, 0.0f};

        for (int j = 0; j < polygonVertices - 2; ++j)
        {
            float *p1 = &position[i],
                   *p2 = &position[i + (j + 2) * elementSize],
                    *p3 = &position[i + (j + 1) * elementSize];

            MINUS3(p2, p1, v1);
            MINUS3(p3, p1, v2);
            CROSS3(v1, v2, n);
            normalize3(n);

            PLUS3(n, sum, sum);
        }
        for (int j = 0; j < polygonVertices; ++j)
        {
            COPY3(&buffer[i + j * elementSize], sum);
        }
    }
    return true;
}
Ejemplo n.º 2
0
bool CalculateGridNormalFlat(float* position, float* buffer, int bufferLength, int elementSize)
{
    if (elementSize < 3)
    {
        return false;
    }
    for (int i = 0; i < bufferLength; i += 4 * elementSize)
    {
        float *p1 = &position[i],
               *p2 = &position[i + elementSize],
                *p3 = &position[i + 2 * elementSize],
                 *p4 = &position[i + 3 * elementSize];

        float v1[3], v2[3], n1[3], n2[3], n1pn2[3];
        //v1 = p2-p1
        MINUS3(p2, p1, v1);
        MINUS3(p4, p1, v2);

        //n1 = v1 x v2
        CROSS3(v1, v2, n1);

        MINUS3(p4, p1, v1);
        MINUS3(p3, p1, v2);

        CROSS3(v1, v2, n2);

        normalize3(n1);
        normalize3(n2);
        PLUS3(n1, n2, n1pn2);

        normalize3(n1pn2);


        COPY3(&buffer[i], n1pn2);
        COPY3(&buffer[i + elementSize], n1pn2);
        COPY3(&buffer[i + 2 * elementSize], n1pn2);
        COPY3(&buffer[i + 3 * elementSize], n1pn2);
    }
    return true;
}
Ejemplo n.º 3
0
void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
                              GLfloat u, GLfloat v )
{
    GLuint attr;

    for (attr = 1; attr <= VBO_ATTRIB_TEX7; attr++) {
        struct gl_2d_map *map = exec->eval.map2[attr].map;
        if (map) {
            GLfloat uu = (u - map->u1) * map->du;
            GLfloat vv = (v - map->v1) * map->dv;
            GLfloat data[4];

            ASSIGN_4V(data, 0, 0, 0, 1);

            _math_horner_bezier_surf(map->Points,
                                     data,
                                     uu, vv,
                                     exec->eval.map2[attr].sz,
                                     map->Uorder, map->Vorder);

            COPY_SZ_4V( exec->vtx.attrptr[attr],
                        exec->vtx.attrsz[attr],
                        data );
        }
    }

    /** Vertex -- EvalCoord2f is a noop if this map not enabled:
     **/
    if (exec->eval.map2[0].map) {
        struct gl_2d_map *map = exec->eval.map2[0].map;
        GLfloat uu = (u - map->u1) * map->du;
        GLfloat vv = (v - map->v1) * map->dv;
        GLfloat vertex[4];

        ASSIGN_4V(vertex, 0, 0, 0, 1);

        if (exec->ctx->Eval.AutoNormal) {
            GLfloat normal[4];
            GLfloat du[4], dv[4];

            _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
                                    exec->eval.map2[0].sz,
                                    map->Uorder, map->Vorder);

            if (exec->eval.map2[0].sz == 4) {
                du[0] = du[0]*vertex[3] - du[3]*vertex[0];
                du[1] = du[1]*vertex[3] - du[3]*vertex[1];
                du[2] = du[2]*vertex[3] - du[3]*vertex[2];

                dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0];
                dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1];
                dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2];
            }


            CROSS3(normal, du, dv);
            NORMALIZE_3FV(normal);
            normal[3] = 1.0;

            COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
                        exec->vtx.attrsz[VBO_ATTRIB_NORMAL],
                        normal );

        }
        else {
            _math_horner_bezier_surf(map->Points, vertex, uu, vv,
                                     exec->eval.map2[0].sz,
                                     map->Uorder, map->Vorder);
        }

        if (exec->vtx.attrsz[0] == 4)
            CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
        else
            CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
    }
}
Ejemplo n.º 4
0
bool CalculateGridNormalSmooth(float* position, float* buffer, int bufferLength, int elementSize, int numX, int numY)
{
    if (elementSize < 3)
    {
        return false;
    }
    for (int i = 0; i < bufferLength; i += 4 * elementSize)
    {
        float *p1 = &position[i],
               *p2 = &position[i + elementSize],
                *p3 = &position[i + 2 * elementSize],
                 *p4 = &position[i + 3 * elementSize];

        float v1[3], v2[3], n1[3], n2[3], n1pn2[3];
        //v1 = p2-p1
        MINUS3(p2, p1, v1);
        MINUS3(p4, p1, v2);

        //n1 = v1 x v2
        CROSS3(v1, v2, n1);

        MINUS3(p4, p1, v1);
        MINUS3(p3, p1, v2);

        CROSS3(v1, v2, n2);

        normalize3(n1);
        normalize3(n2);
        PLUS3(n1, n2, n1pn2);

        normalize3(n1pn2);


        COPY3(&buffer[i], n1pn2);
        COPY3(&buffer[i + elementSize], n1);
        COPY3(&buffer[i + 2 * elementSize], n2);
        COPY3(&buffer[i + 3 * elementSize], n1pn2);
    }

    // average normals in x axis
    for (int i = 0; i < numX - 1; ++i)
    {
        for (int j = 0; j < numY - 2; ++j)
        {
            float sum[3];
            float *p2, *p3, *pj0, *pj1;
            p2 = getGridNormal(buffer, numX, numY, elementSize, i, j, 2);
            p3 = getGridNormal(buffer, numX, numY, elementSize, i, j, 3);

            pj0 = getGridNormal(buffer, numX, numY, elementSize, i, j + 1, 0);
            pj1 = getGridNormal(buffer, numX, numY, elementSize, i, j + 1, 1);

            PLUS3(pj0, p2, sum);
            COPY3(p2, sum);
            COPY3(pj0, sum);

            PLUS3(pj1, p3, sum);
            COPY3(p3, sum);
            COPY3(pj1, sum);
        }
    }

    // average normals in y axis
    for (int j = 0; j < numY - 1; ++j)
    {
        for (int i = 0; i < numX - 2; ++i)
        {
            float sum[3];
            float *p1, *p3, *pi0, *pi2;
            p1 = getGridNormal(buffer, numX, numY, elementSize, i, j, 1);
            p3 = getGridNormal(buffer, numX, numY, elementSize, i, j, 3);

            pi0 = getGridNormal(buffer, numX, numY, elementSize, i + 1, j, 0);
            pi2 = getGridNormal(buffer, numX, numY, elementSize, i + 1, j, 2);

            PLUS3(pi0, p1, sum);
            COPY3(p1, sum);
            COPY3(pi0, sum);

            PLUS3(pi2, p3, sum);
            COPY3(p3, sum);
            COPY3(pi2, sum);
        }
    }
    return true;
}
Ejemplo n.º 5
0
/**
 * Determine type and flags from scratch.  
 *
 * \param mat matrix.
 * 
 * This is expensive enough to only want to do it once.
 */
static void analyse_from_scratch( GLmatrix *mat )
{
   const GLfloat *m = mat->m;
   GLuint mask = 0;
   GLuint i;

   for (i = 0 ; i < 16 ; i++) {
      if (m[i] == 0.0) mask |= (1<<i);
   }

   if (m[0] == 1.0F) mask |= (1<<16);
   if (m[5] == 1.0F) mask |= (1<<21);
   if (m[10] == 1.0F) mask |= (1<<26);
   if (m[15] == 1.0F) mask |= (1<<31);

   mat->flags &= ~MAT_FLAGS_GEOMETRY;

   /* Check for translation - no-one really cares
    */
   if ((mask & MASK_NO_TRX) != MASK_NO_TRX)
      mat->flags |= MAT_FLAG_TRANSLATION;

   /* Do the real work
    */
   if (mask == (GLuint) MASK_IDENTITY) {
      mat->type = MATRIX_IDENTITY;
   }
   else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) {
      mat->type = MATRIX_2D_NO_ROT;

      if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
	 mat->flags |= MAT_FLAG_GENERAL_SCALE;
   }
   else if ((mask & MASK_2D) == (GLuint) MASK_2D) {
      GLfloat mm = DOT2(m, m);
      GLfloat m4m4 = DOT2(m+4,m+4);
      GLfloat mm4 = DOT2(m,m+4);

      mat->type = MATRIX_2D;

      /* Check for scale */
      if (SQ(mm-1) > SQ(1e-6) ||
	  SQ(m4m4-1) > SQ(1e-6))
	 mat->flags |= MAT_FLAG_GENERAL_SCALE;

      /* Check for rotation */
      if (SQ(mm4) > SQ(1e-6))
	 mat->flags |= MAT_FLAG_GENERAL_3D;
      else
	 mat->flags |= MAT_FLAG_ROTATION;

   }
   else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) {
      mat->type = MATRIX_3D_NO_ROT;

      /* Check for scale */
      if (SQ(m[0]-m[5]) < SQ(1e-6) &&
	  SQ(m[0]-m[10]) < SQ(1e-6)) {
	 if (SQ(m[0]-1.0) > SQ(1e-6)) {
	    mat->flags |= MAT_FLAG_UNIFORM_SCALE;
         }
      }
      else {
	 mat->flags |= MAT_FLAG_GENERAL_SCALE;
      }
   }
   else if ((mask & MASK_3D) == (GLuint) MASK_3D) {
      GLfloat c1 = DOT3(m,m);
      GLfloat c2 = DOT3(m+4,m+4);
      GLfloat c3 = DOT3(m+8,m+8);
      GLfloat d1 = DOT3(m, m+4);
      GLfloat cp[3];

      mat->type = MATRIX_3D;

      /* Check for scale */
      if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) {
	 if (SQ(c1-1.0) > SQ(1e-6))
	    mat->flags |= MAT_FLAG_UNIFORM_SCALE;
	 /* else no scale at all */
      }
      else {
	 mat->flags |= MAT_FLAG_GENERAL_SCALE;
      }

      /* Check for rotation */
      if (SQ(d1) < SQ(1e-6)) {
	 CROSS3( cp, m, m+4 );
	 SUB_3V( cp, cp, (m+8) );
	 if (LEN_SQUARED_3FV(cp) < SQ(1e-6))
	    mat->flags |= MAT_FLAG_ROTATION;
	 else
	    mat->flags |= MAT_FLAG_GENERAL_3D;
      }
      else {
	 mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
      }
   }
   else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {
      mat->type = MATRIX_PERSPECTIVE;
      mat->flags |= MAT_FLAG_GENERAL;
   }
   else {
      mat->type = MATRIX_GENERAL;
      mat->flags |= MAT_FLAG_GENERAL;
   }
}