Пример #1
0
int
_echoRayIntx_TriMesh(RAYINTX_ARGS(TriMesh)) {
  echoPos_t *pos, vert0[3], edge0[3], edge1[3], pvec[3], qvec[3], tvec[3],
    det, t, tmax, u, v, tmp;
  echoTriMesh *trim;
  int i, ret;

  AIR_UNUSED(parm);
  trim = TRIMESH(obj);
  if (!_echoRayIntx_CubeSolid(&t, &tmax,
                              trim->min[0], trim->max[0],
                              trim->min[1], trim->max[1],
                              trim->min[2], trim->max[2], ray)) {
    if (tstate->verbose) {
      fprintf(stderr, "%s%s: trimesh bbox (%g,%g,%g) --> (%g,%g,%g) not hit\n",
              _echoDot(tstate->depth), "_echoRayIntx_TriMesh",
              trim->min[0], trim->min[1], trim->min[2],
              trim->max[0], trim->max[1], trim->max[2]);
    }
    return AIR_FALSE;
  }
  /* stupid linear search for now */
  ret = AIR_FALSE;
  for (i=0; i<trim->numF; i++) {
    pos = trim->pos + 3*trim->vert[0 + 3*i];
    ELL_3V_COPY(vert0, pos);
    pos = trim->pos + 3*trim->vert[1 + 3*i];
    ELL_3V_SUB(edge0, pos, vert0);
    pos = trim->pos + 3*trim->vert[2 + 3*i];
    ELL_3V_SUB(edge1, pos, vert0);
    TRI_INTX(ray, vert0, edge0, edge1,
             pvec, qvec, tvec, det, t, u, v,
             (v < 0.0 || u + v > 1.0), continue);
    if (ray->shadow) {
      return AIR_TRUE;
    }
    intx->t = ray->faar = t;
    ELL_3V_CROSS(intx->norm, edge0, edge1);
    ELL_3V_NORM(intx->norm, intx->norm, tmp);
    intx->obj = (echoObject *)obj;
    intx->face = i;
    ret = AIR_TRUE;
  }
  /* does NOT set u, v */
  return ret;
}
Пример #2
0
echoObject *
echoRoughSphereNew(echoScene *scene, int theRes, int phiRes, echoPos_t *matx) {
  echoObject *trim;
  echoPos_t *_pos, *pos, tmp[3];
  int *_vert, *vert, thidx, phidx, n;
  echoPos_t th, ph;

  trim = echoObjectNew(scene, echoTypeTriMesh);
  TRIMESH(trim)->numV = 2 + (phiRes-1)*theRes;
  TRIMESH(trim)->numF = (2 + 2*(phiRes-2))*theRes;

  _pos = pos = (echoPos_t *)calloc(3*TRIMESH(trim)->numV, sizeof(echoPos_t));
  _vert = vert = (int *)calloc(3*TRIMESH(trim)->numF, sizeof(int));

  ELL_3V_SET(tmp, 0, 0, 1); _echoPosSet(pos, matx, tmp); pos += 3;
  for (phidx=1; phidx<phiRes; phidx++) {
    ph = AIR_AFFINE(0, phidx, phiRes, 0.0, AIR_PI);
    for (thidx=0; thidx<theRes; thidx++) {
      th = AIR_AFFINE(0, thidx, theRes, 0.0, 2*AIR_PI);
      ELL_3V_SET(tmp, cos(th)*sin(ph), sin(th)*sin(ph), cos(ph));
      _echoPosSet(pos, matx, tmp); pos += 3;
    }
  }
  ELL_3V_SET(tmp, 0, 0, -1); _echoPosSet(pos, matx, tmp);

  for (thidx=0; thidx<theRes; thidx++) {
    n = AIR_MOD(thidx+1, theRes);
    ELL_3V_SET(vert, 0, 1+thidx, 1+n); vert += 3;
  }
  for (phidx=0; phidx<phiRes-2; phidx++) {
    for (thidx=0; thidx<theRes; thidx++) {
      n = AIR_MOD(thidx+1, theRes);
      ELL_3V_SET(vert, 1+phidx*theRes+thidx, 1+(1+phidx)*theRes+thidx,
                 1+phidx*theRes+n); vert += 3;
      ELL_3V_SET(vert, 1+(1+phidx)*theRes+thidx, 1+(1+phidx)*theRes+n, 
                 1+phidx*theRes+n); vert += 3;
    }
  }
  for (thidx=0; thidx<theRes; thidx++) {
    n = AIR_MOD(thidx+1, theRes);
    ELL_3V_SET(vert, 1+(phiRes-2)*theRes+thidx, TRIMESH(trim)->numV-1,
               1+(phiRes-2)*theRes+n); 
    vert += 3;
  }

  echoTriMeshSet(trim, TRIMESH(trim)->numV, _pos, TRIMESH(trim)->numF, _vert);
  return(trim);
}
Пример #3
0
void
_echoRayIntxUV_TriMesh(echoIntx *intx) {
  echoPos_t u, v, norm[3], len;
  echoTriMesh *trim;

  trim = TRIMESH(intx->obj);
  ELL_3V_SUB(norm, intx->pos, trim->meanvert);
  ELL_3V_NORM(norm, norm, len);
  if (norm[0] || norm[1]) {
    u = atan2(norm[1], norm[0]);
    intx->u = AIR_AFFINE(-AIR_PI, u, AIR_PI, 0.0, 1.0);
    v = -asin(norm[2]);
    intx->v = AIR_AFFINE(-AIR_PI/2, v, AIR_PI/2, 0.0, 1.0);
  }
  else {
    intx->u = 0;
    intx->v = AIR_AFFINE(1.0, norm[2], -1.0, 0.0, 1.0);
  }
}
Пример #4
0
/*
******** echoTriMeshSet()
**
** This has to be called any time that the locations of the points are
** changing, even if the connectivity is not changed, because of how
** the bounding box and mean vert position is calculated here.
**
** NB: the TriMesh will directly use the given pos[] and vert[] arrays,
** so don't go freeing them after they've been passed here.
*/
void
echoTriMeshSet(echoObject *trim,
               int numV, echoPos_t *pos,
               int numF, int *vert) {
  int i;

  if (trim && echoTypeTriMesh == trim->type) {
    TRIMESH(trim)->numV = numV;
    TRIMESH(trim)->numF = numF;
    TRIMESH(trim)->pos = pos;
    TRIMESH(trim)->vert = vert;
    ELL_3V_SET(TRIMESH(trim)->min, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX);
    ELL_3V_SET(TRIMESH(trim)->max, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN);
    ELL_3V_SET(TRIMESH(trim)->meanvert, 0.0, 0.0, 0.0);
    for (i=0; i<numV; i++) {
      ELL_3V_MIN(TRIMESH(trim)->min, TRIMESH(trim)->min, pos + 3*i);
      ELL_3V_MAX(TRIMESH(trim)->max, TRIMESH(trim)->max, pos + 3*i);
      ELL_3V_INCR(TRIMESH(trim)->meanvert, pos + 3*i);
    }
    ELL_3V_SCALE(TRIMESH(trim)->meanvert, 1.0/numV, TRIMESH(trim)->meanvert);
  }
  return;
}