void Puppet::Save() { if (entity) { // save to filename TiXmlDocument xmlDoc; /// TextureAtlas if (textureAtlas) { textureAtlas->Save(&xmlDoc); } /// Parts //TiXmlElement *xmlParts = xmlDoc.FirstChildElement("Parts"); TiXmlElement xmlParts("Parts"); for (std::list<Part*>::iterator i = parts.begin(); i != parts.end(); ++i) { if ((*i)->GetParent() == entity) { printf("calling SaveParts... top level...\n"); SavePart(&xmlParts, (*i)); } } 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 k = keyFrames->begin(); k != keyFrames->end(); ++k) { KeyFrame *keyFrame = &(*k); 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); } }
void AnimationTimeline::animationAttached(Animation& animation) { ASSERT(animation.timeline() == this); ASSERT(!m_animations.contains(&animation)); m_animations.add(&animation); }
//--------------------------------------------------------------------- void Skeleton::setAnimationState(const AnimationStateSet& animSet) { /* Algorithm: 1. Reset all bone positions 2. Iterate per AnimationState, if enabled get Animation and call Animation::apply */ // Reset bones reset(); Real weightFactor = 1.0f; if (mBlendState == ANIMBLEND_AVERAGE) { // Derive total weights so we can rebalance if > 1.0f Real totalWeights = 0.0f; ConstEnabledAnimationStateIterator stateIt = animSet.getEnabledAnimationStateIterator(); while (stateIt.hasMoreElements()) { const AnimationState* animState = stateIt.getNext(); // Make sure we have an anim to match implementation const LinkedSkeletonAnimationSource* linked = 0; if (_getAnimationImpl(animState->getAnimationName(), &linked)) { totalWeights += animState->getWeight(); } } // Allow < 1.0f, allows fade out of all anims if required if (totalWeights > 1.0f) { weightFactor = 1.0f / totalWeights; } } // Per enabled animation state ConstEnabledAnimationStateIterator stateIt = animSet.getEnabledAnimationStateIterator(); while (stateIt.hasMoreElements()) { const AnimationState* animState = stateIt.getNext(); const LinkedSkeletonAnimationSource* linked = 0; Animation* anim = _getAnimationImpl(animState->getAnimationName(), &linked); // tolerate state entries for animations we're not aware of if (anim) { if(animState->hasBlendMask()) { anim->apply(this, animState->getTimePosition(), animState->getWeight() * weightFactor, animState->getBlendMask(), linked ? linked->scale : 1.0f); } else { anim->apply(this, animState->getTimePosition(), animState->getWeight() * weightFactor, linked ? linked->scale : 1.0f); } } } }
inline float currentOpacity() const { return min(opacity.value(), opacityWhenDisabled.value()); }
inline void Block::setSize(const Size<double>& size) { Rectangle::setSize(size); animation.setSize(size); }
Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties) { assert(animationProperties); assert(std::strcmp(animationProperties->getNamespace(), "animation") == 0); const char* propertyIdStr = animationProperties->getString("property"); assert(propertyIdStr); // Get animation target property id int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr); assert(propertyId != -1); unsigned int keyCount = animationProperties->getInt("keyCount"); assert(keyCount > 0); const char* keyTimesStr = animationProperties->getString("keyTimes"); assert(keyTimesStr); const char* keyValuesStr = animationProperties->getString("keyValues"); assert(keyValuesStr); const char* curveStr = animationProperties->getString("curve"); assert(curveStr); char delimeter = ' '; unsigned int startOffset = 0; unsigned int endOffset = (unsigned int)std::string::npos; unsigned long* keyTimes = new unsigned long[keyCount]; for (unsigned int i = 0; i < keyCount; i++) { endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0); } else { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0); } startOffset = endOffset + 1; } startOffset = 0; endOffset = (unsigned int)std::string::npos; int componentCount = getAnimationPropertyComponentCount(propertyId); assert(componentCount > 0); unsigned int components = keyCount * componentCount; float* keyValues = new float[components]; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str()); } startOffset = endOffset + 1; } const char* keyInStr = animationProperties->getString("keyIn"); float* keyIn = NULL; if (keyInStr) { keyIn = new float[components]; startOffset = 0; endOffset = (unsigned int)std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str()); } startOffset = endOffset + 1; } } const char* keyOutStr = animationProperties->getString("keyOut"); float* keyOut = NULL; if (keyOutStr) { keyOut = new float[components]; startOffset = 0; endOffset = (unsigned int)std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str()); } startOffset = endOffset + 1; } } int curve = Curve::getInterpolationType(curveStr); Animation* animation = NULL; if (keyIn && keyOut) { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve); } else { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve); } SAFE_DELETE(keyOut); SAFE_DELETE(keyIn); SAFE_DELETE(keyValues); SAFE_DELETE(keyTimes); Properties* pClip = animationProperties->getNextNamespace(); if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0) { int frameCount = animationProperties->getInt("frameCount"); assert(frameCount > 0); animation->createClips(animationProperties, (unsigned int) frameCount); } return animation; }
int UtcDaliModelBuildAnimation01(void) { TestApplication application; TestPlatformAbstraction& platform = application.GetPlatform(); tet_infoline("Testing Dali::MeshActor::New()"); Dali::ModelData modelData = BuildTreeModel(); // Raise a request Model model = Model::New("Tree"); application.SendNotification(); application.Render(); Integration::ResourceRequest* request = platform.GetRequest(); // Return modelData if(request) { platform.SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(&(modelData.GetBaseObject()))); } application.Render(); application.SendNotification(); Actor actor = ModelActorFactory::BuildActorTree(model, ""); // model should be loaded Stage::GetCurrent().Add(actor); DALI_TEST_CHECK(model.GetLoadingState() == ResourceLoadingSucceeded); DALI_TEST_CHECK(actor); DALI_TEST_CHECK(actor.GetName().compare("root") == 0); DALI_TEST_EQUALS(model.NumberOfAnimations(), static_cast<size_t>(1), TEST_LOCATION); unsigned int animIndex=0; bool found = model.FindAnimation("Anim1", animIndex); DALI_TEST_CHECK(found); Animation twigAnim = ModelActorFactory::BuildAnimation(model, actor, animIndex); DALI_TEST_CHECK(twigAnim); DALI_TEST_EQUALS(twigAnim.GetDuration(), 10.0f, 0.001, TEST_LOCATION); DALI_TEST_CHECK(twigAnim.GetDefaultAlphaFunction() == Dali::AlphaFunctions::Linear); Actor twigActor = actor.FindChildByName("twig"); DALI_TEST_CHECK(twigActor); // Start the animation twigAnim.Play(); float durationSeconds = 10.0f; bool signalReceived(false); AnimationFinishCheck finishCheck(signalReceived); twigAnim.FinishedSignal().Connect(&application, finishCheck); application.SendNotification(); application.Render(); finishCheck.CheckSignalNotReceived(); DALI_TEST_EQUALS( twigActor.GetCurrentPosition(), Vector3(2.0f, 1.0f, 0.0f), 0.01f, TEST_LOCATION ); application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */); application.SendNotification(); DALI_TEST_EQUALS( twigActor.GetCurrentPosition(), Vector3(2.5f, 1.0f, 2.5f), 0.01f, TEST_LOCATION ); application.Render(static_cast<unsigned int>(durationSeconds*500.0f)/* 75% progress */); application.SendNotification(); DALI_TEST_EQUALS( twigActor.GetCurrentPosition(), Vector3(3.5f, 1.0f, 7.5f), 0.01f, TEST_LOCATION ); application.Render(static_cast<unsigned int>(durationSeconds*500.0f)/* Past Finished */); application.SendNotification(); DALI_TEST_EQUALS( twigActor.GetCurrentPosition(), Vector3(4.0f, 1.0f, 10.0f), 0.01f, TEST_LOCATION ); finishCheck.CheckSignalReceived(); END_TEST; }
void CSSToStyleMap::mapAnimationTimingFunction(Animation& animation, const CSSValue& value) { if (value.treatAsInitialValue(CSSPropertyWebkitAnimationTimingFunction)) { animation.setTimingFunction(Animation::initialTimingFunction()); return; } if (is<CSSPrimitiveValue>(value)) { switch (downcast<CSSPrimitiveValue>(value).getValueID()) { case CSSValueLinear: animation.setTimingFunction(LinearTimingFunction::create()); break; case CSSValueEase: animation.setTimingFunction(CubicBezierTimingFunction::create()); break; case CSSValueEaseIn: animation.setTimingFunction(CubicBezierTimingFunction::create(CubicBezierTimingFunction::EaseIn)); break; case CSSValueEaseOut: animation.setTimingFunction(CubicBezierTimingFunction::create(CubicBezierTimingFunction::EaseOut)); break; case CSSValueEaseInOut: animation.setTimingFunction(CubicBezierTimingFunction::create(CubicBezierTimingFunction::EaseInOut)); break; case CSSValueStepStart: animation.setTimingFunction(StepsTimingFunction::create(1, true)); break; case CSSValueStepEnd: animation.setTimingFunction(StepsTimingFunction::create(1, false)); break; default: break; } return; } if (is<CSSCubicBezierTimingFunctionValue>(value)) { auto& cubicTimingFunction = downcast<CSSCubicBezierTimingFunctionValue>(value); animation.setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction.x1(), cubicTimingFunction.y1(), cubicTimingFunction.x2(), cubicTimingFunction.y2())); } else if (is<CSSStepsTimingFunctionValue>(value)) { auto& stepsTimingFunction = downcast<CSSStepsTimingFunctionValue>(value); animation.setTimingFunction(StepsTimingFunction::create(stepsTimingFunction.numberOfSteps(), stepsTimingFunction.stepAtStart())); } else if (is<CSSSpringTimingFunctionValue>(value)) { auto& springTimingFunction = downcast<CSSSpringTimingFunctionValue>(value); animation.setTimingFunction(SpringTimingFunction::create(springTimingFunction.mass(), springTimingFunction.stiffness(), springTimingFunction.damping(), springTimingFunction.initialVelocity())); } }
void ChangeControllerState::undo() { Animation* a = project()->getAnimation(m_animation); a->setControllerState(m_controller, !m_state); }
// TODO: get the time it takes the user to draw the LOA, going to need the control points dropped at intervals Animation* evaluateDLOA(ModelData* modelData, vector<struct pt*> spline) { Animation* animation = new Animation(); ofstream myfile; myfile.open ("/home/psarahdactyl/Documents/ccfunfunfun.txt"); spline.clear(); for(int i = 0; i < 100; i+=1) { spline.push_back(createPoint(i, 0, 0)); } // calculate the constant b double modelLength = getModelLength(modelData->mutable_model()); double splineLength = getSplineLength(spline); myfile << "ml " << modelLength << endl; myfile << "sl " << splineLength << endl; double b = modelLength / (splineLength); myfile << "b " << b << endl; // calculate points in spline per frame double pointsPerFrame = spline.size() * b; myfile << "ss: " << spline.size() << endl; myfile << "ppf: " << pointsPerFrame << endl; // calculate which point goes with which joint Node* root = modelData->mutable_model(); // maps points from user drawn curve -- now a spline -- to the joints in the model vector<int> correspondingPoints = mapPoints(root, pointsPerFrame, modelLength); for(int h = 0; h < correspondingPoints.size(); h++) { myfile << correspondingPoints.at(h) << endl; } vector<struct pt*> extra; struct pt* last = spline.at(spline.size()-1); struct pt* secondLast = spline.at(spline.size()-2); double x = last->x - secondLast->x; double y = last->y - secondLast->y; double z = last->z - secondLast->z; struct pt* difference = createPoint(x, y, z); for(double t = 1; t <= pointsPerFrame; t++) { struct pt* diff = multScalar(t, difference); struct pt* r = add(last, diff); extra.push_back(r); } vector<struct pt*> newSpline; newSpline.reserve( spline.size() + extra.size() ); // preallocate memory newSpline.insert( newSpline.end(), spline.begin(), spline.end() ); newSpline.insert( newSpline.end(), extra.begin(), extra.end() ); // go through every point in spline // iterating by 1 every time gives us frames overlapping points in the spline for (int i = 0; i < newSpline.size() - pointsPerFrame; i++) { int index = 0; // move model and its joints Node frame = jointsToSpline(root, newSpline, correspondingPoints, index, &myfile); frame.set_name(root->name()); // go through the mapped joints on the model and move them up by 1 // since we are on a new frame vector<int> newCorresponding; for (int j = 0; j < correspondingPoints.size(); j++) { newCorresponding.push_back(correspondingPoints.at(j)+1); } // copy for the next iteration correspondingPoints = newCorresponding; // add frames to the animation Node* a = animation->add_frames(); Node parent; Node* p = parent.add_children(); parent.CopyFrom(frame); p->CopyFrom(frame); a->CopyFrom(parent); a->set_name(root->name()); } return animation; }
void LevelParser::writeAnimation(tinyxml2::XMLElement* pAnimElem, Animation animation) { pAnimElem->SetAttribute("row", animation.getRow()); // Sprite sheet row pAnimElem->SetAttribute("nFrames", animation.getNFrames()); // Total frames pAnimElem->SetAttribute("frameTime", animation.getFrameTime()); // Interval between frames }
// Update: draw background update_status ModuleBlinky::Update() { Animation* current_animation = &idle; Animation* horitzontal = &a_hor; Animation* vertical = &a_vert; float position_x = position.x; float position_y = position.y; int i_position_x = position.x; int i_position_y = position.y; int tilepos_x = ((i_position_x + 16) / 16) * 16; int tilepos_y = ((i_position_y + 16) / 16) * 16; int d_up = 1000; int d_down = 1000; int d_right = 1000; int d_left = 1000; float speed = 1.5; if (SDL_GetTicks() - time <= 700){ direction = 2; //if (SDL_GetTicks() - time >= 2000) direction = 1; } else if (SDL_GetTicks() - time <= 810){ direction = 1; } else { if (turn == true){ if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -1 || App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -2){ if (App->player->s_map[(tilepos_y / 16) - 1][(tilepos_x / 16)] != 2){ d_up = SDL_sqrt(((tilepos_x)-App->player->position.x)*(tilepos_x - App->player->position.x) + ((tilepos_y - 16) - App->player->position.y)*((tilepos_y - 16) - App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16) + 1][(tilepos_x / 16)] != 2){ d_down = SDL_sqrt(((tilepos_x)-App->player->position.x)*(tilepos_x - App->player->position.x) + ((tilepos_y + 16) - App->player->position.y)*((tilepos_y + 16) - App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16) - 1] != 2){ d_left = SDL_sqrt(((tilepos_x - 16) - App->player->position.x)*((tilepos_x - 16) - App->player->position.x) + ((tilepos_y)-App->player->position.y)*((tilepos_y)-App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16) + 1] != 2){ d_right = SDL_sqrt(((tilepos_x + 16) - App->player->position.x)*((tilepos_x + 16) - App->player->position.x) + ((tilepos_y)-App->player->position.y)*((tilepos_y)-App->player->position.y)); } if (direction == 0){ d_left = 1000; } if (direction == 1){ d_right = 1000; } if (direction == 2){ d_down = 1000; } if (direction == 3){ d_up = 1000; } if (d_up <= d_down && d_up <= d_right && d_up <= d_left){ direction = 2; turn = false; } else if (d_right <= d_down && d_right <= d_left && d_right <= d_up){ direction = 0; turn = false; } else if (d_down <= d_up && d_down <= d_right && d_down <= d_left){ direction = 3; turn = false; } else if (d_left <= d_up && d_left <= d_right && d_left <= d_down){ direction = 1; turn = false; } } if (App->player->power == true){ d_up = 0; d_down = 0; d_right = 0; d_left = 0; if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -1 || App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -2){ if (App->player->s_map[(tilepos_y / 16) - 1][(tilepos_x / 16)] != 2){ d_up = SDL_sqrt(((tilepos_x)-App->player->position.x)*(tilepos_x - App->player->position.x) + ((tilepos_y - 16) - App->player->position.y)*((tilepos_y - 16) - App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16) + 1][(tilepos_x / 16)] != 2){ d_down = SDL_sqrt(((tilepos_x)-App->player->position.x)*(tilepos_x - App->player->position.x) + ((tilepos_y + 16) - App->player->position.y)*((tilepos_y + 16) - App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16) - 1] != 2){ d_left = SDL_sqrt(((tilepos_x - 16) - App->player->position.x)*((tilepos_x - 16) - App->player->position.x) + ((tilepos_y)-App->player->position.y)*((tilepos_y)-App->player->position.y)); } if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16) + 1] != 2){ d_right = SDL_sqrt(((tilepos_x + 16) - App->player->position.x)*((tilepos_x + 16) - App->player->position.x) + ((tilepos_y)-App->player->position.y)*((tilepos_y)-App->player->position.y)); } if (d_up >= d_down && d_up >= d_right && d_up >= d_left){ direction = 2; turn = false; } else if (d_down >= d_up && d_down >= d_right && d_down >= d_left){ direction = 3; turn = false; } else if (d_right >= d_down && d_right >= d_left && d_right >= d_up){ direction = 0; turn = false; } else if (d_left >= d_up && d_left >= d_right && d_left >= d_down){ direction = 1; turn = false; } } } } } if (App->player->power == true ||App->player->god ==true){ if (SDL_GetTicks() - App->player->time > 2000 && SDL_GetTicks() - App->player->time < 4000){ current_animation = &scared2; } else current_animation = &scared; } else{ if (direction == 0){ current_animation = &right; //position.x += speed; } if (direction == 1){ current_animation = &left; //position.x -= speed; } if (direction == 2){ current_animation = &up; //position.y -= speed; } if (direction == 3){ current_animation = &down; //position.y += speed; } } if (direction == 0 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16)] != 2){ position_x = position_x + speed; position.x = position_x; position.y = (i_position_y / 16) * 16 + 8; } if (direction == 1 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16)] != 2){ position_x = position_x - speed; position.x = position_x; position.y = (i_position_y / 16) * 16 + 8; } if (direction == 2 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16)] != 2){ position_y = position_y - speed; position.y = position_y; position.x = (i_position_x / 16) * 16 + 8; } if (direction == 3 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16)] != 2){ position_y = position_y + speed; position.y = position_y; position.x = (i_position_x / 16) * 16 + 8; } if (direction == 0 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16) + 1] == 2){ position_x = position_x - speed; position.x = (i_position_x / 16) * 16 + 8; } if (direction == 1 && App->player->s_map[tilepos_y / 16][(tilepos_x / 16) - 1] == 2){ position_x = position_x + speed; position.x = (i_position_x / 16) * 16 + 8; } if (direction == 2 && App->player->s_map[(tilepos_y / 16) - 1][(tilepos_x / 16)] == 2){ position_y = position_y + speed; position.y = (i_position_y / 16) * 16 + 8; } if (direction == 3 && App->player->s_map[(tilepos_y / 16) + 1][(tilepos_x / 16)] == 2){ position_y = position_y - speed; position.y = (i_position_y / 16) * 16 + 8; } float t_positionx = position.x; float t_positiony = position.y; float t_position_x = t_positionx; float t_position_y = t_positiony; int p_position_x = App->player->position.x; int p_position_y = App->player->position.y; int player_position_x = (( p_position_x+ 16) / 16) * 16; int player_position_y = ((p_position_y + 16) / 16) * 16; bool t_turn = true; // Collider-------------- col->SetPos(tilepos_x, tilepos_y); int i = 0, n = 0; int temp_dir = direction; bool ret = false; int cont = 0; if (debug ==true){ while (ret != true){ d_up = 1000; d_down = 1000; d_left = 1000; d_right = 1000; //t_position_x + i != App->player->position.x && t_position_y + n != App->player->position.y float t_position_x = t_positionx; float t_position_y = t_positiony; int t_i_position_x = t_positionx; int t_i_position_y = t_positiony; int t_tilepos_y = ((t_i_position_y + 16) / 16) * 16; int t_tilepos_x = ((t_i_position_x + 16) / 16) * 16; if (t_turn == true){ if (App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16)] == -1 || App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16)] == -2){ if (App->player->s_map[(t_tilepos_y / 16) - 1][(t_tilepos_x / 16)] != 2){ d_up = SDL_sqrt(((t_tilepos_x)-App->player->position.x)*(t_tilepos_x - App->player->position.x) + ((t_tilepos_y - 16) - App->player->position.y)*((t_tilepos_y - 16) - App->player->position.y)); } if (App->player->s_map[(t_tilepos_y / 16) + 1][(t_tilepos_x / 16)] != 2){ d_down = SDL_sqrt(((t_tilepos_x)-App->player->position.x)*(t_tilepos_x - App->player->position.x) + ((t_tilepos_y + 16) - App->player->position.y)*((t_tilepos_y + 16) - App->player->position.y)); } if (App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16) - 1] != 2){ d_left = SDL_sqrt(((t_tilepos_x - 16) - App->player->position.x)*((t_tilepos_x - 16) - App->player->position.x) + ((t_tilepos_y)-App->player->position.y)*((t_tilepos_y)-App->player->position.y)); } if (App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16) + 1] != 2){ d_right = SDL_sqrt(((t_tilepos_x + 16) - App->player->position.x)*((t_tilepos_x + 16) - App->player->position.x) + ((t_tilepos_y)-App->player->position.y)*((t_tilepos_y)-App->player->position.y)); } if (temp_dir == 0){ d_left = 1000; } if (temp_dir == 1){ d_right = 1000; } if (temp_dir == 2){ d_down = 1000; } if (temp_dir == 3){ d_up = 1000; } if (d_up <= d_down && d_up <= d_right && d_up <= d_left){ temp_dir = 2; t_turn = false; } else if (d_right <= d_down && d_right <= d_left && d_right <= d_up){ temp_dir = 0; t_turn = false; } else if (d_down <= d_up && d_down <= d_right && d_down <= d_left){ temp_dir = 3; t_turn = false; } else if (d_left <= d_up && d_left <= d_right && d_left <= d_down){ temp_dir = 1; t_turn = false; } } } if (temp_dir == 0 && App->player->s_map[t_tilepos_y / 16][(t_tilepos_x / 16)] != 2){ t_position_x = t_position_x + speed; t_positionx = t_position_x; t_positiony = (t_i_position_y / 16) * 16 + 8; } if (temp_dir == 1 && App->player->s_map[t_tilepos_y / 16][(t_tilepos_x / 16)] != 2){ t_position_x = t_position_x - speed; t_positionx = t_position_x; t_positiony = (t_i_position_y / 16) * 16 + 8; } if (temp_dir == 2 && App->player->s_map[t_tilepos_y / 16][(t_tilepos_x / 16)] != 2){ t_position_y = t_position_y - speed; t_positiony = t_position_y; t_positionx = (t_i_position_x / 16) * 16 + 8; } if (temp_dir == 3 && App->player->s_map[t_tilepos_y / 16][(t_tilepos_x / 16)] != 2){ t_position_y = t_position_y + speed; t_positiony = t_position_y; t_positionx = (t_i_position_x / 16) * 16 + 8; } if (temp_dir == 0 && App->player->s_map[t_tilepos_y / 16][(t_tilepos_x / 16) + 1] == 2){ t_position_x = t_position_x - speed; t_positionx = (t_i_position_x / 16) * 16 + 8; } if (temp_dir == 0 || temp_dir == 1){ App->render->Blit(graphics, t_tilepos_x, t_tilepos_y, &(horitzontal->GetCurrentFrame())); } else App->render->Blit(graphics, t_tilepos_x, t_tilepos_y, &(vertical->GetCurrentFrame())); if (temp_dir == 0){ t_tilepos_x += 16; } if (temp_dir == 1){ t_tilepos_x -= 16; } if (temp_dir == 2){ t_tilepos_y -= 16; } if (temp_dir == 3){ t_tilepos_y += 16; } if (App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16)] != -1 && App->player->s_map[(t_tilepos_y / 16)][(t_tilepos_x / 16)] != -2) { t_turn = true; } if ((t_tilepos_y == player_position_y && t_tilepos_x == player_position_x) || cont >= 100){ ret = true; t_turn = true; temp_dir = direction; } cont++; } } if (destroyed == false) App->render->Blit(graphics, position.x, position.y, &(current_animation->GetCurrentFrame())); if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -3) { position.x = 0; } if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] == -4) { position.x = 410; } // Draw everything -------------------------------------- SDL_Rect r = current_animation->GetCurrentFrame(); //App->render->Blit(graphics, position.x, position.y - r.h, &r); /*int tilepos_x_temp = ((i_position_x + 16) / 16) * 16; int tilepos_y_temp = ((i_position_y + 16) / 16) * 16; if (tilepos_x_temp != tilepos_x || tilepos_y_temp != tilepos_y){ turn = true; }*/ if (App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] != -1 && App->player->s_map[(tilepos_y / 16)][(tilepos_x / 16)] != -2) { turn = true; } return UPDATE_CONTINUE; }
void SkeletalAnimation::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Also create a DebugRenderer component so that we can draw debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); // Create scene node & StaticModel component for showing a static plane Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.5f, 0.5f, 0.7f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light to the world. Enable cascaded shadows on it Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); // Create animated models const unsigned NUM_MODELS = 100; const float MODEL_MOVE_SPEED = 2.0f; const float MODEL_ROTATE_SPEED = 100.0f; const BoundingBox bounds(Vector3(-47.0f, 0.0f, -47.0f), Vector3(47.0f, 0.0f, 47.0f)); for (unsigned i = 0; i < NUM_MODELS; ++i) { Node* modelNode = scene_->CreateChild("Jack"); modelNode->SetPosition(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f)); modelNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f)); AnimatedModel* modelObject = modelNode->CreateComponent<AnimatedModel>(); modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl")); modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml")); modelObject->SetCastShadows(true); // Create an AnimationState for a walk animation. Its time position will need to be manually updated to advance the // animation, The alternative would be to use an AnimationController component which updates the animation automatically, // but we need to update the model's position manually in any case Animation* walkAnimation = cache->GetResource<Animation>("Models/Jack_Walk.ani"); AnimationState* state = modelObject->AddAnimationState(walkAnimation); // The state would fail to create (return null) if the animation was not found if (state) { // Enable full blending weight and looping state->SetWeight(1.0f); state->SetLooped(true); state->SetTime(Random(walkAnimation->GetLength())); } // Create our custom Mover component that will move & animate the model during each frame's update Mover* mover = modelNode->CreateComponent<Mover>(); mover->SetParameters(MODEL_MOVE_SPEED, MODEL_ROTATE_SPEED, bounds); } // Create the camera. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera"); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); }
void Puppet::Load(const std::string &filename, Entity *entity) { this->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, NULL); } /// 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 SpriteDef::loadAnimation(xmlNodePtr animationNode, Action *action, ImageSet *imageSet, int variant_offset) { const std::string directionName = XML::getProperty(animationNode, "direction", ""); const SpriteDirection directionType = makeSpriteDirection(directionName); if (directionType == DIRECTION_INVALID) { logger->log("Warning: Unknown direction \"%s\" used in %s", directionName.c_str(), getIdPath().c_str()); return; } Animation *animation = new Animation; action->setAnimation(directionType, animation); // Get animation frames for_each_xml_child_node(frameNode, animationNode) { const int delay = XML::getProperty(frameNode, "delay", DEFAULT_FRAME_DELAY); int offsetX = XML::getProperty(frameNode, "offsetX", 0) + imageSet->getOffsetX(); int offsetY = XML::getProperty(frameNode, "offsetY", 0) + imageSet->getOffsetY(); if (xmlStrEqual(frameNode->name, BAD_CAST "frame")) { const int index = XML::getProperty(frameNode, "index", -1); if (index < 0) { logger->log("No valid value for 'index'"); continue; } Image *img = imageSet->get(index + variant_offset); if (!img) { logger->log("No image at index %d", index + variant_offset); continue; } animation->addFrame(img, delay, offsetX, offsetY); } else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence")) { int start = XML::getProperty(frameNode, "start", -1); const int end = XML::getProperty(frameNode, "end", -1); if (start < 0 || end < 0) { logger->log("No valid value for 'start' or 'end'"); continue; } while (end >= start) { Image *img = imageSet->get(start + variant_offset); if (!img) { logger->log("No image at index %d", start + variant_offset); break; } animation->addFrame(img, delay, offsetX, offsetY); start++; } } else if (xmlStrEqual(frameNode->name, BAD_CAST "end")) { animation->addTerminator(); } } // for frameNode }
void Container::updateScroll() { // Update Time. static long lastFrameTime = Game::getGameTime(); long frameTime = Game::getGameTime(); long elapsedTime = (frameTime - lastFrameTime); lastFrameTime = frameTime; const Theme::Border& containerBorder = getBorder(_state); const Theme::Padding& containerPadding = getPadding(); // Calculate total width and height. float totalWidth = 0; float totalHeight = 0; std::vector<Control*> controls = getControls(); unsigned int controlsCount = controls.size(); for (unsigned int i = 0; i < controlsCount; i++) { Control* control = controls.at(i); const Rectangle& bounds = control->getBounds(); const Theme::Margin& margin = control->getMargin(); float newWidth = bounds.x + bounds.width; if (newWidth > totalWidth) { totalWidth = newWidth; } float newHeight = bounds.y + bounds.height; if (newHeight > totalHeight) { totalHeight = newHeight; } } float vWidth = getImageRegion("verticalScrollBar", _state).width; float hHeight = getImageRegion("horizontalScrollBar", _state).height; float clipWidth = _bounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right - vWidth; float clipHeight = _bounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom - hHeight; // Apply and dampen inertia. if (!_scrolling && !_scrollingVelocity.isZero()) { // Calculate the time passed since last update. float elapsedSecs = (float)elapsedTime * 0.001f; _scrollPosition.x += _scrollingVelocity.x * elapsedSecs; _scrollPosition.y += _scrollingVelocity.y * elapsedSecs; float dampening = 1.0f - _scrollingFriction * SCROLL_FRICTION_FACTOR * elapsedSecs; _scrollingVelocity.x *= dampening; _scrollingVelocity.y *= dampening; if (fabs(_scrollingVelocity.x) < 100.0f) _scrollingVelocity.x = 0.0f; if (fabs(_scrollingVelocity.y) < 100.0f) _scrollingVelocity.y = 0.0f; } // Stop scrolling when the far edge is reached. if (-_scrollPosition.x > totalWidth - clipWidth) { _scrollPosition.x = -(totalWidth - clipWidth); _scrollingVelocity.x = 0; } if (-_scrollPosition.y > totalHeight - clipHeight) { _scrollPosition.y = -(totalHeight - clipHeight); _scrollingVelocity.y = 0; } if (_scrollPosition.x > 0) { _scrollPosition.x = 0; _scrollingVelocity.x = 0; } if (_scrollPosition.y > 0) { _scrollPosition.y = 0; _scrollingVelocity.y = 0; } float scrollWidth = 0; if (clipWidth < totalWidth) scrollWidth = (clipWidth / totalWidth) * clipWidth; float scrollHeight = 0; if (clipHeight < totalHeight) scrollHeight = (clipHeight / totalHeight) * clipHeight; _scrollBarBounds.set(((-_scrollPosition.x) / totalWidth) * clipWidth, ((-_scrollPosition.y) / totalHeight) * clipHeight, scrollWidth, scrollHeight); // If scroll velocity is 0 and scrollbars are not always visible, trigger fade-out animation. if (!_scrolling && _scrollingVelocity.isZero() && _scrollBarsAutoHide && _scrollBarOpacity == 1.0f) { float to = 0; _scrollBarOpacity = 0.99f; Animation* animation = createAnimationFromTo("scrollbar-fade-out", ANIMATE_OPACITY, &_scrollBarOpacity, &to, Curve::QUADRATIC_IN_OUT, 500L); _scrollBarOpacityClip = animation->getClip(); _scrollBarOpacityClip->play(); } // Position controls within scroll area. _layout->update(this, _scrollPosition); }
void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { if (!panelWidget(widget)) return QProxyStyle::drawPrimitive(element, option, painter, widget); bool animating = (option->state & State_Animating); int state = option->state; QRect rect = option->rect; QRect oldRect; QRect newRect; if (widget && (element == PE_PanelButtonTool) && !animating) { QWidget *w = const_cast<QWidget *> (widget); int oldState = w->property("_q_stylestate").toInt(); oldRect = w->property("_q_stylerect").toRect(); newRect = w->rect(); w->setProperty("_q_stylestate", (int)option->state); w->setProperty("_q_stylerect", w->rect()); // Determine the animated transition bool doTransition = ((state & State_On) != (oldState & State_On) || (state & State_MouseOver) != (oldState & State_MouseOver)); if (oldRect != newRect) { doTransition = false; d->animator.stopAnimation(widget); } if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); Animation *anim = d->animator.widgetAnimation(widget); QStyleOption opt = *option; opt.state = (QStyle::State)oldState; opt.state |= State_Animating; startImage.fill(0); Transition *t = new Transition; t->setWidget(w); QPainter startPainter(&startImage); if (!anim) { drawPrimitive(element, &opt, &startPainter, widget); } else { anim->paint(&startPainter, &opt); d->animator.stopAnimation(widget); } QStyleOption endOpt = *option; endOpt.state |= State_Animating; t->setStartImage(startImage); d->animator.startAnimation(t); endImage.fill(0); QPainter endPainter(&endImage); drawPrimitive(element, &endOpt, &endPainter, widget); t->setEndImage(endImage); if (oldState & State_MouseOver) t->setDuration(150); else t->setDuration(75); t->setStartTime(QTime::currentTime()); } } switch (element) { case PE_IndicatorDockWidgetResizeHandle: painter->fillRect(option->rect, Utils::StyleHelper::borderColor()); break; case PE_FrameDockWidget: QCommonStyle::drawPrimitive(element, option, painter, widget); break; case PE_PanelLineEdit: { painter->save(); // Fill the line edit background QRect filledRect = option->rect.adjusted(1, 1, -1, -1); painter->setBrushOrigin(filledRect.topLeft()); painter->fillRect(filledRect, option->palette.base()); if (option->state & State_Enabled) Utils::StyleHelper::drawCornerImage(d->lineeditImage, painter, option->rect, 5, 5, 5, 5); else Utils::StyleHelper::drawCornerImage(d->lineeditImage_disabled, painter, option->rect, 5, 5, 5, 5); if (option->state & State_HasFocus || option->state & State_MouseOver) { QColor hover = Utils::StyleHelper::baseColor(); if (state & State_HasFocus) hover.setAlpha(100); else hover.setAlpha(50); painter->setPen(QPen(hover, 1)); painter->drawRect(option->rect.adjusted(1, 1, -2 ,-2)); } painter->restore(); } break; case PE_FrameStatusBarItem: break; case PE_PanelButtonTool: { Animation *anim = d->animator.widgetAnimation(widget); if (!animating && anim) { anim->paint(painter, option); } else { bool pressed = option->state & State_Sunken || option->state & State_On; QColor shadow(0, 0, 0, 30); painter->setPen(shadow); if (pressed) { QColor shade(0, 0, 0, 40); painter->fillRect(rect, shade); painter->drawLine(rect.topLeft() + QPoint(1, 0), rect.topRight() - QPoint(1, 0)); painter->drawLine(rect.topLeft(), rect.bottomLeft()); painter->drawLine(rect.topRight(), rect.bottomRight()); // painter->drawLine(rect.bottomLeft() + QPoint(1, 0), rect.bottomRight() - QPoint(1, 0)); QColor highlight(255, 255, 255, 30); painter->setPen(highlight); } else if (option->state & State_Enabled && option->state & State_MouseOver) { QColor lighter(255, 255, 255, 37); painter->fillRect(rect, lighter); } if (option->state & State_HasFocus && (option->state & State_KeyboardFocusChange)) { QColor highlight = option->palette.highlight().color(); highlight.setAlphaF(0.4); painter->setPen(QPen(highlight.lighter(), 1)); highlight.setAlphaF(0.3); painter->setBrush(highlight); painter->setRenderHint(QPainter::Antialiasing); QRectF rect = option->rect; rect.translate(0.5, 0.5); painter->drawRoundedRect(rect.adjusted(2, 2, -3, -3), 2, 2); } } } break; case PE_PanelStatusBar: { painter->save(); QLinearGradient grad = Utils::StyleHelper::statusBarGradient(rect); painter->fillRect(rect, grad); painter->setPen(QColor(255, 255, 255, 60)); painter->drawLine(rect.topLeft() + QPoint(0,1), rect.topRight()+ QPoint(0,1)); painter->setPen(Utils::StyleHelper::borderColor().darker(110)); painter->drawLine(rect.topLeft(), rect.topRight()); painter->restore(); } break; case PE_IndicatorToolBarSeparator: { QColor separatorColor = Utils::StyleHelper::borderColor(); separatorColor.setAlpha(100); painter->setPen(separatorColor); const int margin = 6; if (option->state & State_Horizontal) { const int offset = rect.width()/2; painter->drawLine(rect.bottomLeft().x() + offset, rect.bottomLeft().y() - margin, rect.topLeft().x() + offset, rect.topLeft().y() + margin); } else { //Draw vertical separator const int offset = rect.height()/2; painter->setPen(QPen(option->palette.background().color().darker(110))); painter->drawLine(rect.topLeft().x() + margin , rect.topLeft().y() + offset, rect.topRight().x() - margin, rect.topRight().y() + offset); } } break; case PE_IndicatorToolBarHandle: { bool horizontal = option->state & State_Horizontal; painter->save(); QPainterPath path; int x = option->rect.x() + (horizontal ? 2 : 6); int y = option->rect.y() + (horizontal ? 6 : 2); static const int RectHeight = 2; if (horizontal) { while (y < option->rect.height() - RectHeight - 6) { path.moveTo(x, y); path.addRect(x, y, RectHeight, RectHeight); y += 6; } } else { while (x < option->rect.width() - RectHeight - 6) { path.moveTo(x, y); path.addRect(x, y, RectHeight, RectHeight); x += 6; } } painter->setPen(Qt::NoPen); QColor dark = Utils::StyleHelper::borderColor(); dark.setAlphaF(0.4); QColor light = Utils::StyleHelper::baseColor(); light.setAlphaF(0.4); painter->fillPath(path, light); painter->save(); painter->translate(1, 1); painter->fillPath(path, dark); painter->restore(); painter->translate(3, 3); painter->fillPath(path, light); painter->translate(1, 1); painter->fillPath(path, dark); painter->restore(); } break; case PE_IndicatorArrowUp: case PE_IndicatorArrowDown: case PE_IndicatorArrowRight: case PE_IndicatorArrowLeft: { Utils::StyleHelper::drawArrow(element, painter, option); } break; default: QProxyStyle::drawPrimitive(element, option, painter, widget); break; } }
// Returns an animation of the model evaluated at a certain point along spline. // TODO: get the time it takes the user to draw the LOA, going to need the // control points dropped at intervals Animation* evaluateDLOA(ModelData* modelData, const vector<Point>& spline, int* modelFrames) { Animation* animation = new Animation(); ofstream myfile; // myfile.open ("/home/psarahdactyl/Documents/ccfunfunfun.txt"); // calculate the constant b double modelLength = getModelLength(modelData->mutable_model()); double splineLength = getSplineLength(spline); double b = modelLength / (splineLength); // calculate points in spline per frame double pointsPerFrame = spline.size() * b; *modelFrames = pointsPerFrame; // myfile << pointsPerFrame << endl; // calculate which point goes with which joint Node* root = modelData->mutable_model(); // maps points from user drawn curve -- now a spline -- to the joints in the // model vector<int> correspondingPoints = mapPoints(root, pointsPerFrame, modelLength); for (int h = 0; h < correspondingPoints.size(); h++) { myfile << correspondingPoints.at(h) << endl; } // End animation on curve unless there are not enough points on spline. vector<Point> extra; if (spline.size() < pointsPerFrame) { Point last = spline.at(spline.size() - 1); Point secondLast = spline.at(spline.size() - 2); double x = last.x - secondLast.x; double y = last.y - secondLast.y; double z = last.z - secondLast.z; Point difference = createPoint(x, y, z); for (double t = 1; t <= pointsPerFrame; t++) { Point diff = multScalar(t, difference); Point r = add(last, diff); extra.push_back(r); } } vector<Point> newSpline; newSpline.reserve(spline.size() + extra.size()); // preallocate memory newSpline.insert(newSpline.end(), spline.begin(), spline.end()); newSpline.insert(newSpline.end(), extra.begin(), extra.end()); // go through every point in spline // iterating by 1 every time gives us frames overlapping points in the spline for (int i = 0; i <= newSpline.size() - pointsPerFrame; i++) { int index = 0; // move model and its joints Node frame = jointsToSpline(root, newSpline, correspondingPoints, index, &myfile); frame.set_name(root->name()); // go through the mapped joints on the model and move them up by 1 // since we are on a new frame vector<int> newCorresponding; for (int j = 0; j < correspondingPoints.size(); j++) { newCorresponding.push_back(correspondingPoints.at(j) + 1); } // copy for the next iteration correspondingPoints = newCorresponding; // add frames to the animation Node* a = animation->add_frames(); a->CopyFrom(frame); a->set_name(root->name()); } return animation; }
bool createAnimationForRasterLayer(RasterLayer *pRasterLayer, AnimationController *pController) { if(pRasterLayer == NULL || pController == NULL) { return false; } std::vector<double> frameTimes; unsigned int numFrames = 0; RasterElement *pRasterElement = dynamic_cast<RasterElement*>(pRasterLayer->getDataElement()); if(pRasterElement != NULL) { const RasterDataDescriptor *pDescriptor = dynamic_cast<RasterDataDescriptor*>(pRasterElement->getDataDescriptor()); if(pDescriptor != NULL) { numFrames = pDescriptor->getBandCount(); const DynamicObject *pMetadata = pDescriptor->getMetadata(); try { frameTimes = dv_cast<std::vector<double> >(pMetadata->getAttributeByPath(FRAME_TIMES_METADATA_PATH)); if(frameTimes.size() < numFrames) { frameTimes.clear(); } } catch(const std::bad_cast&) { // do nothing } } } if(frameTimes.empty()) { double frameTime = pController->getStartFrame(); if(frameTime < 0.0) { frameTime = QDateTime::currentDateTime().toUTC().toTime_t(); } frameTimes.reserve(numFrames); for(unsigned int i = 0; i < numFrames; i++) { frameTimes.push_back(frameTime); frameTime += 1.0; } } Animation *pAnim = pController->createAnimation(pRasterLayer->getName()); VERIFY(pAnim != NULL); std::vector<AnimationFrame> frames; for(unsigned int i = 0; i < numFrames; ++i) { AnimationFrame frame; frame.mFrameNumber = i; if(pAnim->getFrameType() == FRAME_TIME) { frame.mTime = frameTimes[i]; } frames.push_back(frame); } pAnim->setFrames(frames); pRasterLayer->setAnimation(pAnim); return true; }
//--------------------------------------------------------------------- void XMLSkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, const String& filename) { LogManager::getSingleton().logMessage("XMLSkeletonSerializer writing " " skeleton data to " + filename + "..."); mXMLDoc = new TiXmlDocument(); mXMLDoc->InsertEndChild(TiXmlElement("skeleton")); TiXmlElement* rootNode = mXMLDoc->RootElement(); LogManager::getSingleton().logMessage("Populating DOM..."); // Write main skeleton data LogManager::getSingleton().logMessage("Exporting bones.."); writeSkeleton(pSkeleton); LogManager::getSingleton().logMessage("Bones exported."); // Write all animations unsigned short numAnims = pSkeleton->getNumAnimations(); String msg = "Exporting animations, count=" + StringConverter::toString(numAnims); LogManager::getSingleton().logMessage(msg); TiXmlElement* animsNode = rootNode->InsertEndChild(TiXmlElement("animations"))->ToElement(); for (unsigned short i = 0; i < numAnims; ++i) { Animation* pAnim = pSkeleton->getAnimation(i); msg = "Exporting animation: " + pAnim->getName(); LogManager::getSingleton().logMessage(msg); writeAnimation(animsNode, pAnim); LogManager::getSingleton().logMessage("Animation exported."); } // Write links Skeleton::LinkedSkeletonAnimSourceIterator linkIt = pSkeleton->getLinkedSkeletonAnimationSourceIterator(); if (linkIt.hasMoreElements()) { LogManager::getSingleton().logMessage("Exporting animation links."); TiXmlElement* linksNode = rootNode->InsertEndChild(TiXmlElement("animationlinks"))->ToElement(); while(linkIt.hasMoreElements()) { const LinkedSkeletonAnimationSource& link = linkIt.getNext(); writeSkeletonAnimationLink(linksNode, link); } } LogManager::getSingleton().logMessage("DOM populated, writing XML file.."); // Write out to a file if(! mXMLDoc->SaveFile(filename) ) { LogManager::getSingleton().logMessage("XMLSkeletonSerializer failed writing the XML file.", LML_CRITICAL); } else { LogManager::getSingleton().logMessage("XMLSkeletonSerializer export successful."); } delete mXMLDoc; }
bool Barrier::init(int type) { Size visibleSize = Director::getInstance()->getVisibleSize(); m_barrierType = type; char filename[128]; sprintf(filename, "Images/Game/Barrier_%02d_01.png", m_barrierType); // Barrier_01_01 ui::Button *button = ui::Button::create(filename); button->addClickEventListener(CC_CALLBACK_1(Barrier::ClickBarrier, this)); button->setOpacity(0); addChild(button); // Barrier Area sprintf(filename, "Data/Barrier/Barrier_Type_%d.json", m_barrierType); char buffer[100]; FILE *file = fopen(filename, "r"); rapidjson::FileReadStream is(file, buffer, sizeof(buffer)); rapidjson::Document document; document.ParseStream(is); fclose(file); rapidjson::Value &positionArray = document["position"]; for (auto iter = positionArray.Begin(); iter != positionArray.End(); iter++) { Vec2 position; position.x = (float)(*iter)["x"].GetInt(); position.y = (float)(*iter)["y"].GetInt(); m_barrierArea.emplace_back(position); } rapidjson::Value &areaArray = document["area"]; for (auto iter = areaArray.Begin(); iter != areaArray.End(); iter++) { Vec2 position; Vec2 scale; position.x = (float)(*iter)["x"].GetInt(); position.y = (float)(*iter)["y"].GetInt(); scale.x = (float)(*iter)["scale_x"].GetDouble(); scale.y = (float)(*iter)["scale_y"].GetDouble(); //m_barrierArea.emplace_back(position); } // Animation Size buttonSize = button->getContentSize(); Sprite *sprite = Sprite::create(filename); sprite->setPosition(buttonSize.width / 2.0f, buttonSize.height / 2.0f); Animation *animation = Animation::create(); for (int i = 0; i < 6; i++) { sprintf(filename, "Images/Game/Barrier_%02d_%02d.png", m_barrierType, i + 1); animation->addSpriteFrameWithFile(filename); } animation->setDelayPerUnit(0.1f); animation->setRestoreOriginalFrame(true); Animate *animate = Animate::create(animation); RepeatForever *repeatForever = RepeatForever::create(animate); sprite->runAction(repeatForever); button->addChild(sprite); ui::Button *buttonDemolish = ui::Button::create("Images/Game/temp_x.png"); buttonDemolish->setPosition(Vec2(buttonSize.width, buttonSize.height)); buttonDemolish->setVisible(false); buttonDemolish->addClickEventListener(CC_CALLBACK_1(Barrier::ClickDemolish, this)); buttonDemolish->setName("Button_Demolish"); button->addChild(buttonDemolish, 1); // Event EventListenerCustom *eventListener = EventListenerCustom::create("Object_Menu_Close", CC_CALLBACK_1(Barrier::ObjectMenuClose, this)); _eventDispatcher->addEventListenerWithSceneGraphPriority(eventListener, this); return true; }
void AnimationSet::load() { assert(!loaded); loaded = true; FileParser parser; // @CLASS Animation|Description of animations in animations/ if (!parser.open(name, true, "Error loading animation definition: " + name)) return; string _name = ""; int position = 0; int frames = 0; int duration = 0; Point render_size; Point render_offset; string type = ""; string starting_animation = ""; bool first_section=true; bool compressed_loading=false; // is reset every section to false, set by frame keyword Animation *newanim = NULL; vector<short> active_frames; // Parse the file and on each new section create an animation object from the data parsed previously while (parser.next()) { // create the animation if finished parsing a section if (parser.new_section) { if (!first_section && !compressed_loading) { Animation *a = new Animation(_name, type, sprite); a->setupUncompressed(render_size, render_offset, position, frames, duration); if (!active_frames.empty()) a->setActiveFrames(active_frames); active_frames.clear(); animations.push_back(a); } first_section = false; compressed_loading = false; } if (parser.key == "image") { // @ATTR image|string|Filename of sprite-sheet image. if (sprite != NULL) { printf("multiple images specified in %s, dragons be here!\n", name.c_str()); SDL_Quit(); exit(128); } sprite = render_device->loadImage(parser.val); } else if (parser.key == "position") { // @ATTR position|integer|Number of frames to the right to use as the first frame. Unpacked animations only. position = toInt(parser.val); } else if (parser.key == "frames") { // @ATTR frames|integer|The total number of frames frames = toInt(parser.val); } else if (parser.key == "duration") { // @ATTR duration|integer|The duration of each frame. duration = parse_duration(parser.val); } else if (parser.key == "type") // @ATTR type|[play_once, back_forth, looped]|How to loop (or not loop) this animation. type = parser.val; else if (parser.key == "render_size") { // @ATTR render_size|w (integer), h (integer)|Width and height of animation. render_size.x = toInt(parser.nextValue()); render_size.y = toInt(parser.nextValue()); } else if (parser.key == "render_offset") { // @ATTR render_offset|x (integer), y (integer)|Render x/y offset. render_offset.x = toInt(parser.nextValue()); render_offset.y = toInt(parser.nextValue()); } else if (parser.key == "active_frame") { // @ATTR active_frame|[all:frame (integer), ...]|A list of frames marked as "active". Also, "all" can be used to mark all frames as active. active_frames.clear(); string nv = parser.nextValue(); if (nv == "all") { active_frames.push_back(-1); } else { while (nv != "") { active_frames.push_back(toInt(nv)); nv = parser.nextValue(); } sort(active_frames.begin(), active_frames.end()); active_frames.erase(unique(active_frames.begin(), active_frames.end()), active_frames.end()); } } else if (parser.key == "frame") { // @ATTR frame|index (integer), direction (integer), x (integer), y (integer), w (integer), h (integer), x offset (integer), y offset (integer)|A single frame of a compressed animation. if (compressed_loading == false) { // first frame statement in section newanim = new Animation(_name, type, sprite); newanim->setup(frames, duration); if (!active_frames.empty()) newanim->setActiveFrames(active_frames); active_frames.clear(); animations.push_back(newanim); compressed_loading = true; } // frame = index, direction, x, y, w, h, offsetx, offsety Rect r; Point offset; const int index = toInt(parser.nextValue()); const int direction = toInt(parser.nextValue()); r.x = toInt(parser.nextValue()); r.y = toInt(parser.nextValue()); r.w = toInt(parser.nextValue()); r.h = toInt(parser.nextValue()); offset.x = toInt(parser.nextValue()); offset.y = toInt(parser.nextValue()); newanim->addFrame(index, direction, r, offset); } else { fprintf(stderr, "animations definitions (%s): Key %s not supported!\n", parser.getFileName().c_str(), parser.key.c_str()); } if (_name == "") { // This is the first animation starting_animation = parser.section; } _name = parser.section; } if (!compressed_loading) { // add final animation Animation *a = new Animation(_name, type, sprite); a->setupUncompressed(render_size, render_offset, position, frames, duration); if (!active_frames.empty()) a->setActiveFrames(active_frames); active_frames.clear(); animations.push_back(a); } if (starting_animation != "") { Animation *a = getAnimation(starting_animation); delete defaultAnimation; defaultAnimation = a; } }
bool AnimationController::Play(const String& name, unsigned char layer, bool looped, float fadeInTime) { // ATOMIC BEGIN Animation* newAnimation = 0; // Check if we're using attached animation resource if (animation_.NotNull() && animation_->GetAnimationName() == name) { newAnimation = animation_; } else { for (unsigned i = 0; i < animationResources_.Size(); i++) { if (name == animationResources_[i]->GetAnimationName()) { newAnimation = animationResources_[i]; break; } } } // Get the animation resource first to be able to get the canonical resource name // (avoids potential adding of duplicate animations) if (!newAnimation) newAnimation = GetSubsystem<ResourceCache>()->GetResource<Animation>(name); if (!newAnimation) return false; // ATOMIC END // Check if already exists unsigned index; AnimationState* state; FindAnimation(newAnimation->GetName(), index, state); if (!state) { state = AddAnimationState(newAnimation); if (!state) return false; } if (index == M_MAX_UNSIGNED) { AnimationControl newControl; newControl.name_ = newAnimation->GetName(); newControl.hash_ = newAnimation->GetNameHash(); animations_.Push(newControl); index = animations_.Size() - 1; } state->SetLayer(layer); state->SetLooped(looped); animations_[index].targetWeight_ = 1.0f; animations_[index].fadeTime_ = fadeInTime; MarkNetworkUpdate(); return true; }
void LevelMainCharacter::load() { setBoundingBox(sf::FloatRect(0.f, 0.f, 30.f, 100.f)); setSpriteOffset(sf::Vector2f(-25.f, -20.f)); Animation walkingAnimation; walkingAnimation.setSpriteSheet(g_resourceManager->getTexture(ResourceID::Texture_mainChar)); walkingAnimation.addFrame(sf::IntRect(0, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(80, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(160, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(240, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(320, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(400, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(480, 0, 80, 120)); walkingAnimation.addFrame(sf::IntRect(560, 0, 80, 120)); addAnimation(GameObjectState::Walking, walkingAnimation); Animation idleAnimation; idleAnimation.setSpriteSheet(g_resourceManager->getTexture(ResourceID::Texture_mainChar)); idleAnimation.addFrame(sf::IntRect(640, 0, 80, 120)); addAnimation(GameObjectState::Idle, idleAnimation); Animation jumpingAnimation; jumpingAnimation.setSpriteSheet(g_resourceManager->getTexture(ResourceID::Texture_mainChar)); jumpingAnimation.addFrame(sf::IntRect(720, 0, 80, 120)); addAnimation(GameObjectState::Jumping, jumpingAnimation); Animation fightingAnimation; fightingAnimation.setSpriteSheet(g_resourceManager->getTexture(ResourceID::Texture_mainChar)); fightingAnimation.addFrame(sf::IntRect(800, 0, 80, 120)); fightingAnimation.addFrame(sf::IntRect(880, 0, 80, 120)); fightingAnimation.addFrame(sf::IntRect(960, 0, 80, 120)); fightingAnimation.addFrame(sf::IntRect(1040, 0, 80, 120)); fightingAnimation.addFrame(sf::IntRect(1040, 0, 80, 120)); addAnimation(GameObjectState::Fighting, fightingAnimation); Animation deadAnimation; deadAnimation.setSpriteSheet(g_resourceManager->getTexture(ResourceID::Texture_mainChar)); deadAnimation.addFrame(sf::IntRect(1120, 0, 80, 120)); addAnimation(GameObjectState::Dead, deadAnimation); setFrameTime(sf::seconds(0.07f)); // initial values m_state = GameObjectState::Idle; m_isFacingRight = true; setCurrentAnimation(getAnimation(m_state), !m_isFacingRight); playCurrentAnimation(true); setDebugBoundingBox(sf::Color::White); }
void AnimationTimeline::animationAttached(Animation& animation) { DCHECK_EQ(animation.timeline(), this); DCHECK(!m_animations.contains(&animation)); m_animations.add(&animation); }
void DialogCharacter::Update(int delta, string &emotionId, bool finishOneTimeEmotions, bool isInBackground) { if (emotionId.length() == 0) { emotionId = defaultEmotionId; } if (characterOneTimeEmotions.count(emotionId) > 0) { OneTimeEmotion *pOneTimeEmotion = characterOneTimeEmotions[emotionId]; Video *pVideo = pOneTimeEmotion->GetVideo(); if (finishOneTimeEmotions) { pVideo->Finish(); } else { pVideo->Update(delta); } if (pVideo->IsFinished() && pOneTimeEmotion->GetTransitionToEmotion().length() > 0) { pVideo->Reset(); emotionId = pOneTimeEmotion->GetTransitionToEmotion(); } else { return; } } vector<Animation *> *pForegroundLayers = GetForegroundLayersForEmotion(emotionId); if (pForegroundLayers != NULL) { for (unsigned int i = 0; i < pForegroundLayers->size(); i++) { Animation *pAnimation = (*pForegroundLayers)[i]; pAnimation->Update(delta); } } // If this emotion is currently in the background (e.g., if the character is currently zoomed), // then we won't bother updating the eye frame duration list. if (isInBackground || characterEmotionEyeSpriteIds.count(emotionId) == 0) { return; } if (eyeFrameDurationList.size() == 0 || eyeFrameDurationList.size() != characterEmotionEyeSpriteIds[emotionId].size()) { PopulateEyeFrameDurationList(emotionId); } msElapsedCurrentEyeFrame += delta; while (msElapsedCurrentEyeFrame > eyeFrameDurationList[currentEyeFrame]) { msElapsedCurrentEyeFrame -= eyeFrameDurationList[currentEyeFrame]; currentEyeFrame++; // If we've reached the end, then we'll wrap back around and get a // new random number representing the time until the next eye blink. if (currentEyeFrame >= eyeFrameDurationList.size()) { currentEyeFrame = 0; eyeFrameDurationList[0] = (int)(rand() % 2001) + 2000; } } }
void World::Render() { City* c; Animation* a; int tileScaleW = visualMap->GetTileWidth() * visualMapScale->X; int tileScaleH = visualMap->GetTileHeight() * visualMapScale->Y; int tileCentreX; int tileCentreY; visualMap->Render( 0, 0, visualMapScale->X, visualMapScale->Y ); // Draw shadow for( std::vector<City*>::iterator ci = Cities.begin(); ci != Cities.end(); ci++ ) { c = (City*)(*ci); tileCentreX = (c->MapPosition->X * tileScaleW) + (tileScaleW / 2); tileCentreY = (c->MapPosition->Y * tileScaleH) + (tileScaleH / 2); al_draw_filled_ellipse( tileCentreX, tileCentreY, (tileScaleW / 1.5), (tileScaleH / 4), al_map_rgba( 0, 0, 0, 128 ) ); } if( !IsBetweenTurns ) { for( int li = 0; li < Cities.at(AgentWillis->CurrentCity)->LinkedCityNumbers.size(); li++ ) { Vector2* la = Cities.at(AgentWillis->CurrentCity)->MapPosition; Vector2* lb = Cities.at(Cities.at(AgentWillis->CurrentCity)->LinkedCityNumbers.at(li))->MapPosition; al_draw_line( (la->X * tileScaleW) + (tileScaleW / 2), (la->Y * tileScaleH) + (tileScaleH / 2), (lb->X * tileScaleW) + (tileScaleW / 2), (lb->Y * tileScaleH) + (tileScaleH / 2), al_map_rgba( 0, 0, 0, 64 ), 3.0f ); } // Draw Navigation Lines if( visualNavigationLineIndex > 0 ) { Line* l = new Line( Cities.at(AgentWillis->CurrentCity)->MapPosition, Cities.at(AgentWillis->TargetCity)->MapPosition ); Vector2* segA = l->GetSegmentPoint( visualNavigationLineIndex, WORLD_NAVIGATION_LINE_SEGMENTS ); Vector2* segB = l->GetSegmentPoint( visualNavigationLineIndex - 1, WORLD_NAVIGATION_LINE_SEGMENTS ); segA->X = (segA->X * tileScaleW) + (tileScaleW / 2); segA->Y = (segA->Y * tileScaleH) + (tileScaleH / 2); segB->X = (segB->X * tileScaleW) + (tileScaleW / 2); segB->Y = (segB->Y * tileScaleH) + (tileScaleH / 2); al_draw_line( segA->X, segA->Y, segB->X, segB->Y, al_map_rgba( 255, 240, 64, 192 ), 3.0f ); } } // Draw Weather Indicator for( std::vector<City*>::iterator ci = Cities.begin(); ci != Cities.end(); ci++ ) { c = (City*)(*ci); a = WeatherAnimations.at( c->WeatherCondition ); tileCentreX = (c->MapPosition->X * tileScaleW) + (tileScaleW / 2); tileCentreY = (c->MapPosition->Y * tileScaleH) + (tileScaleH / 2); a->DrawFrame( tileCentreX - (visualSprites->GetFrame(0)->Width / 2), tileCentreY - visualSprites->GetFrame(0)->Height); } ProfessorFrost->WorldRender(); AgentWillis->WorldRender(); al_draw_filled_rectangle( 0, FRAMEWORK->Display_GetHeight() - (textFontHeight * 3), FRAMEWORK->Display_GetWidth(), FRAMEWORK->Display_GetHeight(), al_map_rgb( 0, 0, 0 ) ); int curY = FRAMEWORK->Display_GetHeight() - (textFontHeight * 3); int tmpX = (FRAMEWORK->Display_GetWidth() / 2) + 20; al_draw_text( textFont, al_map_rgb( 255, 255, 0 ), 20, curY, 0, Cities.at( AgentWillis->CurrentCity )->Name->c_str() ); al_draw_text( textFont, al_map_rgb( 255, 255, 0 ), tmpX, curY, 0, Cities.at( AgentWillis->TargetCity )->Name->c_str() ); curY += textFontHeight; al_draw_textf( textFont, al_map_rgb( 255, 255, 0 ), 20, curY, 0, "Population: %d", (int)(Cities.at( AgentWillis->CurrentCity )->Population * 1000.0) ); al_draw_textf( textFont, al_map_rgb( 255, 255, 0 ), tmpX, curY, 0, "Population: %d", (int)(Cities.at( AgentWillis->TargetCity )->Population * 1000.0) ); curY += textFontHeight; }
nsIStyleRule* nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, mozilla::dom::Element* aElement) { if (!mPresContext->IsDynamic()) { // For print or print preview, ignore animations. return nullptr; } // Everything that causes our animation data to change triggers a // style change, which in turn triggers a non-animation restyle. // Likewise, when we initially construct frames, we're not in a // style change, but also not in an animation restyle. const nsStyleDisplay* disp = aStyleContext->StyleDisplay(); AnimationCollection* collection = GetAnimations(aElement, aStyleContext->GetPseudoType(), false); if (!collection && disp->mAnimationNameCount == 1 && disp->mAnimations[0].GetName().IsEmpty()) { return nullptr; } nsAutoAnimationMutationBatch mb(aElement); // build the animations list dom::DocumentTimeline* timeline = aElement->OwnerDoc()->Timeline(); AnimationPtrArray newAnimations; if (!aStyleContext->IsInDisplayNoneSubtree()) { BuildAnimations(aStyleContext, aElement, timeline, newAnimations); } if (newAnimations.IsEmpty()) { if (collection) { // There might be transitions that run now that animations don't // override them. mPresContext->TransitionManager()-> UpdateCascadeResultsWithAnimationsToBeDestroyed(collection); collection->Destroy(); } return nullptr; } if (collection) { collection->mStyleRule = nullptr; collection->mStyleRuleRefreshTime = TimeStamp(); collection->UpdateAnimationGeneration(mPresContext); // Copy over the start times and (if still paused) pause starts // for each animation (matching on name only) that was also in the // old list of animations. // This means that we honor dynamic changes, which isn't what the // spec says to do, but WebKit seems to honor at least some of // them. See // http://lists.w3.org/Archives/Public/www-style/2011Apr/0079.html // In order to honor what the spec said, we'd copy more data over // (or potentially optimize BuildAnimations to avoid rebuilding it // in the first place). if (!collection->mAnimations.IsEmpty()) { for (size_t newIdx = newAnimations.Length(); newIdx-- != 0;) { Animation* newAnim = newAnimations[newIdx]; // Find the matching animation with this name in the old list // of animations. We iterate through both lists in a backwards // direction which means that if there are more animations in // the new list of animations with a given name than in the old // list, it will be the animations towards the of the beginning of // the list that do not match and are treated as new animations. nsRefPtr<CSSAnimation> oldAnim; size_t oldIdx = collection->mAnimations.Length(); while (oldIdx-- != 0) { CSSAnimation* a = collection->mAnimations[oldIdx]->AsCSSAnimation(); MOZ_ASSERT(a, "All animations in the CSS Animation collection should" " be CSSAnimation objects"); if (a->AnimationName() == newAnim->AsCSSAnimation()->AnimationName()) { oldAnim = a; break; } } if (!oldAnim) { continue; } bool animationChanged = false; // Update the old from the new so we can keep the original object // identity (and any expando properties attached to it). if (oldAnim->GetEffect() && newAnim->GetEffect()) { KeyframeEffectReadOnly* oldEffect = oldAnim->GetEffect(); KeyframeEffectReadOnly* newEffect = newAnim->GetEffect(); animationChanged = oldEffect->Timing() != newEffect->Timing() || oldEffect->Properties() != newEffect->Properties(); oldEffect->Timing() = newEffect->Timing(); oldEffect->Properties() = newEffect->Properties(); } // Reset compositor state so animation will be re-synchronized. oldAnim->ClearIsRunningOnCompositor(); // Handle changes in play state. If the animation is idle, however, // changes to animation-play-state should *not* restart it. if (oldAnim->PlayState() != AnimationPlayState::Idle) { // CSSAnimation takes care of override behavior so that, // for example, if the author has called pause(), that will // override the animation-play-state. // (We should check newAnim->IsStylePaused() but that requires // downcasting to CSSAnimation and we happen to know that // newAnim will only ever be paused by calling PauseFromStyle // making IsPausedOrPausing synonymous in this case.) if (!oldAnim->IsStylePaused() && newAnim->IsPausedOrPausing()) { oldAnim->PauseFromStyle(); animationChanged = true; } else if (oldAnim->IsStylePaused() && !newAnim->IsPausedOrPausing()) { oldAnim->PlayFromStyle(); animationChanged = true; } } if (animationChanged) { nsNodeUtils::AnimationChanged(oldAnim); } // Replace new animation with the (updated) old one and remove the // old one from the array so we don't try to match it any more. // // Although we're doing this while iterating this is safe because // we're not changing the length of newAnimations and we've finished // iterating over the list of old iterations. newAnim->CancelFromStyle(); newAnim = nullptr; newAnimations.ReplaceElementAt(newIdx, oldAnim); collection->mAnimations.RemoveElementAt(oldIdx); // We've touched the old animation's timing properties, so this // could update the old animation's relevance. oldAnim->UpdateRelevance(); } } } else { collection = GetAnimations(aElement, aStyleContext->GetPseudoType(), true); } collection->mAnimations.SwapElements(newAnimations); collection->mNeedsRefreshes = true; collection->Tick(); // Cancel removed animations for (size_t newAnimIdx = newAnimations.Length(); newAnimIdx-- != 0; ) { newAnimations[newAnimIdx]->CancelFromStyle(); } UpdateCascadeResults(aStyleContext, collection); TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh(); UpdateStyleAndEvents(collection, refreshTime, EnsureStyleRule_IsNotThrottled); // We don't actually dispatch the mPendingEvents now. We'll either // dispatch them the next time we get a refresh driver notification // or the next time somebody calls // nsPresShell::FlushPendingNotifications. if (!mPendingEvents.IsEmpty()) { mPresContext->Document()->SetNeedStyleFlush(); } return GetAnimationRule(aElement, aStyleContext->GetPseudoType()); }
//--------------------------------------------------------------------- void Skeleton::_dumpContents(const String& filename) { std::ofstream of; Quaternion q; Radian angle; Vector3 axis; of.open(filename.c_str()); of << "-= Debug output of skeleton " << mName << " =-" << std::endl << std::endl; of << "== Bones ==" << std::endl; of << "Number of bones: " << (unsigned int)mBoneList.size() << std::endl; BoneList::iterator bi; for (bi = mBoneList.begin(); bi != mBoneList.end(); ++bi) { Bone* bone = *bi; of << "-- Bone " << bone->getHandle() << " --" << std::endl; of << "Position: " << bone->getPosition(); q = bone->getOrientation(); of << "Rotation: " << q; q.ToAngleAxis(angle, axis); of << " = " << angle.valueRadians() << " radians around axis " << axis << std::endl << std::endl; } of << "== Animations ==" << std::endl; of << "Number of animations: " << (unsigned int)mAnimationsList.size() << std::endl; AnimationList::iterator ai; for (ai = mAnimationsList.begin(); ai != mAnimationsList.end(); ++ai) { Animation* anim = ai->second; of << "-- Animation '" << anim->getName() << "' (length " << anim->getLength() << ") --" << std::endl; of << "Number of tracks: " << anim->getNumNodeTracks() << std::endl; for (unsigned short ti = 0; ti < anim->getNumNodeTracks(); ++ti) { NodeAnimationTrack* track = anim->getNodeTrack(ti); of << " -- AnimationTrack " << ti << " --" << std::endl; of << " Affects bone: " << ((Bone*)track->getAssociatedNode())->getHandle() << std::endl; of << " Number of keyframes: " << track->getNumKeyFrames() << std::endl; for (unsigned short ki = 0; ki < track->getNumKeyFrames(); ++ki) { TransformKeyFrame* key = track->getNodeKeyFrame(ki); of << " -- KeyFrame " << ki << " --" << std::endl; of << " Time index: " << key->getTime(); of << " Translation: " << key->getTranslate() << std::endl; q = key->getRotation(); of << " Rotation: " << q; q.ToAngleAxis(angle, axis); of << " = " << angle.valueRadians() << " radians around axis " << axis << std::endl; } } } }
// https://w3c.github.io/web-animations/#setting-the-target-effect void Animation::SetEffectNoUpdate(AnimationEffectReadOnly* aEffect) { RefPtr<Animation> kungFuDeathGrip(this); if (mEffect == aEffect) { return; } AutoMutationBatchForAnimation mb(*this); bool wasRelevant = mIsRelevant; if (mEffect) { if (!aEffect) { // If the new effect is null, call ResetPendingTasks before clearing // mEffect since ResetPendingTasks needs it to get the appropriate // PendingAnimationTracker. ResetPendingTasks(); } // We need to notify observers now because once we set mEffect to null // we won't be able to find the target element to notify. if (mIsRelevant) { nsNodeUtils::AnimationRemoved(this); } // Break links with the old effect and then drop it. RefPtr<AnimationEffectReadOnly> oldEffect = mEffect; mEffect = nullptr; oldEffect->SetAnimation(nullptr); // The following will not do any notification because mEffect is null. UpdateRelevance(); } if (aEffect) { // Break links from the new effect to its previous animation, if any. RefPtr<AnimationEffectReadOnly> newEffect = aEffect; Animation* prevAnim = aEffect->GetAnimation(); if (prevAnim) { prevAnim->SetEffect(nullptr); } // Create links with the new effect. SetAnimation(this) will also update // mIsRelevant of this animation, and then notify mutation observer if // needed by calling Animation::UpdateRelevance(), so we don't need to // call it again. mEffect = newEffect; mEffect->SetAnimation(this); // Notify possible add or change. // If the target is different, the change notification will be ignored by // AutoMutationBatchForAnimation. if (wasRelevant && mIsRelevant) { nsNodeUtils::AnimationChanged(this); } // Reschedule pending pause or pending play tasks. // If we have a pending animation, it will either be registered // in the pending animation tracker and have a null pending ready time, // or, after it has been painted, it will be removed from the tracker // and assigned a pending ready time. // After updating the effect we'll typically need to repaint so if we've // already been assigned a pending ready time, we should clear it and put // the animation back in the tracker. if (!mPendingReadyTime.IsNull()) { mPendingReadyTime.SetNull(); nsIDocument* doc = GetRenderedDocument(); if (doc) { PendingAnimationTracker* tracker = doc->GetOrCreatePendingAnimationTracker(); if (mPendingState == PendingState::PlayPending) { tracker->AddPlayPending(*this); } else { tracker->AddPausePending(*this); } } } } UpdateTiming(SeekFlag::NoSeek, SyncNotifyFlag::Async); }