コード例 #1
0
ファイル: geo.quadric.c プロジェクト: Thundzz/TDP
BOOL hit_geo_sphere (GEO *Generic, RAY *Ray, HIT *Hit, PAIR *Bound, void *Info)
{
  GEO_SPHERE  *Geo;
  VECTOR      Point;
  REAL        a, b, Distance, Delta;

  Geo = (GEO_SPHERE *) Generic;

  VEC_SUB (Point, Ray->Point, Geo->Point);
  a = - VEC_DOT (Point, Ray->Vector);
  b = VEC_DOT (Point, Point);
  Delta = a * a - b + Geo->Radius * Geo->Radius;
  if (Delta < 0.0)
    return (FALSE);

  Delta = sqrt (Delta);
  Distance = a - Delta;   /* - Epsilon;*/
  if (Distance < Bound->u || Distance > Bound->v)
    return (FALSE);

  if (Hit) {
    Ray->Distance = Distance;
    VEC_LIN (Point, Ray->Point, Distance, Ray->Vector);
    VEC_SUB (Hit->Normal, Point, Geo->Point);
    if (VEC_DOT (Ray->Vector, Hit->Normal) > 0.0)
      VEC_NEG (Hit->Normal);
    VEC_UNIT (Hit->Normal, Distance);
    VEC_LIN (Hit->Point, Point, Epsilon, Hit->Normal);
    xyz2uv_geo_sphere (Geo, Hit);
  }

  return (TRUE);
}
コード例 #2
0
ファイル: geo.nappe.c プロジェクト: Moeryn/PRCD-TP5
/********************************************************
 * Search for an intersection between a nappe and a ray *
 *******************************************************/
BOOL hit_geo_nappe (GEO *Generic, RAY *Ray, HIT *Hit, PAIR *Bound, void *Info)
{
	GEO_NAPPE	*Geo;
	FCT		*Fct;
	PNT	        *Pnt, *PntA, *PntB;
	VECTOR		Normal;
	VECTOR		Point;
	REAL		a, b, c, u, v, uA, vA, uB, vB, Distance, Real;

  Geo = (GEO_NAPPE *) Generic;

  Fct = (FCT *) Info;
  Distance = VEC_DOT (Ray->Vector, Fct->Normal);
  if (ABS(Distance) < EPSILON)
    return (FALSE);
  Pnt = Geo->TabPnt + Fct->i;
  VEC_SUB (Point, Pnt->Point, Ray->Point);
  Distance = VEC_DOT (Point, Fct->Normal) / Distance ; /*-Epsilon est vire*/
  if (Distance < Bound->u || Distance > Bound->v)
    return (FALSE);
  VEC_LIN (Point, Ray->Point, Distance, Ray->Vector);

  if ((ABS(Fct->Normal.z) > ABS(Fct->Normal.x)) && (ABS(Fct->Normal.z) > ABS(Fct->Normal.y))) {
    u = Point.x - Pnt->Point.x; v = Point.y - Pnt->Point.y;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.x - Pnt->Point.x; vA = PntA->Point.y - Pnt->Point.y;
    uB = PntB->Point.x - Pnt->Point.x; vB = PntB->Point.y - Pnt->Point.y;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA-u*vA) / a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }

    if (Fct->l == Fct->i) 
      return (FALSE);
    
    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.x - Pnt->Point.x; vA = PntA->Point.y - Pnt->Point.y;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }

  else if (ABS(Fct->Normal.y) > ABS(Fct->Normal.x)) {
    u = Point.z - Pnt->Point.z; v = Point.x - Pnt->Point.x;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.z - Pnt->Point.z; vA = PntA->Point.x - Pnt->Point.x;
    uB = PntB->Point.z - Pnt->Point.z; vB = PntB->Point.x - Pnt->Point.x;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    
    if (Fct->l == Fct->i) return (FALSE);

    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.z - Pnt->Point.z; vA = PntA->Point.x - Pnt->Point.x;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }

  else if (ABS(Fct->Normal.x) > EPSILON) {
    u = Point.y - Pnt->Point.y; v = Point.z - Pnt->Point.z;
    PntA = Geo->TabPnt + Fct->j; PntB = Geo->TabPnt + Fct->k;
    uA = PntA->Point.y - Pnt->Point.y; vA = PntA->Point.z - Pnt->Point.z;
    uB = PntB->Point.y - Pnt->Point.y; vB = PntB->Point.z - Pnt->Point.z;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    
    if (Fct->l == Fct->i) return (FALSE);

    PntA = Geo->TabPnt + Fct->l;
    uA = PntA->Point.y - Pnt->Point.y; vA = PntA->Point.z - Pnt->Point.z;
    a = uA*vB - vA*uB; b = (u*vB - v*uB)/a; c = (v*uA - u*vA)/a; a = 1.0-b-c;

    if (a > -EPSILON && b > -EPSILON && c > -EPSILON) {
      VEC_INTER (Normal, a, Pnt->Normal, b, PntA->Normal, c, PntB->Normal);
      Real = VEC_DOT (Ray->Vector, Normal);
      if (Real > 0.0)
	return (FALSE);
      if (Hit) {
        Real = VEC_LEN (Normal); VEC_UNIT (Normal, Real);
        Ray->Distance = Distance; Hit->Point = Point; Hit->Normal = Normal;
	xyz2uv_geo_nappe (Geo, Hit, Fct);
      }
      return (TRUE);
    }
    return (FALSE);
  }
  return (FALSE);
}