// // 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; } }
// // 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; }
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; }