void Animation::SetPartKeyFrame(Part *part, const KeyFrame &keyFrame) { PartKeyFrames *partKeyFrames = GetPartKeyFrames(part); if (!partKeyFrames) { AddPartKeyFrames(PartKeyFrames(part)); partKeyFrames = GetPartKeyFrames(part); } if (partKeyFrames) { partKeyFrames->InsertKeyFrame(keyFrame); } }
void Timeline::Render() { //Entity::Render(); if (currentAnimation) { Graphics::PushMatrix(); float lineHalfWidth = Graphics::GetVirtualWidth() * 0.9f * 0.5f; float y = Graphics::GetVirtualHeight() * 0.5f - 50; float p = currentAnimation->GetCurrentTime() / currentAnimation->GetDuration(); Vector2 start = Graphics::GetScreenCenter() + Vector2(-lineHalfWidth, y); Vector2 end = Graphics::GetScreenCenter() + Vector2(lineHalfWidth, y); Graphics::BindTexture(NULL); Graphics::SetColor(Color::blue); Graphics::RenderLine(start, end); Vector2 playHead; float playHeadHalfHeight = 16; if (Debug::selectedEntity) { Graphics::SetColor(Color::orange); Part *part = dynamic_cast<Part*>(Debug::selectedEntity); if (part) { PartKeyFrames *partKeyFrames = currentAnimation->GetPartKeyFrames(part); if (partKeyFrames) { const std::list<KeyFrame> *keyFrames = partKeyFrames->GetKeyFrames(); for (std::list<KeyFrame>::const_iterator i = keyFrames->begin(); i != keyFrames->end(); ++i) { playHead = (end-start) * ((*i).GetTime()/currentAnimation->GetDuration()) + start; Graphics::RenderLine(playHead + Vector2::up * playHeadHalfHeight, playHead + Vector2::down * playHeadHalfHeight); } } } } playHead = (end - start) * p + start; Graphics::SetColor(Color::blue); Graphics::RenderLine(playHead + Vector2::up * playHeadHalfHeight * 0.5f, playHead + Vector2::down * playHeadHalfHeight * 0.5f); Graphics::PopMatrix(); } }
void Animation::ApplyTimeChange(bool loop) { if (currentTime >= duration) { if (!loop) currentTime = duration; else currentTime -= int(currentTime/duration) * duration; } else if (currentTime < 0) { if (!loop) currentTime = 0; else currentTime += (int(-1*currentTime/duration)+1) * duration; } for (std::list<PartKeyFrames>::iterator i = partKeyFrames.begin(); i != partKeyFrames.end(); ++i) { PartKeyFrames *currentPartKeyFrames = &(*i); if (currentPartKeyFrames) { KeyFrame *prev=NULL, *next=NULL; currentPartKeyFrames->GetKeyFrameForTime(currentTime, &prev, &next); if (prev && !next) { currentPartKeyFrames->GetPart()->LerpTransform(prev, prev, 1.0f); } else if (prev && next) { float diff = next->GetTime() - prev->GetTime(); float p = (currentTime - prev->GetTime()) / diff; //printf("LerpTransform %f\n", p); // adjust p by ease currentPartKeyFrames->GetPart()->LerpTransform(prev, next, Tween::Ease(p, EASE_INOUTSIN));//prev->easeType)); } } } }
void Puppet::Load(const std::string &filename, Entity *entity) { this->filename = filename; animations.clear(); // delete parts? parts.clear(); TiXmlDocument xmlDoc(Assets::GetContentPath() + filename); if (xmlDoc.LoadFile()) { /// TextureAtlas TiXmlElement *xmlTextureAtlas = xmlDoc.FirstChildElement("TextureAtlas"); if (xmlTextureAtlas) { textureAtlas = new TextureAtlas(); textureAtlas->Load(xmlTextureAtlas); } /// Parts TiXmlElement *xmlParts = xmlDoc.FirstChildElement("Parts"); if (xmlParts) { LoadParts(xmlParts, entity); } /// Animations TiXmlElement *xmlAnimations = xmlDoc.FirstChildElement("Animations"); if (xmlAnimations) { /// Animation TiXmlElement *xmlAnimation = xmlAnimations->FirstChildElement("Animation"); while (xmlAnimation) { Animation animation; XMLFileNode xmlFileNodeKeyFrameAnim(xmlAnimation); animation.Load(&xmlFileNodeKeyFrameAnim); /// PartKeyFrames TiXmlElement *xmlPartKeyFrames = xmlAnimation->FirstChildElement("PartKeyFrames"); while (xmlPartKeyFrames) { PartKeyFrames partKeyFrames; partKeyFrames.SetPuppet(this); XMLFileNode xmlFileNodeKeyFramePart(xmlPartKeyFrames); partKeyFrames.Load(&xmlFileNodeKeyFramePart); /// KeyFrame TiXmlElement *xmlKeyFrame = xmlPartKeyFrames->FirstChildElement("KeyFrame"); while (xmlKeyFrame) { KeyFrame keyFrame; XMLFileNode xmlFileNodeKeyFrame(xmlKeyFrame); keyFrame.Load(&xmlFileNodeKeyFrame); partKeyFrames.AddKeyFrame(keyFrame); xmlKeyFrame = xmlKeyFrame->NextSiblingElement("KeyFrame"); } animation.AddPartKeyFrames(partKeyFrames); xmlPartKeyFrames = xmlPartKeyFrames->NextSiblingElement("PartKeyFrames"); } animation.RefreshDuration(); animations.push_back(animation); xmlAnimation = xmlAnimation->NextSiblingElement("Animation"); } } } else { Debug::Log("Warning: Could not open puppet file: " + Assets::GetContentPath() + filename); Debug::Log(" " + std::string(xmlDoc.ErrorDesc())); printf(" Row: %d\n", xmlDoc.ErrorRow()); } }
void Puppet::Save(Entity *entity) { // save to filename TiXmlDocument xmlDoc; /// TextureAtlas if (textureAtlas) { textureAtlas->Save(&xmlDoc); } /// Parts //TiXmlElement *xmlParts = xmlDoc.FirstChildElement("Parts"); TiXmlElement xmlParts("Parts"); SaveParts(&xmlParts, entity); xmlDoc.InsertEndChild(xmlParts); /// Animations TiXmlElement xmlAnimations("Animations"); { /// Animation for (std::list<Animation>::iterator i = animations.begin(); i != animations.end(); ++i) { TiXmlElement xmlAnimation("Animation"); Animation *animation = &(*i); XMLFileNode xmlFileNodeKeyFrameAnim(&xmlAnimation); animation->Save(&xmlFileNodeKeyFrameAnim); /// PartKeyFrames for (std::list<Part*>::iterator j = parts.begin(); j != parts.end(); ++j) { PartKeyFrames *partKeyFrames = animation->GetPartKeyFrames(*j); if (partKeyFrames) { TiXmlElement xmlPartKeyFrames("PartKeyFrames"); XMLFileNode xmlFileNodePartKeyFrames(&xmlPartKeyFrames); partKeyFrames->Save(&xmlFileNodePartKeyFrames); /// KeyFrame std::list<KeyFrame> *keyFrames = partKeyFrames->GetKeyFrames(); for (std::list<KeyFrame>::iterator i = keyFrames->begin(); i != keyFrames->end(); ++i) { KeyFrame *keyFrame = &(*i); TiXmlElement xmlKeyFrame("KeyFrame"); XMLFileNode xmlFileNodeKeyFrame(&xmlKeyFrame); keyFrame->Save(&xmlFileNodeKeyFrame); xmlPartKeyFrames.InsertEndChild(xmlKeyFrame); } xmlAnimation.InsertEndChild(xmlPartKeyFrames); } } xmlAnimations.InsertEndChild(xmlAnimation); } } xmlDoc.InsertEndChild(xmlAnimations); xmlDoc.SaveFile(Assets::GetContentPath() + filename); }