예제 #1
0
/*!
 * Compute a vector normal to two line segments.
 *
 * Computes the normal vector to the lines b-a and b-c.
 *
 * \param n Returned normal vector.
 * \param a Endpoint of first line.
 * \param b Base point of both lines.
 * \param c Endpoint of second line.
 */
void
lib3ds_vector_normal(float n[3], float a[3], float b[3], float c[3]) {
    float p[3], q[3];

    lib3ds_vector_sub(p, c, b);
    lib3ds_vector_sub(q, a, b);
    lib3ds_vector_cross(n, p, q);
    lib3ds_vector_normalize(n);
}
예제 #2
0
파일: vector.c 프로젝트: 01iv3r/OpenPilot
/*!
 * Compute a vector normal to two line segments.
 *
 * Computes the normal vector to the lines b-a and b-c.
 *
 * \param n Returned normal vector.
 * \param a Endpoint of first line.
 * \param b Base point of both lines.
 * \param c Endpoint of second line.
 *
 * \ingroup vector
 */
void
lib3ds_vector_normal(Lib3dsVector n, Lib3dsVector a, Lib3dsVector b, Lib3dsVector c)
{
  Lib3dsVector p,q;

  lib3ds_vector_sub(p,c,b);
  lib3ds_vector_sub(q,a,b);
  lib3ds_vector_cross(n,p,q);
  lib3ds_vector_normalize(n);
}
예제 #3
0
파일: matrix.cpp 프로젝트: joevandyk/osg
/*!
 * \ingroup matrix
 */
void
lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos,
  Lib3dsVector tgt, Lib3dsFloat roll)
{
  Lib3dsMatrix M,R;
  Lib3dsVector x, y, z;

  lib3ds_vector_sub(y, tgt, pos);
  lib3ds_vector_normalize(y);
  
  z[0] = 0;
  z[1] = 0;
  z[2] = 1.0;
  
  lib3ds_vector_cross(x, y, z);
  lib3ds_vector_cross(z, x, y);
  lib3ds_vector_normalize(x);
  lib3ds_vector_normalize(y);

  lib3ds_matrix_identity(M);
  M[0][0] = x[0];
  M[1][0] = x[1];
  M[2][0] = x[2];
  M[0][1] = y[0];
  M[1][1] = y[1];
  M[2][1] = y[2];
  M[0][2] = z[0];
  M[1][2] = z[1];
  M[2][2] = z[2];

  lib3ds_matrix_identity(R);
  lib3ds_matrix_rotate_y(R, roll);
  lib3ds_matrix_mul(matrix, R,M);
  lib3ds_matrix_translate_xyz(matrix, -pos[0],-pos[1],-pos[2]);
}
예제 #4
0
파일: tracks.c 프로젝트: refnum/quesa
/*!
 * \ingroup tracks 
 */
void
lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c,
  Lib3dsLin3Key *cn, Lib3dsLin3Key *n)
{
  Lib3dsVector np,nn;
  Lib3dsFloat ksm,ksp,kdm,kdp;
  int i;
  
  ASSERT(c);
  if (!cp) {
    cp=c;
  }
  if (!cn) {
    cn=c;
  }
  if (!p && !n) {
    lib3ds_vector_zero(c->ds);
    lib3ds_vector_zero(c->dd);
    return;
  }

  if (n && p) {
    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
    lib3ds_vector_sub(np, c->value, p->value); 
    lib3ds_vector_sub(nn, n->value, c->value); 

    for(i=0; i<3; ++i) {
      c->ds[i]=ksm*np[i] + ksp*nn[i];
      c->dd[i]=kdm*np[i] + kdp*nn[i];
    }
  }
  else {
    if (p) {
      lib3ds_vector_sub(np, c->value, p->value);
      lib3ds_vector_copy(c->ds, np);
      lib3ds_vector_copy(c->dd, np);
    }
    if (n) {
      lib3ds_vector_sub(nn, n->value, c->value); 
      lib3ds_vector_copy(c->ds, nn);
      lib3ds_vector_copy(c->dd, nn);
    }
  }
}
예제 #5
0
파일: matrix.c 프로젝트: Aharobot/mrpt
/*!
 * Compute a camera matrix based on position, target and roll.
 *
 * Generates a translate/rotate matrix that maps world coordinates
 * to camera coordinates.  Resulting matrix does not include perspective
 * transform.
 *
 * \param matrix Destination matrix.
 * \param pos Camera position
 * \param tgt Camera target
 * \param roll Roll angle
 *
 * \ingroup matrix
 */
void
lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos,
  Lib3dsVector tgt, Lib3dsFloat roll)
{
  Lib3dsMatrix M;
  Lib3dsVector x, y, z;

  lib3ds_vector_sub(y, tgt, pos);
  lib3ds_vector_normalize(y);

  if (y[0] != 0. || y[1] != 0) {
    z[0] = 0;
    z[1] = 0;
    z[2] = 1.0;
  }
  else {	/* Special case:  looking straight up or down z axis */
    z[0] = -1.0;
    z[1] = 0;
    z[2] = 0;
  }

  lib3ds_vector_cross(x, y, z);
  lib3ds_vector_cross(z, x, y);
  lib3ds_vector_normalize(x);
  lib3ds_vector_normalize(z);

  lib3ds_matrix_identity(M);
  M[0][0] = x[0];
  M[1][0] = x[1];
  M[2][0] = x[2];
  M[0][1] = y[0];
  M[1][1] = y[1];
  M[2][1] = y[2];
  M[0][2] = z[0];
  M[1][2] = z[1];
  M[2][2] = z[2];

  lib3ds_matrix_identity(matrix);
  lib3ds_matrix_rotate_y(matrix, roll);
  lib3ds_matrix_mult(matrix, M);
  lib3ds_matrix_translate_xyz(matrix, -pos[0],-pos[1],-pos[2]);
}
예제 #6
0
/*!
 * Compute a camera matrix based on position, target and roll.
 *
 * Generates a translate/rotate matrix that maps world coordinates
 * to camera coordinates.  Resulting matrix does not include perspective
 * transform.
 *
 * \param matrix Destination matrix.
 * \param pos Camera position
 * \param tgt Camera target
 * \param roll Roll angle
 */
void
lib3ds_matrix_camera(float matrix[4][4], float pos[3], float tgt[3], float roll) {
    float M[4][4];
    float x[3], y[3], z[3];

    lib3ds_vector_sub(y, tgt, pos);
    lib3ds_vector_normalize(y);

    if (y[0] != 0. || y[1] != 0) {
        z[0] = 0;
        z[1] = 0;
        z[2] = 1.0;
    } else { /* Special case:  looking straight up or down z axis */
        z[0] = -1.0;
        z[1] = 0;
        z[2] = 0;
    }

    lib3ds_vector_cross(x, y, z);
    lib3ds_vector_cross(z, x, y);
    lib3ds_vector_normalize(x);
    lib3ds_vector_normalize(z);

    lib3ds_matrix_identity(M);
    M[0][0] = x[0];
    M[1][0] = x[1];
    M[2][0] = x[2];
    M[0][1] = y[0];
    M[1][1] = y[1];
    M[2][1] = y[2];
    M[0][2] = z[0];
    M[1][2] = z[1];
    M[2][2] = z[2];

    lib3ds_matrix_identity(matrix);
    lib3ds_matrix_rotate(matrix, roll, 0, 1, 0);
    lib3ds_matrix_mult(matrix, matrix, M);
    lib3ds_matrix_translate(matrix, -pos[0], -pos[1], -pos[2]);
}
예제 #7
0
/*!
 * Calculates the vertex normals corresponding to the smoothing group
 * settings for each face of a mesh.
 *
 * \param mesh      A pointer to the mesh to calculate the normals for.
 * \param normals   A pointer to a buffer to store the calculated
 *                  normals. The buffer must have the size:
 *                  3*3*sizeof(float)*mesh->nfaces.
 *
 * To allocate the normal buffer do for example the following:
 * \code
 *  Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh->nfaces);
 * \endcode
 *
 * To access the normal of the i-th vertex of the j-th face do the
 * following:
 * \code
 *   normals[3*j+i]
 * \endcode
 */
void
lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh *mesh, float (*normals)[3]) {
    Lib3dsFaces **fl;
    Lib3dsFaces *fa;
    int i, j;

    if (!mesh->nfaces) {
        return;
    }

    fl = (Lib3dsFaces**)calloc(sizeof(Lib3dsFaces*), mesh->nvertices);
    fa = (Lib3dsFaces*)malloc(sizeof(Lib3dsFaces) * 3 * mesh->nfaces);

    for (i = 0; i < mesh->nfaces; ++i) {
        for (j = 0; j < 3; ++j) {
            Lib3dsFaces* l = &fa[3*i+j];
            float p[3], q[3], n[3];
            float len, weight;

            l->index = i;
            l->next = fl[mesh->faces[i].index[j]];
            fl[mesh->faces[i].index[j]] = l;

            lib3ds_vector_sub(p, mesh->vertices[mesh->faces[i].index[j<2? j + 1 : 0]], mesh->vertices[mesh->faces[i].index[j]]);
            lib3ds_vector_sub(q, mesh->vertices[mesh->faces[i].index[j>0? j - 1 : 2]], mesh->vertices[mesh->faces[i].index[j]]);
            lib3ds_vector_cross(n, p, q);
            len = lib3ds_vector_length(n);
            if (len > 0) {
                weight = (float)atan2(len, lib3ds_vector_dot(p, q));
                lib3ds_vector_scalar_mul(l->normal, n, weight / len);
            } else {
                lib3ds_vector_zero(l->normal);
            }
        }
    }

    for (i = 0; i < mesh->nfaces; ++i) {
        Lib3dsFace *f = &mesh->faces[i];
        for (j = 0; j < 3; ++j) {
            float n[3];
            Lib3dsFaces *p;
            Lib3dsFace *pf;

            assert(mesh->faces[i].index[j] < mesh->nvertices);

            if (f->smoothing_group) {
                unsigned smoothing_group = f->smoothing_group;

                lib3ds_vector_zero(n);
                for (p = fl[mesh->faces[i].index[j]]; p; p = p->next) {
                    pf = &mesh->faces[p->index];
                    if (pf->smoothing_group & f->smoothing_group)
                        smoothing_group |= pf->smoothing_group;
                }

                for (p = fl[mesh->faces[i].index[j]]; p; p = p->next) {
                    pf = &mesh->faces[p->index];
                    if (smoothing_group & pf->smoothing_group) {
                        lib3ds_vector_add(n, n, p->normal);
                    }
                }
            } else {
                lib3ds_vector_copy(n, fa[3*i+j].normal);
            }

            lib3ds_vector_normalize(n);
            lib3ds_vector_copy(normals[3*i+j], n);
        }
    }

    free(fa);
    free(fl);
}
예제 #8
0
파일: 3dsplay.c 프로젝트: gdh1995/GhostFace
/*!
* Main display function; called whenever the scene needs to be redrawn.
*/
static void
display(void)
{
  Lib3dsNode *c,*t;
  Lib3dsFloat fov, roll;
  float near, far, dist;
  float *campos;
  float *tgt;
  Lib3dsMatrix M;
  Lib3dsCamera *cam;
  Lib3dsVector v;
  Lib3dsNode *p;

  if( file != NULL && file->background.solid.use )
    glClearColor(file->background.solid.col[0],
    file->background.solid.col[1],
    file->background.solid.col[2], 1.);

  /* TODO: fog */

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  if( anti_alias )
    glEnable(GL_POLYGON_SMOOTH);
  else
    glDisable(GL_POLYGON_SMOOTH);


  if (!file) {
    return;
  }

  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, file->ambient);

  c=lib3ds_file_node_by_name(file, camera, LIB3DS_CAMERA_NODE);
  t=lib3ds_file_node_by_name(file, camera, LIB3DS_TARGET_NODE);

  if( t != NULL )
    tgt = t->data.target.pos;

  if( c != NULL ) {
    fov = c->data.camera.fov;
    roll = c->data.camera.roll;
    campos = c->data.camera.pos;
  }

  if ((cam = lib3ds_file_camera_by_name(file, camera)) == NULL)
    return;

  near = cam->near_range;
  far = cam->far_range;

  if (c == NULL || t == NULL) {
    if( c == NULL ) {
      fov = cam->fov;
      roll = cam->roll;
      campos = cam->position;
    }
    if( t == NULL )
      tgt = cam->target;
  }

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  /* KLUDGE alert:  OpenGL can't handle a near clip plane of zero,
  * so if the camera's near plane is zero, we give it a small number.
  * In addition, many .3ds files I've seen have a far plane that's
  * much too close and the model gets clipped away.  I haven't found
  * a way to tell OpenGL not to clip the far plane, so we move it
  * further away.  A factor of 10 seems to make all the models I've
  * seen visible.
  */
  if( near <= 0. ) near = far * .001;

  gluPerspective( fov, 1.0*gl_width/gl_height, near, far);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glRotatef(-90, 1.0,0,0);

  /* User rotates the view about the target point */

  lib3ds_vector_sub(v, tgt, campos);
  dist = lib3ds_vector_length(v);

  glTranslatef(0.,dist, 0.);
  glRotatef(view_rotx, 1., 0., 0.);
  glRotatef(view_roty, 0., 1., 0.);
  glRotatef(view_rotz, 0., 0., 1.);
  glTranslatef(0.,-dist, 0.);

  lib3ds_matrix_camera(M, campos, tgt, roll);
  glMultMatrixf(&M[0][0]);

  /* Lights.  Set them from light nodes if possible.  If not, use the
  * light objects directly.
  */
  {
    static const GLfloat a[] = {0.0f, 0.0f, 0.0f, 1.0f};
    static GLfloat c[] = {1.0f, 1.0f, 1.0f, 1.0f};
    static GLfloat p[] = {0.0f, 0.0f, 0.0f, 1.0f};
    Lib3dsLight *l;

    int li=GL_LIGHT0;
    for (l=file->lights; l; l=l->next) {
      glEnable(li);

      light_update(l);

      c[0] = l->color[0];
      c[1] = l->color[1];
      c[2] = l->color[2];
      glLightfv(li, GL_AMBIENT, a);
      glLightfv(li, GL_DIFFUSE, c);
      glLightfv(li, GL_SPECULAR, c);

      p[0] = l->position[0];
      p[1] = l->position[1];
      p[2] = l->position[2];
      glLightfv(li, GL_POSITION, p);

      if (l->spot_light) {
        p[0] = l->spot[0] - l->position[0];
        p[1] = l->spot[1] - l->position[1];
        p[2] = l->spot[2] - l->position[2];
        glLightfv(li, GL_SPOT_DIRECTION, p);
      }
      ++li;
    }
  }




  if( show_object )
  {
    for (p=file->nodes; p!=0; p=p->next) {
      render_node(p);
    }
  }

  if( show_bounds )
    draw_bounds(tgt);

  if( show_cameras )
  {
    for( cam = file->cameras; cam != NULL; cam = cam->next )
    {
      lib3ds_matrix_camera(M, cam->position, cam->target, cam->roll);
      lib3ds_matrix_inv(M);

      glPushMatrix();
      glMultMatrixf(&M[0][0]);
      glScalef(size/20, size/20, size/20);
      glCallList(cameraList);
      glPopMatrix();
    }
  }

  if( show_lights )
  {
    Lib3dsLight *light;
    for( light = file->lights; light != NULL; light = light->next )
      draw_light(light->position, light->color);
    glMaterialfv(GL_FRONT, GL_EMISSION, black);
  }


  glutSwapBuffers();
}