CONE *Create_Cylinder() { CONE *New; New = (CONE *)POV_MALLOC(sizeof(CONE), "cone"); INIT_OBJECT_FIELDS(New, CONE_OBJECT, &Cone_Methods) Make_Vector(New->apex, 0.0, 0.0, 1.0); Make_Vector(New->base, 0.0, 0.0, 0.0); New->apex_radius = 1.0; New->base_radius = 1.0; New->dist = 0.0; New->Trans = Create_Transform(); Set_Flag(New, CYLINDER_FLAG); /* This is a cylinder. */ Set_Flag(New, CLOSED_FLAG); /* Has capped ends. */ /* Default bounds */ Make_BBox(New->BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0); return (New); }
void Cone::Cylinder() { apex_radius = 1.0; base_radius = 1.0; Set_Flag(this, CYLINDER_FLAG); // This is a cylinder. }
GMC_DCL(boolean, IgnoreStatus) { tp_FilPrm FilPrm; tp_FilElm FilElm; *FilHdrPtr = (tp_FilHdr)NIL; *FilPrmPtr = (tp_FilPrm)NIL; if (FilHdr == ERROR) { return; }/*if*/; if (FilHdr_Flag(FilHdr, FLAG_DeRef)) { FilHdr_Error("<%s> is circular.\n", FilHdr); Ret_FilHdr(FilHdr); return; }/*if*/; if (!(IsPntr(FilHdr) && (FilHdr_Status(FilHdr) > STAT_Error || IgnoreStatus))) { *FilHdrPtr = FilHdr; *FilPrmPtr = RootFilPrm; return; }/*if*/; FilElm = LocElm_FilElm(FilHdr_LocElm(FilHdr)); if (IgnoreStatus && FilElm == NIL) { Ret_FilHdr(FilHdr); return; }/*if*/; FORBIDDEN(!IgnoreStatus && (FilElm == NIL || FilElm_Next(FilElm) != NIL)); *FilHdrPtr = FilElm_FilHdr(FilElm); FilPrm = FilElm_FilPrm(FilElm); Ret_FilElm(FilElm); Set_Flag(FilHdr, FLAG_DeRef); Deref_Pntrs(FilHdrPtr, FilPrmPtr, *FilHdrPtr, IgnoreStatus); Clr_Flag(FilHdr, FLAG_DeRef); *FilPrmPtr = Append_FilPrm(*FilPrmPtr, FilPrm); Ret_FilHdr(FilHdr); }/*Deref_Pntrs*/
GMC_DCL(tp_FilHdr, ListFilHdr) { tp_FilHdr ElmFilHdr; tp_LocElm LocElm; tp_FilElm FilElm; if (IsViewSpec(FilHdr)) { FilHdr_Error("Illegal view specification argument: %s\n", FilHdr); return; }/*if*/; if (FilHdr_Flag(FilHdr, FLAG_Union)) { return; }/*if*/; Set_Flag(FilHdr, FLAG_Union); if (!IsRef(FilHdr)) { ElmFilHdr = Do_Deriv(Copy_FilHdr(FilHdr), RootFilPrm, FilPrm, FilTyp); /*select*/{ if (ElmFilHdr != ERROR) { LocElm = Make_LocElm(ElmFilHdr, RootFilPrm, ListFilHdr); Chain_LocElms(FirstLEPtr, LastLEPtr, LocElm); Ret_FilHdr(ElmFilHdr); }else{ FilHdr_Error(" from:\n %s.\n", FilHdr); };}/*select*/; return; }/*if*/; for (FilElm = LocElm_FilElm(FilHdr_LocElm(FilHdr)); FilElm != NIL; FilElm = FilElm_NextFilElm(FilElm)) { ElmFilHdr = FilElm_FilHdr(FilElm); Get_Map(FirstLEPtr, LastLEPtr, ElmFilHdr, Append_FilPrm(FilElm_FilPrm(FilElm), FilPrm), FilTyp, ListFilHdr); Ret_FilHdr(ElmFilHdr); }/*for*/; }/*Get_Map*/
GMC_DCL(tp_FilHdr, FilHdr) { tp_FilHdr DestElmFH, OrigElmFH; tp_LocElm LocElm; tp_FilElm FilElm; tps_Str StrBuf; if (FilHdr_Flag(OrigFilHdr, FLAG_Union)) { return; }/*if*/; Set_Flag(OrigFilHdr, FLAG_Union); if (!IsRef(OrigFilHdr)) { DestElmFH = Copy_FilHdr(DestFilHdr); DestElmFH = Do_Key(DestElmFH, FilHdr_Label(StrBuf, OrigFilHdr, FALSE)); LocElm = Make_CopyLocElm(OrigFilHdr, DestElmFH, FilHdr); Chain_LocElms(FirstLEPtr, LastLEPtr, LocElm); Ret_FilHdr(DestElmFH); return; }/*if*/; for (FilElm = LocElm_FilElm(FilHdr_LocElm(OrigFilHdr)); FilElm != NIL; FilElm = FilElm_NextFilElm(FilElm)) { OrigElmFH = FilElm_FilHdr(FilElm); Get_CopyList(FirstLEPtr, LastLEPtr, OrigElmFH, DestFilHdr, FilHdr); Ret_FilHdr(OrigElmFH); }/*for*/; }/*Get_CopyList*/
Sor::Sor() : ObjectBase(SOR_OBJECT) { Trans = Create_Transform(); Spline = NULL; Radius2 = 0.0; Base_Radius_Squared = 0.0; Cap_Radius_Squared = 0.0; /* SOR should have capped ends by default. CEY 3/98*/ Set_Flag(this, CLOSED_FLAG); }
static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle) { VECTOR P3MinusP2, VTemp1, VTemp2; DBL x, y, z, uDenominator, Proj; VSub(P3MinusP2, Triangle->P3, Triangle->P2); x = fabs(P3MinusP2[X]); y = fabs(P3MinusP2[Y]); z = fabs(P3MinusP2[Z]); Triangle->vAxis = max3_coordinate(x, y, z); VSub(VTemp1, Triangle->P2, Triangle->P3); VNormalize(VTemp1, VTemp1); VSub(VTemp2, Triangle->P1, Triangle->P3); VDot(Proj, VTemp2, VTemp1); VScaleEq(VTemp1, Proj); VSub(Triangle->Perp, VTemp1, VTemp2); VNormalize(Triangle->Perp, Triangle->Perp); VDot(uDenominator, VTemp2, Triangle->Perp); VInverseScaleEq(Triangle->Perp, -uDenominator); /* Degenerate if smooth normals are more than 90 from actual normal or its inverse. */ VDot(x,Triangle->Normal_Vector,Triangle->N1); VDot(y,Triangle->Normal_Vector,Triangle->N2); VDot(z,Triangle->Normal_Vector,Triangle->N3); if ( ((x<0.0) && (y<0.0) && (z<0.0)) || ((x>0.0) && (y>0.0) && (z>0.0)) ) { return(true); } Set_Flag(Triangle, DEGENERATE_FLAG); return(false); }
Lemon::Lemon() : ObjectBase(LEMON_OBJECT) { apex = Vector3d(0.0, 0.0, 1.0); base = Vector3d(0.0, 0.0, 0.0); apex_radius = 0.0; base_radius = 0.0; inner_radius = 0.5; Trans = Create_Transform(); /* Lemon has capped ends by default. */ Set_Flag(this, CLOSED_FLAG); /* Default bounds */ Make_BBox(BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0); }
Cone::Cone() : ObjectBase(CONE_OBJECT) { apex = Vector3d(0.0, 0.0, 1.0); base = Vector3d(0.0, 0.0, 0.0); apex_radius = 1.0; base_radius = 0.0; dist = 0.0; Trans = Create_Transform(); /* Cone/Cylinder has capped ends by default. */ Set_Flag(this, CLOSED_FLAG); /* Default bounds */ Make_BBox(BBox, -1.0, -1.0, 0.0, 2.0, 2.0, 1.0); }
bool SmoothTriangle::Compute_Smooth_Triangle() { Vector3d P3MinusP2, VTemp1, VTemp2; DBL x, y, z, uDenominator, Proj; P3MinusP2 = P3 - P2; x = fabs(P3MinusP2[X]); y = fabs(P3MinusP2[Y]); z = fabs(P3MinusP2[Z]); vAxis = max3_coordinate(x, y, z); VTemp1 = (P2 - P3).normalized(); VTemp2 = (P1 - P3); Proj = dot(VTemp2, VTemp1); VTemp1 *= Proj; Perp = (VTemp1 - VTemp2).normalized(); uDenominator = dot(VTemp2, Perp); Perp /= -uDenominator; /* Degenerate if smooth normals are more than 90 from actual normal or its inverse. */ x = dot(Normal_Vector,N1); y = dot(Normal_Vector,N2); z = dot(Normal_Vector,N3); if ( ((x<0.0) && (y<0.0) && (z<0.0)) || ((x>0.0) && (y>0.0) && (z>0.0)) ) { return(true); } Set_Flag(this, DEGENERATE_FLAG); return(false); }
LightSource::LightSource() : CompoundObject(LIGHT_OBJECT) { Set_Flag(this, NO_SHADOW_FLAG); colour = MathColour(1.0); Direction = Vector3d(0.0, 0.0, 0.0); Center = Vector3d(0.0, 0.0, 0.0); Points_At = Vector3d(0.0, 0.0, 1.0); Axis1 = Vector3d(0.0, 0.0, 1.0); Axis2 = Vector3d(0.0, 1.0, 0.0); Coeff = 0.0; Radius = 0.0; Falloff = 0.0; Fade_Distance = 0.0; Fade_Power = 0.0; Projected_Through_Object= NULL; Light_Type = POINT_SOURCE; Area_Light = false; Use_Full_Area_Lighting = false; // JN2007: Full area lighting Jitter = false; Orient = false; Circular = false; Parallel = false; Photon_Area_Light = false; Area_Size1 = 0; Area_Size2 = 0; Adaptive_Level = 100; Media_Attenuation = false; Media_Interaction = true; }
void Compute_Polygon(POLYGON *Polyg, int Number, VECTOR *Points) { int i; DBL x, y, z, d; VECTOR o, u, v, w, N; MATRIX a, b; /* Create polygon data. */ if (Polyg->Data == NULL) { Polyg->Data = (POLYGON_DATA *)POV_MALLOC(sizeof(POLYGON_DATA), "polygon points"); Polyg->Data->References = 1; Polyg->Data->Number = Number; Polyg->Data->Points = (UV_VECT *)POV_MALLOC(Number*sizeof(UV_VECT), "polygon points"); } else { Error("Polygon data already computed."); } /* Get polygon's coordinate system (one of the many possible) */ Assign_Vector(o, Points[0]); /* Find valid, i.e. non-zero u vector. */ for (i = 1; i < Number; i++) { VSub(u, Points[i], o); if (VSumSqr(u) > EPSILON) { break; } } if (i == Number) { Set_Flag(Polyg, DEGENERATE_FLAG); Warning(0, "Points in polygon are co-linear. Ignoring polygon."); } /* Find valid, i.e. non-zero v and w vectors. */ for (i++; i < Number; i++) { VSub(v, Points[i], o); VCross(w, u, v); if ((VSumSqr(v) > EPSILON) && (VSumSqr(w) > EPSILON)) { break; } } if (i == Number) { Set_Flag(Polyg, DEGENERATE_FLAG); Warning(0, "Points in polygon are co-linear. Ignoring polygon."); } VCross(u, v, w); VCross(v, w, u); VNormalize(u, u); VNormalize(v, v); VNormalize(w, w); MIdentity(a); MIdentity(b); a[3][0] = -o[X]; a[3][1] = -o[Y]; a[3][2] = -o[Z]; b[0][0] = u[X]; b[1][0] = u[Y]; b[2][0] = u[Z]; b[0][1] = v[X]; b[1][1] = v[Y]; b[2][1] = v[Z]; b[0][2] = w[X]; b[1][2] = w[Y]; b[2][2] = w[Z]; MTimesC(Polyg->Trans->inverse, a, b); MInvers(Polyg->Trans->matrix, Polyg->Trans->inverse); /* Project points onto the u,v-plane (3D --> 2D) */ for (i = 0; i < Number; i++) { x = Points[i][X] - o[X]; y = Points[i][Y] - o[Y]; z = Points[i][Z] - o[Z]; d = x * w[X] + y * w[Y] + z * w[Z]; if (fabs(d) > ZERO_TOLERANCE) { Set_Flag(Polyg, DEGENERATE_FLAG); Warning(0, "Points in polygon are not co-planar. Ignoring polygons."); } Polyg->Data->Points[i][X] = x * u[X] + y * u[Y] + z * u[Z]; Polyg->Data->Points[i][Y] = x * v[X] + y * v[Y] + z * v[Z]; } Make_Vector(N, 0.0, 0.0, 1.0); MTransNormal(Polyg->S_Normal, N, Polyg->Trans); VNormalizeEq(Polyg->S_Normal); Compute_Polygon_BBox(Polyg); }
void Polygon::Compute_Polygon(int number, Vector3d *points) { int i; DBL x, y, z, d; Vector3d o, u, v, w, N; MATRIX a, b; /* Create polygon data. */ if (Data == NULL) { Data = reinterpret_cast<POLYGON_DATA *>(POV_MALLOC(sizeof(POLYGON_DATA), "polygon points")); Data->References = 1; Data->Number = number; Data->Points = reinterpret_cast<Vector2d *>(POV_MALLOC(number*sizeof(Vector2d), "polygon points")); } else { throw POV_EXCEPTION_STRING("Polygon data already computed."); } /* Get polygon's coordinate system (one of the many possible) */ o = points[0]; /* Find valid, i.e. non-zero u vector. */ for (i = 1; i < number; i++) { u = points[i] - o; if (u.lengthSqr() > EPSILON) { break; } } if (i == number) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are co-linear. Ignoring polygon."); } /* Find valid, i.e. non-zero v and w vectors. */ for (i++; i < number; i++) { v = points[i] - o; w = cross(u, v); if ((v.lengthSqr() > EPSILON) && (w.lengthSqr() > EPSILON)) { break; } } if (i == number) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are co-linear. Ignoring polygon."); } u = cross(v, w); v = cross(w, u); u.normalize(); v.normalize(); w.normalize(); MIdentity(a); MIdentity(b); a[3][0] = -o[X]; a[3][1] = -o[Y]; a[3][2] = -o[Z]; b[0][0] = u[X]; b[1][0] = u[Y]; b[2][0] = u[Z]; b[0][1] = v[X]; b[1][1] = v[Y]; b[2][1] = v[Z]; b[0][2] = w[X]; b[1][2] = w[Y]; b[2][2] = w[Z]; MTimesC(Trans->inverse, a, b); MInvers(Trans->matrix, Trans->inverse); /* Project points onto the u,v-plane (3D --> 2D) */ for (i = 0; i < number; i++) { x = points[i][X] - o[X]; y = points[i][Y] - o[Y]; z = points[i][Z] - o[Z]; d = x * w[X] + y * w[Y] + z * w[Z]; if (fabs(d) > ZERO_TOLERANCE) { Set_Flag(this, DEGENERATE_FLAG); ;// TODO MESSAGE Warning("Points in polygon are not co-planar. Ignoring polygons."); } Data->Points[i][X] = x * u[X] + y * u[Y] + z * u[Z]; Data->Points[i][Y] = x * v[X] + y * v[Y] + z * v[Z]; } N = Vector3d(0.0, 0.0, 1.0); MTransNormal(S_Normal, N, Trans); S_Normal.normalize(); Compute_BBox(); }
bool Triangle::Compute_Triangle() { int swap; Vector3d V1, V2, Temp; DBL Length; V1 = P1 - P2; V2 = P3 - P2; Normal_Vector = cross(V1, V2); Length = Normal_Vector.length(); /* Set up a flag so we can ignore degenerate triangles */ if (Length == 0.0) { Set_Flag(this, DEGENERATE_FLAG); return(false); } /* Normalize the normal vector. */ Normal_Vector /= Length; Distance = dot(Normal_Vector, P1); Distance *= -1.0; find_triangle_dominant_axis(); swap = false; switch (Dominant_Axis) { case X: if ((P2[Y] - P3[Y])*(P2[Z] - P1[Z]) < (P2[Z] - P3[Z])*(P2[Y] - P1[Y])) { swap = true; } break; case Y: if ((P2[X] - P3[X])*(P2[Z] - P1[Z]) < (P2[Z] - P3[Z])*(P2[X] - P1[X])) { swap = true; } break; case Z: if ((P2[X] - P3[X])*(P2[Y] - P1[Y]) < (P2[Y] - P3[Y])*(P2[X] - P1[X])) { swap = true; } break; } if (swap) { Temp = P2; P2 = P1; P1 = Temp; } /* Build the bounding information from the vertices. */ Compute_BBox(); return(true); }
void Cone::Compute_Cone_Data() { DBL tlen, len, tmpf; Vector3d tmpv, axis, origin; /* Process the primitive specific information */ /* Find the axis and axis length */ axis = apex - base; len = axis.length(); if (len < EPSILON) { throw POV_EXCEPTION_STRING("Degenerate cone/cylinder."); // TODO FIXME - should a possible error } else { axis /= len; } /* we need to trap that case first */ if (fabs(apex_radius - base_radius) < EPSILON) { /* What we are dealing with here is really a cylinder */ Set_Flag(this, CYLINDER_FLAG); Compute_Cylinder_Data(); return; } if (apex_radius < base_radius) { /* Want the bigger end at the top */ tmpv = base; base = apex; apex = tmpv; tmpf = base_radius; base_radius = apex_radius; apex_radius = tmpf; axis.invert(); } /* apex & base are different, yet, it might looks like a cylinder */ tmpf = base_radius * len / (apex_radius - base_radius); origin = base - axis * tmpf; tlen = tmpf + len; /* apex is always bigger here */ if (((apex_radius - base_radius)*len/tlen) < EPSILON) { /* What we are dealing with here is really a cylinder */ Set_Flag(this, CYLINDER_FLAG); Compute_Cylinder_Data(); return; } dist = tmpf / tlen; /* Determine alignment */ Compute_Coordinate_Transform(Trans, origin, axis, apex_radius, tlen); /* Recalculate the bounds */ Compute_BBox(); }
void Compute_Cone_Data(OBJECT *Object) { DBL tlen, len, tmpf; VECTOR tmpv, axis, origin; CONE *Cone = (CONE *)Object; /* Process the primitive specific information */ if (fabs(Cone->apex_radius - Cone->base_radius) < EPSILON) { /* What we are dealing with here is really a cylinder */ Set_Flag(Cone, CYLINDER_FLAG); Compute_Cylinder_Data(Object); return; } if (Cone->apex_radius < Cone->base_radius) { /* Want the bigger end at the top */ Assign_Vector(tmpv,Cone->base); Assign_Vector(Cone->base,Cone->apex); Assign_Vector(Cone->apex,tmpv); tmpf = Cone->base_radius; Cone->base_radius = Cone->apex_radius; Cone->apex_radius = tmpf; } /* Find the axis and axis length */ VSub(axis, Cone->apex, Cone->base); VLength(len, axis); if (len < EPSILON) { Error("Degenerate cone/cylinder."); } else { VInverseScaleEq(axis, len); } /* Determine alignment */ tmpf = Cone->base_radius * len / (Cone->apex_radius - Cone->base_radius); VScale(origin, axis, tmpf); VSub(origin, Cone->base, origin); tlen = tmpf + len; Cone->dist = tmpf / tlen; Compute_Coordinate_Transform(Cone->Trans, origin, axis, Cone->apex_radius, tlen); /* Recalculate the bounds */ Compute_Cone_BBox(Cone); }
int Compute_Triangle(TRIANGLE *Triangle,int Smooth) { int swap,degn; VECTOR V1, V2, Temp; DBL Length; VSub(V1, Triangle->P1, Triangle->P2); VSub(V2, Triangle->P3, Triangle->P2); VCross(Triangle->Normal_Vector, V1, V2); VLength(Length, Triangle->Normal_Vector); /* Set up a flag so we can ignore degenerate triangles */ if (Length == 0.0) { Set_Flag(Triangle, DEGENERATE_FLAG); return(false); } /* Normalize the normal vector. */ VInverseScaleEq(Triangle->Normal_Vector, Length); VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1); Triangle->Distance *= -1.0; find_triangle_dominant_axis(Triangle); swap = false; switch (Triangle->Dominant_Axis) { case X: if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) < (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y])) { swap = true; } break; case Y: if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) < (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X])) { swap = true; } break; case Z: if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) < (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X])) { swap = true; } break; } if (swap) { Assign_Vector(Temp, Triangle->P2); Assign_Vector(Triangle->P2, Triangle->P1); Assign_Vector(Triangle->P1, Temp); if (Smooth) { Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2); Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1); Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp); } } degn=true; if (Smooth) { degn=compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle); } /* Build the bounding information from the vertices. */ Compute_Triangle_BBox(Triangle); return(degn); }