Ejemplo n.º 1
0
    void updateDecorations(Surface &suf, MaterialAnimator &matAnimator,
        Vector2f const &materialOrigin, Vector3d const &topLeft,
        Vector3d const &bottomRight, Sector *containingSector = nullptr)
    {
        Vector3d delta = bottomRight - topLeft;
        if(de::fequal(delta.length(), 0)) return;

        Material &material = matAnimator.material();
        int const axis = suf.normal().maxAxis();

        Vector2d sufDimensions;
        if(axis == 0 || axis == 1)
        {
            sufDimensions.x = std::sqrt(de::squared(delta.x) + de::squared(delta.y));
            sufDimensions.y = delta.z;
        }
        else
        {
            sufDimensions.x = std::sqrt(de::squared(delta.x));
            sufDimensions.y = delta.y;
        }

        if(sufDimensions.x < 0) sufDimensions.x = -sufDimensions.x;
        if(sufDimensions.y < 0) sufDimensions.y = -sufDimensions.y;

        // Generate a number of decorations.
        int decorIndex = 0;

        material.forAllDecorations([&suf, &matAnimator, &materialOrigin
                                   , &topLeft, &bottomRight, &containingSector
                                   , &delta, &axis, &sufDimensions, &decorIndex]
                                   (MaterialDecoration &decor)
        {
            Vector2i const &matDimensions               = matAnimator.material().dimensions();
            MaterialAnimator::Decoration const &decorSS = matAnimator.decoration(decorIndex);

            // Skip values must be at least one.
            Vector2i skip = Vector2i(decor.patternSkip().x + 1, decor.patternSkip().y + 1)
                                .max(Vector2i(1, 1));

            Vector2f repeat = matDimensions * skip;
            if(repeat == Vector2f(0, 0))
                return LoopAbort;

            Vector3d origin = topLeft + suf.normal() * decorSS.elevation();

            float s = de::wrap(decorSS.origin().x - matDimensions.x * decor.patternOffset().x + materialOrigin.x,
                               0.f, repeat.x);

            // Plot decorations.
            for(; s < sufDimensions.x; s += repeat.x)
            {
                // Determine the topmost point for this row.
                float t = de::wrap(decorSS.origin().y - matDimensions.y * decor.patternOffset().y + materialOrigin.y,
                                   0.f, repeat.y);

                for(; t < sufDimensions.y; t += repeat.y)
                {
                    float const offS = s / sufDimensions.x;
                    float const offT = t / sufDimensions.y;
                    Vector3d patternOffset(offS, axis == VZ? offT : offS, axis == VZ? offS : offT);

                    Vector3d decorOrigin     = origin + delta * patternOffset;
                    ConvexSubspace *subspace = suf.map().bspLeafAt(decorOrigin).subspacePtr();

                    if(!subspace) continue;
                    if(!subspace->contains(decorOrigin)) continue;

                    if(containingSector)
                    {
                        // The point must be in the correct sector.
                        if(containingSector != &subspace->sector())
                            continue;
                    }

                    suf.addDecoration(new LightDecoration(decorSS, decorOrigin));
                }
            }

            decorIndex += 1;
            return LoopContinue;
        });
    }
Ejemplo n.º 2
0
 void materialAnimatorDecorationStageChanged(MaterialAnimator &animator)
 {
     markSurfacesForRedecoration(animator.material());
 }