Exemplo n.º 1
0
//
// CONVERT NODE SEGMENT BRANCH
// we're now in the middle of converting a segment
// every node gets an animation channel for the time period in question
//
//
bool plAnimAvatarComponent::ConvertNodeSegmentBranch(plMaxNode *node, plAGAnim *mod, plErrorMsg *pErrMsg)
{
    // Check for a suppression marker
    plNotetrackAnim noteAnim(node, pErrMsg);
    plAnimInfo info = noteAnim.GetAnimInfo(plString::Null);
    bool suppressed = info.IsSuppressed(mod->GetName());

    // Get the affine parts and the TM Controller
    plSceneObject *obj = node->GetSceneObject();
    if(obj && !suppressed) {
        hsAffineParts parts;
        hsControlConverter::Instance().ReduceKeys(node->GetTMController(), node->GetKeyReduceThreshold());
        plController* tmc = hsControlConverter::Instance().ConvertTMAnim(obj, node, &parts, mod->GetStart(), mod->GetEnd());
        
        if (tmc)
        {
            plMatrixChannel *channel;
            hsMatrix44 constSetting;
            parts.ComposeMatrix(&constSetting);

            // If all our keys match, there's no point in keeping an animation controller
            // around. Just nuke it and replace it with a constant channel.
            if (tmc->PurgeRedundantSubcontrollers())
            {
                channel = new plMatrixConstant(constSetting);
                delete tmc;
                tmc = nil;
            }
            else
            {
                channel = new plMatrixControllerChannel(tmc, &parts);
            }
            plMatrixChannelApplicator *app = new plMatrixChannelApplicator();
            app->SetChannelName(node->GetKey()->GetName());
            app->SetChannel(channel);
            mod->AddApplicator(app);
        }

        // let's see if the children have any segments specified...
        int childCount = node->NumberOfChildren();
        for (int i = 0; i < childCount; i++)
            ConvertNodeSegmentBranch((plMaxNode *)(node->GetChildNode(i)), mod, pErrMsg);

        return true;
    } else {
        return false;
    }
}
Exemplo n.º 2
0
//
// CONVERTNODE
// look for all the segments on this node and convert them
// recurse on children
//
//
bool plAnimAvatarComponent::ConvertNode(plMaxNode *node, plErrorMsg *pErrMsg)
{
    plNotetrackAnim noteAnim(node, pErrMsg);
    // does this node have any segments specified?
    if (noteAnim.HasNotetracks())
    {
        // for each segment we found:
        plString animName;
        while (!(animName = noteAnim.GetNextAnimName()).IsNull())
        {
            plAnimInfo info = noteAnim.GetAnimInfo(animName);

            plATCAnim *anim = NewAnimation(info.GetAnimName(), info.GetAnimStart(), info.GetAnimEnd());

            plString loopName = info.GetNextLoopName();
            if (!loopName.IsNull())
            {
                anim->SetLoop(true);
                float loopStart = info.GetLoopStart(loopName);
                float loopEnd = info.GetLoopEnd(loopName);
                anim->SetLoopStart(loopStart == -1 ? anim->GetStart() : loopStart);
                anim->SetLoopEnd(loopEnd == -1 ? anim->GetEnd() : loopEnd);
            }
            plString marker;
            while (!(marker = info.GetNextMarkerName()).IsNull())
                anim->AddMarker(marker, info.GetMarkerTime(marker));

            ConvertNodeSegmentBranch(node, anim, pErrMsg);
            MakePersistent(node, anim, info.GetAnimName(), pErrMsg);
        }
    }

    // let's see if the children have any segments specified...
    int childCount = node->NumberOfChildren();
    for (int i = 0; i < childCount; i++)
        ConvertNode((plMaxNode *)(node->GetChildNode(i)), pErrMsg);

    return true;
}
Exemplo n.º 3
0
bool plAnimComponentBase::PreConvert(plMaxNode *node, plErrorMsg *pErrMsg)
{
    // If this is the first time in the preconvert, reset the map
    if (fNeedReset)
    {
        fNeedReset = false;
    }

    // If this node is animated, create it's modifier and key now so we can give
    // it out to anyone that needs it
//  if (node->IsTMAnimated() || node->IsAnimatedLight())
//  {
        const char *name = node->GetName();

        plAGMasterMod *mod = node->GetAGMasterMod();
        if (mod == nil)
        {
            if (!node->HasAGMod()) // Need to add this before the MasterMod, if it doesn't have one already.
            {
                node->AddModifier(new plAGModifier(ST::string::from_utf8(node->GetName())), IGetUniqueName(node));
            }
            mod = new plAGMasterMod();

            plKey modKey = node->AddModifier(mod, IGetUniqueName(node));
        }
        fMods[node] = mod;
//  }


    // Small change here. We're setting up the timing specs on the
    // plAGAnim object during preconvert, so that the info is available
    // when actually converting the anim (and for other components
    // that need it, but may or may not actually convert before us.)

    // Note: if the component uses the "(Entire Animation)" segment for
    // the main start/end, the start/end times won't be valid until
    // we've added all keys during convert. Some cleanup might
    // be necessary in this case.

    ST::string animName = ST::string::from_utf8(fCompPB->GetStr(kAnimName));
    if (animName.is_empty())
        animName = ST_LITERAL(ENTIRE_ANIMATION_NAME);

    if (fCompPB->GetInt(ParamID(kAnimUseGlobal)))
    {
        plAgeGlobalAnim *ageAnim = new plAgeGlobalAnim(animName, 0, 0);
        ageAnim->SetGlobalVarName((char*)fCompPB->GetStr(ParamID(kAnimGlobalName)));

        fAnims[node] = ageAnim;
    }
    else
    {
        plATCAnim *ATCAnim = new plATCAnim(animName, 0, 0);
        plNotetrackAnim noteAnim(node, pErrMsg);
        plAnimInfo info = noteAnim.GetAnimInfo(animName);
        ATCAnim->SetAutoStart(fCompPB->GetInt(kAnimAutoStart));

        float start = info.GetAnimStart();
        float end = info.GetAnimEnd();
        float initial = info.GetAnimInitial();
        if (start != -1)
            ATCAnim->SetStart(start);
        if (end != -1)
            ATCAnim->SetEnd(end);
        if (initial != -1)
            ATCAnim->SetInitial(initial);
    
        if (fCompPB->GetInt(kAnimLoop))
        {
            ATCAnim->SetLoop(true);
            ST::string loopName = ST::string::from_utf8(fCompPB->GetStr(kAnimLoopName));
            float loopStart = info.GetLoopStart(loopName);
            float loopEnd = info.GetLoopEnd(loopName);

            ATCAnim->SetLoopStart(loopStart == -1 ? ATCAnim->GetStart() : loopStart);
            ATCAnim->SetLoopEnd(loopEnd == -1 ? ATCAnim->GetEnd() : loopEnd);
        }
    
        ST::string loop;
        while (!(loop = info.GetNextLoopName()).is_empty())
            ATCAnim->AddLoop(loop, info.GetLoopStart(loop), info.GetLoopEnd(loop));

        ST::string marker;
        while (!(marker = info.GetNextMarkerName()).is_empty())
            ATCAnim->AddMarker(marker, info.GetMarkerTime(marker));

        float stopPoint = -1;
        while ((stopPoint = info.GetNextStopPoint()) != -1)
            ATCAnim->AddStopPoint(stopPoint);

        ATCAnim->SetEaseInType(fCompPB->GetInt(kAnimEaseInType));
        ATCAnim->SetEaseOutType(fCompPB->GetInt(kAnimEaseOutType));
        ATCAnim->SetEaseInLength(fCompPB->GetFloat(kAnimEaseInLength));
        ATCAnim->SetEaseInMin(fCompPB->GetFloat(kAnimEaseInMin));
        ATCAnim->SetEaseInMax(fCompPB->GetFloat(kAnimEaseInMax));
        ATCAnim->SetEaseOutLength(fCompPB->GetFloat(kAnimEaseOutLength));
        ATCAnim->SetEaseOutMin(fCompPB->GetFloat(kAnimEaseOutMin));
        ATCAnim->SetEaseOutMax(fCompPB->GetFloat(kAnimEaseOutMax));

        fAnims[node] = ATCAnim;
    }
    return true;
}