int do_transition(actor *act){ struct CalMixer *mixer; float k; if (act==NULL) return 0; if (act->calmodel==NULL) return 0; if (act->startIdle==act->endIdle) return 0; printf("doing transition from %i to %i at %i of %i\n",act->startIdle,act->endIdle,cur_time-act->idleTime,act->idleDuration); mixer=CalModel_GetMixer(act->calmodel); k=(float)(cur_time-act->idleTime)/act->idleDuration; if(k>1.0) k=1.0; CalMixer_BlendCycle(mixer,act->startIdle,1.0-k, 0.0); CalMixer_BlendCycle(mixer,act->endIdle,k, 0.0); if(k>=1.0) { printf("transition done\n"); CalMixer_ClearCycle(mixer,act->startIdle, 0.0); act->startIdle=act->endIdle; act->idleTime=0; act->busy=0; return 1; } return 0; }
void cal_actor_set_emote_anim(actor *pActor, emote_frame *anims){ struct CalMixer *mixer; struct cal_anim *action; hash_entry *he; emote_anim *cur_emote; int i; float md=0; if (pActor==NULL||!anims) return; if (pActor->calmodel==NULL) return; mixer=CalModel_GetMixer(pActor->calmodel); cur_emote=&pActor->cur_emote; cur_emote->start_time=cur_time; cur_emote->active=1; cur_emote->nframes=anims->nframes; cur_emote->flow=anims; for(i=0;i<anims->nframes;i++) { //printf("adding frame %i: %i\n",i,anims->ids[i]); he=hash_get(actors_defs[pActor->actor_type].emote_frames,(void*)(NULL+anims->ids[i])); if(!he) continue; action = (struct cal_anim*) he->item; //printf("duration scale %f\n",action->duration_scale); cur_emote->frames[i]=*action; if (action->kind==cycle){ //handle cycles: //removes previous emote cycles if(cur_emote->idle.anim_index>=0) CalMixer_ClearCycle(mixer,cur_emote->idle.anim_index, cal_cycle_blending_delay); //removes previous idle cycles if(pActor->cur_anim.kind==cycle) { CalMixer_ClearCycle(mixer,pActor->cur_anim.anim_index, cal_cycle_blending_delay); pActor->cur_anim.anim_index=-1; } CalMixer_BlendCycle(mixer,action->anim_index,1.0f, cal_cycle_blending_delay); CalMixer_SetAnimationTime(mixer, 0.0f); cur_emote->idle=*action; } else { CalMixer_ExecuteAction_Stop(mixer,action->anim_index,0,0); md=(action->duration/action->duration_scale>md) ? (action->duration*1000.0/action->duration_scale):(md); #ifdef NEW_SOUND if (action->sound>-1) cal_play_anim_sound(pActor, *action,1); #endif } } cur_emote->max_duration=(int)md; //printf("EMOTE: start: %i, end: %i, dur: %i\n", cur_emote->start_time, cur_emote->start_time+cur_emote->max_duration,cur_emote->max_duration); }
int set_idle(char *text, int len){ int j,x; char *id; actor *act=NULL; for(j=1;j<len;j++) if(text[j]==' ') {text[j]=0; break;} id=&text[j+1]; x=j; text++; printf("Actor [%s] [%s]\n",text,id); LOCK_ACTORS_LISTS(); for (j = 0; j < max_actors; j++){ if (!strncasecmp(actors_list[j]->actor_name, text, strlen(text)) && (actors_list[j]->actor_name[strlen(text)] == ' ' || actors_list[j]->actor_name[strlen(text)] == '\0')){ struct CalMixer *mixer; act = actors_list[j]; mixer=CalModel_GetMixer(act->calmodel); LOG_TO_CONSOLE(c_orange1, "actor found, adding anims"); printf("actor found\n"); CalMixer_ClearCycle(mixer,act->cur_anim.anim_index, 0.0f); while(*id){ int anim_id; double anim_wg; anim_id=atoi(id); id++; while(*id!=' '&&*id!=0) id++; anim_wg=atof(id); id++; while(*id!=' '&&*id!=0) id++; printf("setting anim %i with weight %f\n",anim_id,anim_wg); if(anim_wg<0) CalMixer_ClearCycle(mixer,actors_defs[act->actor_type].cal_frames[anim_id].anim_index, 0.0f); else CalMixer_BlendCycle(mixer,actors_defs[act->actor_type].cal_frames[anim_id].anim_index,anim_wg, 0.1f); } printf("command added %s\n",id); } } if (!act){ UNLOCK_ACTORS_LISTS(); LOG_TO_CONSOLE(c_orange1, "actor not found"); return 1; } UNLOCK_ACTORS_LISTS(); text[x-1]=' '; return 1; }
void cal_actor_set_anim_delay(int id, struct cal_anim anim, float delay) { actor *pActor = actors_list[id]; struct CalMixer *mixer; int i; //char str[255]; //sprintf(str, "actor:%d anim:%d type:%d delay:%f\0",id,anim.anim_index,anim.kind,delay); //LOG_TO_CONSOLE(c_green2,str); if (pActor==NULL) return; if (pActor->calmodel==NULL) return; if (pActor->cur_anim.anim_index==anim.anim_index) return; //this shouldnt happend but its happends if actor doesnt have //animation so we add this workaround to prevent "freezing" if(anim.anim_index==-1){ attachment_props *att_props; if( pActor->sitting==1 ){ //we dont have sittng anim so cancel it pActor->sitting=0; } pActor->stop_animation=0; att_props = get_attachment_props_if_held(pActor); if (att_props) { anim.anim_index = att_props->cal_frames[cal_attached_idle_frame].anim_index; anim.duration = att_props->cal_frames[cal_attached_idle_frame].duration; anim.duration_scale = att_props->cal_frames[cal_attached_idle_frame].duration_scale; } else { anim.anim_index = actors_defs[pActor->actor_type].cal_frames[cal_actor_idle1_frame].anim_index; anim.duration = actors_defs[pActor->actor_type].cal_frames[cal_actor_idle1_frame].duration; anim.duration_scale = actors_defs[pActor->actor_type].cal_frames[cal_actor_idle1_frame].duration_scale; } anim.kind = cycle; } mixer=CalModel_GetMixer(pActor->calmodel); //Stop previous animation if needed if (pActor->IsOnIdle!=1 && (pActor->cur_anim.anim_index!=-1)) { if (pActor->cur_anim.kind==cycle) { //little more smooth delay+=cal_cycle_blending_delay; CalMixer_ClearCycle(mixer,pActor->cur_anim.anim_index, delay); } if (pActor->cur_anim.kind==action) { CalMixer_RemoveAction(mixer,pActor->cur_anim.anim_index); //change from action to new action or cycle should be smooth if(anim.duration>0.0f) delay=anim.duration; else delay+=cal_action_blending_delay; } }else{ //we starting from unkown state (prev anim == -1) //so we add some delay to blend into new state if(anim.duration>0.0f) delay=anim.duration; else delay+=cal_action_blending_delay; } //seems to be unusable - groups are always empty??? if (pActor->IsOnIdle==1) { for (i=0;i<actors_defs[pActor->actor_type].group_count;++i) { CalMixer_ClearCycle(mixer,pActor->cur_idle_anims[i].anim_index, delay); } } if (anim.kind==cycle){ CalMixer_BlendCycle(mixer,anim.anim_index,1.0f, delay); CalMixer_SetAnimationTime(mixer, 0.0f); //always start at the beginning of a cycling animation //if an emote is cycling, stop it if(pActor->cur_emote.idle.anim_index!=-1) { //printf("stopping idle emote %i\n", pActor->cur_emote.idle.anim_index); CalMixer_ClearCycle(mixer,pActor->cur_emote.idle.anim_index,0); pActor->cur_emote.idle.anim_index=-1; } /* //if an emote is playing, stop it if(pActor->cur_emote.active) { printf("stopping emote of actor %i\n", pActor->actor_id); cal_reset_emote_anims(pActor,0); pActor->cur_emote.flow=NULL; } */ } else { CalMixer_ExecuteAction_Stop(mixer,anim.anim_index,delay,0.0); //if an emote is playing, stop it /* if(pActor->cur_emote.active) { printf("stopping emote of actor %i\n", pActor->actor_id); cal_reset_emote_anims(pActor,0); pActor->cur_emote.flow=NULL; } */ } pActor->cur_anim=anim; pActor->anim_time=0.0; pActor->last_anim_update= cur_time; pActor->stop_animation = anim.kind; CalModel_Update(pActor->calmodel,0.0001);//Make changes take effect now build_actor_bounding_box(pActor); missiles_rotate_actor_bones(pActor); if (use_animation_program) { set_transformation_buffers(pActor); } if (pActor->cur_anim.anim_index==-1) pActor->busy=0; pActor->IsOnIdle=0; #ifdef NEW_SOUND cal_play_anim_sound(pActor, pActor->cur_anim,0); #endif }