int add_keyframe(lua_State* state) { int args = lua_gettop(state); if(args != 4 && args != 5 && args != 8) { luaL_error(state, "Invalid number of arguments for adding keyframes"); } if(!lua_isstring(state, 1)) { return luaL_argerror(state, 1, "animation name expected"); } if(!lua_isnumber(state, 2)) { return luaL_argerror(state, 2, "time value expected"); } if(!lua_isnumber(state, 3)) { return luaL_argerror(state, 3, "transition state expected"); } if(!lua_isnumber(state, 4)) { return luaL_argerror(state, 4, "attribute expected"); } if(args == 5 && !lua_isnumber(state, 5)) { return luaL_argerror(state, 5, "tween type expected"); } if(args == 8) { for(int i = 5; i != 8; i++) { if(!lua_isnumber(state, i)) { return luaL_argerror(state, i, "control point coordinate expected"); } } } lua_getglobal(state, "renderer"); OpticRender* render = static_cast<OpticRender*>(lua_touserdata(state, -1)); lua_pop(state, 1); try { if(args == 4) { render->addKeyframe(lua_tostring(state, 1), Keyframe(lua_tointeger(state, 2), lua_tonumber(state, 3)), TRANSFORM(lua_tointeger(state, 4)), LINEAR); } else if(args == 5) { render->addKeyframe(lua_tostring(state, 1), Keyframe(lua_tointeger(state, 2), lua_tonumber(state, 3)), TRANSFORM(lua_tointeger(state, 4)), TWEEN(lua_tointeger(state, 5))); } else { OpticBezier bezier(lua_tonumber(state, 5), lua_tonumber(state, 6), lua_tonumber(state, 7), lua_tonumber(state, 8)); render->addKeyframe(lua_tostring(state, 1), Keyframe(lua_tointeger(state, 2), lua_tonumber(state, 3)), TRANSFORM(lua_tointeger(state, 4)), bezier); } } catch(OpticException& e) { luaL_error(state, e.what()); } return 0; }
Qgs3DAnimationSettings::Keyframe Qgs3DAnimationSettings::interpolate( float time ) const { if ( mKeyframes.isEmpty() ) return Keyframe(); if ( time < mKeyframes.constFirst().time ) { return mKeyframes.first(); } else if ( time >= mKeyframes.constLast().time ) { return mKeyframes.last(); } else { // TODO: make easing curves configurable. // QEasingCurve is probably not flexible enough, we may need more granular // control with Bezier curves to allow smooth transition at keyframes for ( int i = 0; i < mKeyframes.size() - 1; i++ ) { const Keyframe &k0 = mKeyframes.at( i ); const Keyframe &k1 = mKeyframes.at( i + 1 ); if ( time >= k0.time && time <= k1.time ) { float ip = ( time - k0.time ) / ( k1.time - k0.time ); float eIp = mEasingCurve.valueForProgress( ip ); float eIip = 1.0f - eIp; Keyframe kf; kf.time = time; kf.point.set( k0.point.x() * eIip + k1.point.x() * eIp, k0.point.y() * eIip + k1.point.y() * eIp, k0.point.z() * eIip + k1.point.z() * eIp ); kf.dist = k0.dist * eIip + k1.dist * eIp; kf.pitch = k0.pitch * eIip + k1.pitch * eIp; // always use shorter angle float yaw0 = fmod( k0.yaw, 360 ), yaw1 = fmod( k1.yaw, 360 ); if ( std::abs( yaw0 - yaw1 ) > 180 ) { if ( yaw0 < yaw1 ) yaw0 += 360; else yaw1 += 360; } kf.yaw = yaw0 * eIip + yaw1 * eIp; return kf; } } } Q_ASSERT( false ); return Keyframe(); }
Keyframe estimatedNextKeyframe(Keyframe const keyframe1, Keyframe const keyframe2, size_t next_time) { double diff_frame = keyframe2.getFrame() - keyframe1.getFrame(); double x = (keyframe2.getX() - keyframe1.getX()) / diff_frame; double y = (keyframe2.getY() - keyframe1.getY()) / diff_frame; double z = (keyframe2.getZ() - keyframe1.getZ()) / diff_frame; double frame = next_time - keyframe2.getFrame(); return Keyframe(next_time, x * frame, y * frame, z * frame); }
/// output: a new motion primitive void BVHMotionDatabaseCompiler::CreateMotionPrimitive( MotionPrimitiveDesc& desc, const MotionPrimitiveDescGroup& desc_group, BVHPlayer& bvh_player ) { vector<Keyframe> vecKeyframe; vecKeyframe.reserve( 64 ); // add a new motion primitive and get the reference to it shared_ptr<MotionPrimitive> pMotion( new MotionPrimitive( desc.m_Name ) ); m_pvecpMotionPrimitive->push_back( pMotion ); desc.m_pMotionPrimitive = pMotion; MotionPrimitive& motion = *(m_pvecpMotionPrimitive->back()); motion.SetSkeleton( desc_group.m_Skeleton ); motion.SetLoopedMotion( desc.m_bIsLoopMotion ); motion.SetStartsBoneName( desc.m_StartBoneName ); vecKeyframe.resize(0); int i = 0; int frame = 0; int start = desc.m_StartFrame; int end = desc.m_EndFrame; float time_per_frame = bvh_player.GetFrameTime(); // create keyframes for( frame = start, i=0; frame <= end; frame++, i++ ) { float frame_time = (float)frame * time_per_frame; bvh_player.SetWorldTransformation( frame_time ); // extract world transforms BVHBone *pRootBone = bvh_player.GetRootBone(); // create keyframe from frametime and transformation hierarchy vecKeyframe.push_back( Keyframe( (float)i * time_per_frame, TransformNode( *pRootBone ) ) ); } // modify root position if( 0 < vecKeyframe.size() && desc.m_bResetHorizontalRootPos ) { Matrix34 root_pose = vecKeyframe[0].GetRootPose(); Vector3 vBasePosH = root_pose.vPosition; vBasePosH.y = 0; BOOST_FOREACH( Keyframe& keyframe, vecKeyframe ) { root_pose = keyframe.GetRootPose(); root_pose.vPosition = root_pose.vPosition - vBasePosH; keyframe.SetRootPose( root_pose ); }
void KeyframeWidget::addKeyframe() { if(cache_.joint == NULL) { fprintf(stderr, "No joint block, can't add keyframes.\n"); return; } auto kf = Keyframe(ssprintf("Keyframe %i", keyframeBox->count())); for(int i = 0; i < NUM_JOINTS; i++) kf.joints[i] = cache_.joint->values_[i]; auto kfitem = new KeyframeItem(keyframeBox, kf); }
Line::Line(Keyframe start, Keyframe end) { double diff_frame = end.getFrame() - start.getFrame(); double dx = (end.getX() - start.getX()) / diff_frame; double dy = (end.getY() - start.getY()) / diff_frame; double dz = (end.getZ() - start.getZ()) / diff_frame; for (size_t t = start.getFrame(); t <= (end.getFrame() - start.getFrame()); ++t) { m_video.push_back(Keyframe(t, dx * (double)t, dy * (double)t, dz * (double)t)); } }
/* * Loader for AAA files */ int LoadAAA(string filename, KeyframeAnimation& anim) { ifstream file(filename.c_str(), ios::in | ios::binary); if(!file) return 1; unsigned char anim_name_len = ReadByte(file); string anim_name = ""; for(unsigned int i = 0; i < anim_name_len; ++i) anim_name += ReadByte(file); unsigned int frame_count = ReadUInt32(file); vector<Keyframe> frames = vector<Keyframe>(); for(unsigned int i = 0; i < frame_count; ++i) { Keyframe frame = Keyframe(); frame.next = ReadInt32(file); frame.duration = ReadSingle(file); unsigned int bone_count = ReadUInt32(file); for(unsigned int j = 0; j < bone_count; ++j) { string bone_name = ""; unsigned char bone_name_len = ReadByte(file); for(unsigned int k = 0; k < bone_name_len; ++k) bone_name += ReadByte(file); Vec3 ori; ori.x = ReadSingle(file); ori.y = ReadSingle(file); ori.z = ReadSingle(file); Vec3 pos; pos.x = ReadSingle(file); pos.y = ReadSingle(file); pos.z = ReadSingle(file); frame.values[Bone::string_table[bone_name]] = BoneInfluence(ori, pos, 1.0f); } frames.push_back(frame); } anim.name = anim_name; anim.frames = frames; return 0; }
bool appendKeyframeWithCustomBezierTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, double x1, double y1, double x2, double y2, const FloatSize&) { curve->add(Keyframe(keyTime, value->value()), x1, y1, x2, y2); return true; }
bool appendKeyframeWithStandardTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize&) { curve->add(Keyframe(keyTime, value->value()), timingFunctionType); return true; }
OpticAnimation OpticMedal::defaultSlideAnimation() { OpticAnimation animation; animation.addKeyframe(Keyframe(0, 0.0f), KEYFRAME_POSITION_X); animation.addKeyframe(Keyframe(150, 1.0f), KEYFRAME_POSITION_X); return animation; }
Replay::Replay(QString filepath, bool loadInfosOnly) { QFile file(filepath); m_filepath = filepath; if(file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); in.setCodec("UTF-8"); while(!in.atEnd()) { QString line = in.readLine(); if(!loadInfosOnly && line.startsWith("::ORChunk:")) { // A Chunk line ::ORChunk:id:keyframeid:duration:data:: line.remove(0, 10); line.chop(2); QStringList elements = line.split(':', QString::KeepEmptyParts); if(elements.size() >= 4){ int chunkid = elements.at(0).toInt(); int keyframeid = elements.at(1).toInt(); int chunkduration = elements.at(2).toInt(); if(chunkid <= m_endstartupchunkid.toInt()) { m_primarychunks.append(Chunk(chunkid, QByteArray::fromBase64(elements.at(3).toLocal8Bit()), keyframeid, chunkduration)); } else { m_chunks.append(Chunk(chunkid, QByteArray::fromBase64(elements.at(3).toLocal8Bit()), keyframeid, chunkduration)); } } } else if(!loadInfosOnly && line.startsWith("::ORKeyFrame:")) { // A KeyFrame line ::ORKeyFrame:id:nextchunkid:data:: line.remove(0, 13); line.chop(2); QStringList elements = line.split(':', QString::KeepEmptyParts); if(elements.size() >= 3){ int keyframeid = elements.at(0).toInt(); int nextchunkid = elements.at(1).toInt(); m_keyframes.append(Keyframe(keyframeid, QByteArray::fromBase64(elements.at(2).toLocal8Bit()), nextchunkid)); } } else if(line.startsWith("::ORHeader:")) { // File Header ::ORHeader:platformid:gameid:encryptionkey:serverversion:endstartupchunkid:startgamechunkid:: line.remove(0, 11); line.chop(2); QStringList elements = line.split(':', QString::KeepEmptyParts); if(elements.size() >= 6){ m_platformid = elements.at(0); m_gameid = elements.at(1); m_encryptionkey = elements.at(2); m_serverversion = elements.at(3); m_endstartupchunkid = elements.at(4); m_startgamechunkid = elements.at(5); } } else if(line.startsWith("::ORGameInfos:")) { line.remove(0, 14); line.chop(2); m_gameinfos = QJsonDocument::fromJson(QByteArray::fromBase64(line.toLocal8Bit())); } else if(line.startsWith("::ORGameStats:")) { line.remove(0, 14); line.chop(2); m_endofgamestats = QByteArray::fromBase64(line.toLocal8Bit()); } else if(line == "::OREnd::") { break; } if(loadInfosOnly && !m_gameinfos.isEmpty() && !m_endofgamestats.isEmpty() && !m_encryptionkey.isEmpty()){ break; } } file.close(); if(m_encryptionkey.isEmpty() && !m_gameinfos.isEmpty() && !m_gameinfos.object().value("observers").toObject().value("encryptionKey").toString().isEmpty()){ m_encryptionkey = m_gameinfos.object().value("observers").toObject().value("encryptionKey").toString(); } if(m_platformid.isEmpty() && !m_gameinfos.isEmpty() && !m_gameinfos.object().value("platformId").toString().isEmpty()){ m_platformid = m_gameinfos.object().value("platformId").toString(); } if(m_gameid.isEmpty() && !m_gameinfos.isEmpty() && m_gameinfos.object().value("gameId").toVariant().toULongLong() != 0){ m_gameid = QString::number(m_gameinfos.object().value("gameId").toVariant().toULongLong()); } } else{ //ERROR : cannot open the file } }
void parseKeyframe(FILE* ifile ,vector<Keyframe>& keyframe) { int vid, fid; while (fscanf(ifile, "%d %d", &vid, &fid) == 2) { keyframe.push_back(Keyframe(vid, fid)); } }
bool Channel::Load(Tokenizer &token) { char temp[256]; token.FindToken("extrapolate"); for (int j = 0; j < 2; j++) { token.GetToken(temp); if (strcmp(temp, "constant") == 0) { extrap[j] = 'k'; } else if (strcmp(temp, "linear") == 0) { extrap[j] = 'l'; } else if (strcmp(temp, "cycle") == 0) { extrap[j] = 'c'; } else if (strcmp(temp, "cycle_offset") == 0) { extrap[j] = 'o'; } else if (strcmp(temp, "bounce") == 0) { extrap[j] = 'b'; } } token.FindToken("keys"); int numKeys = token.GetInt(); token.FindToken("{"); for (int i = 0; i < numKeys; i++) { Keyframe newKeyframe = Keyframe(); newKeyframe.Time = token.GetFloat(); newKeyframe.Value = token.GetFloat(); token.GetToken(temp); if (strcmp(temp, "flat") == 0) { newKeyframe.RuleIn = 'f'; newKeyframe.TangentIn = 0; } else if (strcmp(temp, "linear") == 0) { newKeyframe.RuleIn = 'l'; } else if (strcmp(temp, "smooth") == 0) { newKeyframe.RuleIn = 's'; } else { newKeyframe.RuleIn = 'f'; newKeyframe.RuleIn = atof(temp); } token.GetToken(temp); if (strcmp(temp, "flat") == 0) { newKeyframe.RuleOut = 'f'; newKeyframe.TangentOut = 0; } else if (strcmp(temp, "linear") == 0) { newKeyframe.RuleOut = 'l'; } else if (strcmp(temp, "smooth") == 0) { newKeyframe.RuleOut = 's'; } else { newKeyframe.RuleOut = 'f'; newKeyframe.TangentOut = atof(temp); } keyframes.push_back(newKeyframe); } startTime = keyframes[0].Time; endTime = keyframes[keyframes.size()-1].Time; preCompute(); return true; }