예제 #1
0
TEXTURE *material_map(const Vector3d& EPoint, const TEXTURE *Texture)
{
    int reg_number = -1;
    int Material_Number;
    DBL xcoor = 0.0, ycoor = 0.0;
    RGBFTColour colour;

    /*
     * Now we have transformed x, y, z we use image mapping routine to determine
     * texture index.
     */

    if(map_pos(EPoint, Texture->pattern.get(), &xcoor, &ycoor))
        Material_Number = 0;
    else
    {
        if (const ImagePatternImpl *pattern = dynamic_cast<ImagePatternImpl*>(Texture->pattern.get()))
            image_colour_at(pattern->pImage, xcoor, ycoor, colour, &reg_number); // TODO ALPHA - we should decide whether we prefer premultiplied or non-premultiplied alpha
        else
            POV_PATTERN_ASSERT(false);

        if(reg_number == -1)
            Material_Number = (int)(colour.red() * 255.0);
        else
            Material_Number = reg_number;
    }

    if(Material_Number > Texture->Materials.size())
        Material_Number %= Texture->Materials.size();

    return Texture->Materials[Material_Number % Texture->Materials.size()];
}
예제 #2
0
bool image_map(const Vector3d& EPoint, const PIGMENT *Pigment, TransColour& colour)
{
    // TODO ALPHA - the caller does expect non-premultiplied data, but maybe he could profit from premultiplied data?

    int reg_number;
    DBL xcoor = 0.0, ycoor = 0.0;

    // If outside map coverage area, return clear

    if(map_pos(EPoint, Pigment->pattern.get(), &xcoor, &ycoor))
    {
        colour = ToTransColour(RGBFTColour(1.0, 1.0, 1.0, 0.0, 1.0));
        return false;
    }
    else
    {
        RGBFTColour rgbft;
        if (const ImagePatternImpl *pattern = dynamic_cast<ImagePatternImpl*>(Pigment->pattern.get()))
            image_colour_at(pattern->pImage, xcoor, ycoor, rgbft, &reg_number, false);
        else
            POV_PATTERN_ASSERT(false);
        colour = ToTransColour(rgbft);
        return true;
    }
}
예제 #3
0
파일: normal.cpp 프로젝트: BentSm/povray
static void quilted (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal)
{
    Vector3d value;
    DBL t;

    value[X] = EPoint[X]-FLOOR(EPoint[X])-0.5;
    value[Y] = EPoint[Y]-FLOOR(EPoint[Y])-0.5;
    value[Z] = EPoint[Z]-FLOOR(EPoint[Z])-0.5;

    t = value.length();

    const QuiltedPattern *pattern = dynamic_cast<QuiltedPattern*>(Tnormal->pattern.get());
    POV_PATTERN_ASSERT(pattern);

    t = quilt_cubic(t, pattern->Control0, pattern->Control1);

    value *= t;

    normal += (DBL)Tnormal->Amount * value;
}
예제 #4
0
파일: normal.cpp 프로젝트: BentSm/povray
static void facets (const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal, TraceThreadData *Thread)
{
    int      i;
    int      thisseed;
    DBL      sum, minsum;
    Vector3d sv, tv, dv, t1, add, newnormal, pert;
    DBL      scale;
    int      UseSquare;
    int      UseUnity;
    DBL      Metric;

    const FacetsPattern *pattern = dynamic_cast<FacetsPattern*>(Tnormal->pattern.get());
    POV_PATTERN_ASSERT(pattern);

    Vector3d *cv = Thread->Facets_Cube;
    Metric = pattern->facetsMetric;

    UseSquare = (Metric == 2 );
    UseUnity  = (Metric == 1 );

    normal.normalize();

    if (pattern->facetsCoords)
    {
        tv = EPoint;
    }
    else
    {
        tv = normal;
    }

    if (pattern->facetsSize < 1e-6)
    {
        scale = 1e6;
    }
    else
    {
        scale = 1. / pattern->facetsSize;
    }

    tv *= scale;

    /*
     * Check to see if the input point is in the same unit cube as the last
     * call to this function, to use cache of cubelets for speed.
     */

    thisseed = PickInCube(tv, t1);

    if (thisseed != Thread->Facets_Last_Seed)
    {
        /*
         * No, not same unit cube.  Calculate the random points for this new
         * cube and its 80 neighbours which differ in any axis by 1 or 2.
         * Why distance of 2?  If there is 1 point in each cube, located
         * randomly, it is possible for the closest random point to be in the
         * cube 2 over, or the one two over and one up.  It is NOT possible
         * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
         * cubes glued onto each face.
         */

        /* Now store a points for this cube and each of the 80 neighbour cubes. */

        int cvc = 0;

        for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
        {
            for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
            {
                for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
                {
                    /* For each cubelet in a 5x5 cube. */

                    if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
                    {
                        /* Yes, it's within a 3d knight move away. */

                        sv = tv + add;

                        PickInCube(sv, t1);

                        cv[cvc] = t1;
                        cvc++;
                    }
                }
            }
        }

        Thread->Facets_Last_Seed = thisseed;
        Thread->Facets_CVC = cvc;
    }

    /*
     * Find the point with the shortest distance from the input point.
     */

    dv = cv[0] - tv;
    if ( UseSquare )
    {
        minsum  = dv.lengthSqr();
    }
    else if ( UseUnity )
    {
        minsum = dv[X]+dv[Y]+dv[Z];
    }
    else
    {
        minsum = pow(fabs(dv[X]), Metric)+
                 pow(fabs(dv[Y]), Metric)+
                 pow(fabs(dv[Z]), Metric);
    }

    newnormal = cv[0];

    /* Loop for the 81 cubelets to find closest. */

    for (i = 1; i < Thread->Facets_CVC; i++)
    {
        dv = cv[i] - tv;

        if ( UseSquare )
        {
            sum  = dv.lengthSqr();
        }
        else
        {
            if ( UseUnity )
            {
                sum = dv[X]+dv[Y]+dv[Z];
            }
            else
            {
                sum = pow(fabs(dv[X]), Metric)+
                      pow(fabs(dv[Y]), Metric)+
                      pow(fabs(dv[Z]), Metric);
            }
        }

        if (sum < minsum)
        {
            minsum = sum;
            newnormal = cv[i];
        }
    }

    if (pattern->facetsCoords)
    {
        DNoise( pert, newnormal );
        sum = dot(pert, normal);
        newnormal = normal * sum;
        pert -= newnormal;
        normal += pattern->facetsCoords * pert;
    }
    else
    {
        normal = newnormal;
    }
}
예제 #5
0
파일: pigment.cpp 프로젝트: gumpu/povray
bool Compute_Pigment (TransColour& colour, const PIGMENT *Pigment, const Vector3d& EPoint, const Intersection *Intersect, const Ray *ray, TraceThreadData *Thread)
{
    bool Colour_Found;
    Vector3d TPoint;
    DBL value;

    if (Thread->qualityFlags.quickColour && Pigment->Quick_Colour.IsValid())
    {
        colour = Pigment->Quick_Colour;
        return (true);
    }

    if (Pigment->Type <= LAST_SPECIAL_PATTERN)
    {
        Colour_Found = true;

        switch (Pigment->Type)
        {
            case NO_PATTERN:

                POV_PATTERN_ASSERT(false); // should have been forced to PLAIN_PATTERN in Post_Pigment
                colour.Clear();

                break;

            case PLAIN_PATTERN:

                colour = Pigment->colour;

                break;

            case AVERAGE_PATTERN:

                Warp_EPoint (TPoint, EPoint, Pigment);

                Do_Average_Pigments(colour, Pigment, TPoint, Intersect, ray, Thread);

                break;

            case UV_MAP_PATTERN:
                if(Intersect == NULL)
                    throw POV_EXCEPTION_STRING("The 'uv_mapping' pattern cannot be used as part of a pigment function!");

                Colour_Found = Pigment->Blend_Map->ComputeUVMapped(colour, Intersect, ray, Thread);
                break;

            case BITMAP_PATTERN:

                Warp_EPoint (TPoint, EPoint, Pigment);

                colour.Clear();

                Colour_Found = image_map (TPoint, Pigment, colour);

                break;

            default:

                throw POV_EXCEPTION_STRING("Pigment type not yet implemented.");
        }

        return(Colour_Found);
    }

    /* NK 19 Nov 1999 added Warp_EPoint */
    Warp_EPoint (TPoint, EPoint, Pigment);
    value = Evaluate_TPat (Pigment, TPoint, Intersect, ray, Thread);

    return Pigment->Blend_Map->Compute (colour, value, TPoint, Intersect, ray, Thread);
}
예제 #6
0
파일: pigment.cpp 프로젝트: gumpu/povray
void Post_Pigment(PIGMENT *Pigment, bool* pHasFilter)
{
    bool hasFilter;

    if (Pigment == NULL)
    {
        throw POV_EXCEPTION_STRING("Missing pigment");
    }

    if (Pigment->Flags & POST_DONE)
    {
        if ((pHasFilter != NULL) && (Pigment->Flags & HAS_FILTER))
            *pHasFilter = true;
        return;
    }

    if (Pigment->Type == NO_PATTERN)
    {
        Pigment->Type = PLAIN_PATTERN;

        Pigment->colour.Clear();

;// TODO MESSAGE    Warning(150, "No pigment type given.");
    }

    Pigment->Flags |= POST_DONE;

    switch (Pigment->Type)
    {
        case NO_PATTERN:

            POV_PATTERN_ASSERT(false); // should have been forced to PLAIN_PATTERN by now
            break;

        case PLAIN_PATTERN:
        case BITMAP_PATTERN:

            break;

        default:

            if (Pigment->Blend_Map == NULL)
            {
                switch (Pigment->Type)
                {
                    // NB: The const default blend maps are marked so that they will not be modified nor destroyed later.
                    case AVERAGE_PATTERN:
                        // TODO MESSAGE Error("Missing pigment_map in average pigment");
                        break;

                    default:
                        Pigment->Blend_Map = std::tr1::static_pointer_cast<GenericPigmentBlendMap, ColourBlendMap>(
                                                 std::tr1::const_pointer_cast<ColourBlendMap, const ColourBlendMap>(
                                                     Pigment->pattern->GetDefaultBlendMap()));
                        break;
                }
            }

            break;
    }

    /* Now we test wether this pigment is opaque or not. [DB 8/94] */

    hasFilter = false;

    if (!Pigment->colour.TransmittedColour().IsNearZero(EPSILON))
    {
        hasFilter = true;
    }

    if ((Pigment->Type == BITMAP_PATTERN) &&
        (dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage != NULL))
    {
        // bitmaps are transparent if they are used only once, or the image is not opaque
        if ((dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage->Once_Flag) || !is_image_opaque(dynamic_cast<ImagePattern*>(Pigment->pattern.get())->pImage))
            hasFilter = true;
    }

    GenericPigmentBlendMap* Map = Pigment->Blend_Map.get();

    if (Map != NULL)
    {
        Map->Post(hasFilter);
    }

    if (hasFilter)
    {
        Pigment->Flags |= HAS_FILTER;
        if (pHasFilter != NULL)
            *pHasFilter = true;
    }
}
예제 #7
0
void bump_map(const Vector3d& EPoint, const TNORMAL *Tnormal, Vector3d& normal)
{
    DBL xcoor = 0.0, ycoor = 0.0;
    int index = -1, index2 = -1, index3 = -1;
    RGBFTColour colour1, colour2, colour3;
    Vector3d p1, p2, p3;
    Vector3d bump_normal;
    Vector3d xprime, yprime, zprime;
    DBL Length;
    DBL Amount = Tnormal->Amount;
    const ImageData *image;

    if (const ImagePatternImpl *pattern = dynamic_cast<ImagePatternImpl*>(Tnormal->pattern.get()))
        image = pattern->pImage;
    else
        POV_PATTERN_ASSERT(false);

    // going to have to change this
    // need to know if bump point is off of image for all 3 points

    if(map_pos(EPoint, Tnormal->pattern.get(), &xcoor, &ycoor))
        return;
    else
        image_colour_at(image, xcoor, ycoor, colour1, &index); // TODO ALPHA - we should decide whether we prefer premultiplied or non-premultiplied alpha

    xcoor--;
    ycoor++;

    if(xcoor < 0.0)
        xcoor += (DBL)image->iwidth;
    else if(xcoor >= image->iwidth)
        xcoor -= (DBL)image->iwidth;

    if(ycoor < 0.0)
        ycoor += (DBL)image->iheight;
    else if(ycoor >= (DBL)image->iheight)
        ycoor -= (DBL)image->iheight;

    image_colour_at(image, xcoor, ycoor, colour2, &index2); // TODO ALPHA - we should decide whether we prefer premultiplied or non-premultiplied alpha

    xcoor += 2.0;

    if(xcoor < 0.0)
        xcoor += (DBL)image->iwidth;
    else if(xcoor >= image->iwidth)
        xcoor -= (DBL)image->iwidth;

    image_colour_at(image, xcoor, ycoor, colour3, &index3); // TODO ALPHA - we should decide whether we prefer premultiplied or non-premultiplied alpha

    if(image->Use || (index == -1) || (index2 == -1) || (index3 == -1))
    {
        p1[X] = 0;
        p1[Y] = Amount * colour1.Greyscale();
        p1[Z] = 0;

        p2[X] = -1;
        p2[Y] = Amount * colour2.Greyscale();
        p2[Z] = 1;

        p3[X] = 1;
        p3[Y] = Amount * colour3.Greyscale();
        p3[Z] = 1;
    }
    else
    {
        p1[X] = 0;
        p1[Y] = Amount * index;
        p1[Z] = 0;

        p2[X] = -1;
        p2[Y] = Amount * index2;
        p2[Z] = 1;

        p3[X] = 1;
        p3[Y] = Amount * index3;
        p3[Z] = 1;
    }

    // we have points 1,2,3 for a triangle now we need the surface normal for it

    xprime = p1 - p2;
    yprime = p3 - p2;
    bump_normal = cross(yprime, xprime).normalized();

    yprime = normal;
    xprime = cross(yprime, Vector3d(0.0, 1.0, 0.0));
    Length = xprime.length();

    if(Length < EPSILON)
    {
        if(fabs(normal[Y] - 1.0) < EPSILON)
        {
            yprime = Vector3d(0.0, 1.0, 0.0);
            xprime = Vector3d(1.0, 0.0, 0.0);
            Length = 1.0;
        }
        else
        {
            yprime = Vector3d(0.0,-1.0, 0.0);
            xprime = Vector3d(1.0, 0.0, 0.0);
            Length = 1.0;
        }
    }

    xprime /= Length;
    zprime = cross(xprime, yprime).normalized();
    xprime *= bump_normal[X];
    yprime *= bump_normal[Y];
    zprime *= bump_normal[Z];
    normal = xprime + yprime - zprime;
}