예제 #1
0
void MusicEffect::RenderMorph(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, std::list<MusicEvent*>& events, int colourTreatment, bool bounce, bool fade)
{
    bool up = true;
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        up = !up;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);

            int length = buffer.BufferHt;
            int start = -1 * length + progress * 2 * length + 1;
            int end = start + length;

            for (int y = std::max(0, start); y < std::min(end, buffer.BufferHt); y++)
            {
                xlColor c = xlWHITE;
                float proportion = ((float)end - (float)y) / (float)length;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = (1.0 -proportion) * 255;
                }

                if (up || !bounce)
                {
                    buffer.SetPixel(x, y, c);
                }
                else
                {
                    buffer.SetPixel(x, buffer.BufferHt - y - 1, c);
                }
            }
        }
    }
}
예제 #2
0
void MusicEffect::RenderOn(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, std::list<MusicEvent*>& events, int colourTreatment, bool fade)
{
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);


            for (int y = 0; y < buffer.BufferHt; y++)
            {
                xlColor c = xlWHITE;
                float proportion = (float)y / (float)buffer.BufferHt;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = (1.0 - progress) * 255;
                }

                buffer.SetPixel(x, y, c);
            }
        }
    }
}
예제 #3
0
void MusicEffect::RenderCollide(RenderBuffer &buffer, int x, int bars, int startNote, int endNote, bool in, std::list<MusicEvent*>& events, int colourTreatment, bool fade)
{
    int event = -1;
    for (auto it = events.begin(); it != events.end(); ++it)
    {
        event++;
        if ((*it)->IsEventActive(buffer.curPeriod))
        {
            float progress = (*it)->OffsetInDuration(buffer.curPeriod);

            int mid = buffer.BufferHt / 2;
            int length = buffer.BufferHt;
            int leftstart, leftend;

            if (!in)
            {
                progress = 1.0 - progress;
            }

            leftstart = 0 - mid - 1 + progress * length;
            leftend = leftstart + mid;
            if (leftend > mid)
            {
                leftend = mid;
            }

            int loopstart = leftstart;
            if (loopstart < 0)
            {
                loopstart = 0;
            }

            for (int y = loopstart; y < leftend; y++)
            {
                xlColor c = xlWHITE;
                float proportion = ((float)y - (float)leftstart) / (float)mid;
                if (colourTreatment == 1)
                {
                    // distinct
                    float percolour = 1.0 / (float)buffer.GetColorCount();
                    for (int i = 0; i < buffer.GetColorCount(); i++)
                    {
                        if (proportion <= ((float)i + 1.0)*percolour)
                        {
                            buffer.palette.GetColor(i, c);
                            break;
                        }
                    }
                }
                else if (colourTreatment == 2)
                {
                    // blend
                    buffer.GetMultiColorBlend(proportion, false, c);
                }
                else if (colourTreatment == 3)
                {
                    buffer.palette.GetColor(event % buffer.GetColorCount(), c);
                }

                if (fade)
                {
                    c.alpha = progress * 255;
                }

                buffer.SetPixel(x, y, c);
                buffer.SetPixel(x, mid - y + mid - 1, c);
            }
        }
    }
}
예제 #4
0
void GarlandsEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    int GarlandType = SettingsMap.GetInt("SLIDER_Garlands_Type", 0);
    int Spacing = SettingsMap.GetInt("SLIDER_Garlands_Spacing", 0);
    float cycles = SettingsMap.GetDouble("TEXTCTRL_Garlands_Cycles", 1.0);

    if (Spacing < 1) {
        Spacing = 1;
    }
    int x,y,yadj,ylimit,ring;
    double ratio;
    xlColor color;
    int dir = GetDirection(SettingsMap.Get("CHOICE_Garlands_Direction", "Up"));
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    if (dir > 3) {
        dir -= 4;
        if (position > 0.5) {
            position = (1.0 - position) * 2.0;
        } else {
            position *= 2.0;
        }
    }
    int buffMax = buffer.BufferHt;
    int garlandWid = buffer.BufferWi;
    if (dir > 1) {
        buffMax = buffer.BufferWi;
        garlandWid = buffer.BufferHt;
    }
    double PixelSpacing=Spacing*buffMax/100.0;
    if (PixelSpacing < 2.0) PixelSpacing=2.0;


    double total = buffMax * PixelSpacing - buffMax + 1;
    double positionOffset = total * position;

    for (ring = 0; ring < buffMax; ring++)
    {
        ratio=double(buffMax-ring-1)/double(buffMax);
        buffer.GetMultiColorBlend(ratio, false, color);

        y = 1.0 + ring*PixelSpacing - positionOffset;


        ylimit=ring;
        for (x=0; x<garlandWid; x++)
        {
            yadj=y;
            switch (GarlandType)
            {
            case 1:
                switch (x%5)
                {
                case 2:
                    yadj-=2;
                    break;
                case 1:
                case 3:
                    yadj-=1;
                    break;
                }
                break;
            case 2:
                switch (x%5)
                {
                case 2:
                    yadj-=4;
                    break;
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            case 3:
                switch (x%6)
                {
                case 3:
                    yadj-=6;
                    break;
                case 2:
                case 4:
                    yadj-=4;
                    break;
                case 1:
                case 5:
                    yadj-=2;
                    break;
                }
                break;
            case 4:
                switch (x%5)
                {
                case 1:
                case 3:
                    yadj-=2;
                    break;
                }
                break;
            }
            if (yadj < ylimit) yadj=ylimit;
            if (yadj < buffMax) {
                if (dir == 1 || dir == 2) {
                    yadj = buffMax - yadj - 1;
                }
                if (dir > 1) {
                    buffer.SetPixel(yadj,x,color);
                } else {
                    buffer.SetPixel(x,yadj,color);
                }
            }
        }
    }
}
예제 #5
0
void StateEffect::RenderState(RenderBuffer &buffer,
                             SequenceElements *elements, const std::string &faceDefinition,
                             const std::string& Phoneme, const std::string &trackName, const std::string& mode, const std::string& colourmode)
{
    if (buffer.needToInit) {
        buffer.needToInit = false;
        elements->AddRenderDependency(trackName, buffer.cur_model);
    
        if (buffer.isTransformed)
        {
            log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
            logger_base.warn("State effect starting at %dms until %dms on model %s has a transformed buffer. This may not work as expected.", buffer.curEffStartPer * buffer.frameTimeInMs, buffer.curEffEndPer * buffer.frameTimeInMs, (const char *)buffer.cur_model.c_str());
        }
    }

    Element *track = elements->GetElement(trackName);
    std::recursive_mutex tmpLock;
    std::recursive_mutex *lock = &tmpLock;
    if (track != nullptr) {
        lock = &track->GetChangeLock();
    }
    std::unique_lock<std::recursive_mutex> locker(*lock);

    if (buffer.cur_model == "") {
        return;
    }

    Model* model_info = buffer.frame->AllModels[buffer.cur_model];
    if (model_info == nullptr) {
        return;
    }

    std::string definition = faceDefinition;
    bool found = true;
    std::map<std::string, std::map<std::string, std::string> >::iterator it = model_info->stateInfo.find(definition);
    if (it == model_info->stateInfo.end()) {
        //not found
        found = false;
    }
    if (!found) {
        if ("Coro" == definition && model_info->stateInfo.find("SingleNode") != model_info->stateInfo.end()) {
            definition = "SingleNode";
            found = true;
        } else if ("SingleNode" == definition && model_info->stateInfo.find("Coro") != model_info->stateInfo.end()) {
            definition = "Coro";
            found = true;
        }
    }

    if (definition == "")
    {
        return;
    }

    std::string modelType = found ? model_info->stateInfo[definition]["Type"] : definition;
    if (modelType == "") {
        modelType = definition;
    }

    int type = 1;

    if ("SingleNode" == modelType) {
        type = 0;
    } else if ("NodeRange" == modelType) {
        type = 1;
    }

    std::string tstates = Phoneme;
    int intervalnumber = 0;
    //GET label from timing track
    int startms = -1;
    int endms = -1;
    int posms = -1;
    if (tstates == "") {

        // if we dont have a track then exit
        if (track == NULL)
        {
            return;
        }

        EffectLayer *layer = track->GetEffectLayer(0);
        std::unique_lock<std::recursive_mutex> locker(layer->GetLock());
        int time = buffer.curPeriod * buffer.frameTimeInMs + 1;
        posms = buffer.curPeriod * buffer.frameTimeInMs;
        Effect *ef = layer->GetEffectByTime(time);
        if (ef == nullptr) {
            tstates = "";
        }
        else {
            startms = ef->GetStartTimeMS();
            endms = ef->GetEndTimeMS();
            tstates = ef->GetEffectName();
        }

        ef = layer->GetEffectByTime(buffer.curEffStartPer * buffer.frameTimeInMs + 1);
        while (ef != NULL && ef->GetStartTimeMS() <= time)
        {
            intervalnumber++;
            int endtime = ef->GetEndTimeMS();
            ef = layer->GetEffectByTime(endtime + 1);
            if (ef == NULL)
            {
                ef = layer->GetEffectAfterTime(endtime + 1);
            }
        }
    }

    std::vector<std::string> sstates;

    if (mode == "Default" || startms == -1)
    {
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            sstates.push_back(token.Lower().ToStdString());
        }
    }
    else if (mode == "Countdown")
    {
        // tstates should contain the starting number
        int val = wxAtoi(tstates);

        val = val * 1000;
        int subtracttime = (posms - startms);
        val = val - subtracttime;
        val = val / 1000;

        int v = val;
        bool force = false;
        if ((v / 1000) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 1000) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 1000) * 1000;
        if ((v / 100) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 100).ToStdString());
            force = true;
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 10).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("00");
            }
        }
        v = v - (v / 10) * 10;
        sstates.push_back(wxString::Format("%d", v).ToStdString());
    }
    else if (mode == "Time Countdown")
    {
        wxDateTime dt;
        dt.ParseFormat(tstates.c_str(), "%H:%M:%S");

        if (!dt.IsValid())
        {
            dt.ParseFormat(tstates.c_str(), "%M:%S");
        }

        if (dt.IsValid())
        {
            dt.Subtract(wxTimeSpan(0, 0, 0, (buffer.curPeriod - buffer.curEffStartPer) * buffer.frameTimeInMs));
            int m = dt.GetMinute();
            if ((m / 10) * 1000 > 0)
            {
                sstates.push_back(wxString::Format("%d", (m / 10) * 1000).ToStdString());
            }
            else
            {
                sstates.push_back("0000");
            }
            m = m - (m / 10) * 10;
            if (m * 100 > 0)
            {
                sstates.push_back(wxString::Format("%d", m * 100).ToStdString());
            }
            else
            {
                sstates.push_back("000");
            }
            int s = dt.GetSecond();
            if ((s / 10) * 10 > 0)
            {
                sstates.push_back(wxString::Format("%d", (s / 10) * 10).ToStdString());
            }
            else
            {
                sstates.push_back("00");
            }
            s = s - (s / 10) * 10;
            sstates.push_back(wxString::Format("%d", s).ToStdString());
        }
        sstates.push_back("colon");
    }
    else if (mode == "Number") // used for FM frequencies
    {
        double f = wxAtof(tstates);
        sstates.push_back("dot");
        double f2 = f - int(f);
        f2 = (int)(f2 * 10 + 0.5);
        sstates.push_back(wxString::Format("%d", (int)f2).ToStdString());

        int v = f;
        bool force = false;
        if ((v / 100) * 1000 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 100) * 1000).ToStdString());
            force = true;
        }
        v = v - (v / 100) * 100;
        if ((v / 10) * 100 > 0)
        {
            sstates.push_back(wxString::Format("%d", (v / 10) * 100).ToStdString());
        }
        else
        {
            if (force)
            {
                sstates.push_back("000");
            }
        }
        v = v - (v / 10) * 10;
        if (v * 10 > 0)
        {
            sstates.push_back(wxString::Format("%d", v * 10).ToStdString());
        }
        else
        {
            sstates.push_back("00");
        }
    }
    else if (mode == "Iterate")
    {
        float progressthroughtimeinterval = ((float)posms - (float)startms) / ((float)endms - (float)startms);

        std::vector<std::string> tmpstates;
        wxString ss = wxString(tstates);
        wxStringTokenizer tkz(ss, wxT(" ,;:"));
        while (tkz.HasMoreTokens())
        {
            wxString token = tkz.GetNextToken();
            tmpstates.push_back(token.Lower().ToStdString());
        }

        int which = tmpstates.size() * progressthroughtimeinterval;

        if (which < sstates.size())
        {
            sstates.push_back(tmpstates[which]);
        }
    }

    bool customColor = found ? model_info->stateInfo[definition]["CustomColors"] == "1" : false;

    // process each token
    for (size_t i = 0; i < sstates.size(); i++)
    {
        // get the channels
        std::string statename = FindState(model_info->stateInfo[definition], sstates[i]);
        std::string channels = model_info->stateInfo[definition][statename];

        if (statename != "" && channels != "")
        {
            xlColor color;
            if (colourmode == "Graduate")
            {
                buffer.GetMultiColorBlend(buffer.GetEffectTimeIntervalPosition(), false, color);
            }
            else if (colourmode == "Cycle")
            {
                buffer.palette.GetColor((intervalnumber - 1) % buffer.GetColorCount(), color);
            }
            else
            {
                // allocate
                int statenum = wxAtoi(statename.substr(1));
                buffer.palette.GetColor((statenum - 1) % buffer.GetColorCount(), color);
            }
            if (customColor) {
                std::string cname = model_info->stateInfo[definition][statename + "-Color"];
                if (cname == "") {
                    color = xlWHITE;
                }
                else {
                    color = xlColor(cname);
                }
            }

            wxStringTokenizer wtkz(channels, ",");
            while (wtkz.HasMoreTokens())
            {
                wxString valstr = wtkz.GetNextToken();

                if (type == 0) {
                    for (size_t n = 0; n < model_info->GetNodeCount(); n++) {
                        wxString nn = model_info->GetNodeName(n, true);
                        if (nn == valstr) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
                else if (type == 1) {
                    int start, end;
                    if (valstr.Contains("-")) {
                        int idx = valstr.Index('-');
                        start = wxAtoi(valstr.Left(idx));
                        end = wxAtoi(valstr.Right(valstr.size() - idx - 1));
                    }
                    else {
                        start = end = wxAtoi(valstr);
                    }
                    if (start > end) {
                        start = end;
                    }
                    start--;
                    end--;
                    for (int n = start; n <= end; n++) {
                        if (n < buffer.Nodes.size()) {
                            for (auto a = buffer.Nodes[n]->Coords.begin() ; a != buffer.Nodes[n]->Coords.end(); a++) {
                                buffer.SetPixel(a->bufX, a->bufY, color);
                            }
                        }
                    }
                }
            }
        }
    }
}
예제 #6
0
void ColorWashEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) {
    bool HorizFade = SettingsMap.GetBool(CHECKBOX_ColorWash_HFade);
    bool VertFade = SettingsMap.GetBool(CHECKBOX_ColorWash_VFade);
    float cycles = SettingsMap.GetDouble(TEXTCTRL_ColorWash_Cycles, 1.0);
    bool EntireModel = SettingsMap.GetInt(CHECKBOX_ColorWash_EntireModel, 1);
    int x1 = SettingsMap.GetInt(SLIDER_ColorWash_X1, -50);
    int y1 = SettingsMap.GetInt(SLIDER_ColorWash_Y1, -50);
    int x2 = SettingsMap.GetInt(SLIDER_ColorWash_X2, 50);
    int y2 = SettingsMap.GetInt(SLIDER_ColorWash_Y2, 50);
    bool shimmer = SettingsMap.GetInt(CHECKBOX_ColorWash_Shimmer, 0);
    bool circularPalette = SettingsMap.GetInt(CHECKBOX_ColorWash_CircularPalette, 0);
    
    
    int x,y;
    xlColor color, orig;
    
    double position = buffer.GetEffectTimeIntervalPosition(cycles);
    buffer.GetMultiColorBlend(position, circularPalette, color);
    
    int startX = 0;
    int startY = 0;
    int endX = buffer.BufferWi - 1;
    int endY = buffer.BufferHt - 1;
    
    if (!EntireModel) {
        startX = std::min(x1, x2);
        endX = std::max(x1, x2);
        startY = std::min(y1, y2);
        endY = std::max(y1, y2);
        startX = std::round(double(buffer.BufferWi - 0.5) * (double)startX / 100.0);
        endX = std::round(double(buffer.BufferWi - 0.5) * (double)endX / 100.0);
        startY = std::round(double(buffer.BufferHt - 0.5) * (double)startY / 100.0);
        endY = std::round(double(buffer.BufferHt - 0.5) * (double)endY / 100.0);
        startX = std::max(startX, 0);
        endX = std::min(endX, buffer.BufferWi - 1);
        startY = std::max(startY, 0);
        endY = std::min(endY, buffer.BufferHt - 1);
    }
    int tot = buffer.curPeriod - buffer.curEffStartPer;
    if (!shimmer || (tot % 2) == 0) {
        double HalfHt=double(endY - startY)/2.0;
        double HalfWi=double(endX - startX)/2.0;
        
        orig = color;
        HSVValue hsvOrig = color.asHSV();
        xlColor color2 = color;
        for (x=startX; x <= endX; x++)
        {
            HSVValue hsv = hsvOrig;
            if (HorizFade) {
                if (buffer.allowAlpha) {
                    color.alpha = (double)orig.alpha*(1.0-std::abs(HalfWi-x-startX)/HalfWi);
                } else {
                    hsv.value*=1.0-std::abs(HalfWi-x-startX)/HalfWi;
                    color = hsv;
                }
            }
            color2.alpha = color.alpha;
            for (y=startY; y<=endY; y++) {
                if (VertFade) {
                    if (buffer.allowAlpha) {
                        color.alpha = (double)color2.alpha*(1.0-std::abs(HalfHt-(y-startY))/HalfHt);
                    } else {
                        HSVValue hsv2 = hsv;
                        hsv2.value*=1.0-std::abs(HalfHt-(y-startY))/HalfHt;
                        color = hsv2;
                    }
                }
                buffer.SetPixel(x, y, color);
            }
        }
    } else {
        orig = xlBLACK;
    }
    wxMutexLocker lock(effect->GetBackgroundDisplayList().lock);
    if (VertFade || HorizFade) {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4 * 2);
        int total = buffer.curEffEndPer - buffer.curEffStartPer + 1;
        double x1 = double(buffer.curPeriod - buffer.curEffStartPer) / double(total);
        double x2 = (buffer.curPeriod - buffer.curEffStartPer + 1.0) / double(total);
        int idx = (buffer.curPeriod - buffer.curEffStartPer) * 8;
        buffer.SetDisplayListVRect(effect, idx, x1, 0.0, x2, 0.5,
                                   xlBLACK, orig);
        buffer.SetDisplayListVRect(effect, idx + 4, x1, 0.5, x2, 1.0,
                                   orig, xlBLACK);
    } else {
        effect->GetBackgroundDisplayList().resize((buffer.curEffEndPer - buffer.curEffStartPer + 1) * 4);
        int midX = (startX + endX) / 2;
        int midY = (startY + endY) / 2;
        buffer.CopyPixelsToDisplayListX(effect, midY, midX, midX);
    }

}