예제 #1
0
파일: clip.cpp 프로젝트: lealzhan/moged
sqlite3_int64 Clip::ImportClipFromReadNode(sqlite3* db, sqlite3_int64 skel_id, const LBF::ReadNode& rn)
{
	sqlite3_int64 result = 0;
	if(rn.Valid() && rn.GetType() == LBF::ANIMATION) 
	{
		clip_save_info info;
		rn.GetData(&info, sizeof(info));

		LBF::ReadNode rnRots = rn.GetFirstChild(LBF::FRAME_ROTATIONS);
		if(!rnRots.Valid()) return 0;
		LBF::ReadNode rnRootOff = rn.GetFirstChild(LBF::FRAME_ROOT_OFFSETS);
		if(!rnRootOff.Valid()) return 0;
		LBF::ReadNode rnRootRots = rn.GetFirstChild(LBF::FRAME_ROOT_ROTATIONS);
		if(!rnRootRots.Valid()) return 0;

		sql_begin_transaction(db);
		
		std::string clipName ;
		LBF::ReadNode rnName = rn.GetFirstChild(LBF::ANIMATION_NAME);
		if(rnName.Valid()) {
			clipName = std::string(rnName.GetNodeData(), rnName.GetNodeDataLength());
		} else {
			clipName = "missing name";
		}

		// add basic clip info
		Query insert_clip( db, "INSERT INTO clips (skel_id,name,fps,num_frames,frames) VALUES (?,?,?,?,?)");
		insert_clip.BindInt64(1, skel_id);
		insert_clip.BindText(2, clipName.c_str());
		insert_clip.BindDouble(3, info.fps);
		insert_clip.BindInt64(4, info.num_frames);
		insert_clip.BindBlob(5, sizeof(Quaternion) * info.num_frames * info.joints_per_frame +
			sizeof(ClipFrameHeader) * info.num_frames);			
		insert_clip.Step();
		if( insert_clip.IsError() ) {
			sql_rollback_transaction(db);	
			return 0;
		}

		result = insert_clip.LastRowID();

		Blob framesWriter(db, "clips", "frames", result, true);
		int framesOffset = 0;

		// add a frame header
		BufferReader rootOffs = rnRootOff.GetReader();
		BufferReader rootRots = rnRootRots.GetReader();
		BufferReader rotsReader = rnRots.GetReader();

		for(int i = 0; i < info.num_frames; ++i)
		{
			ClipFrameHeader header;
			rootOffs.Get(&header.root_offset, sizeof(header.root_offset));
			rootRots.Get(&header.root_quaternion, sizeof(header.root_quaternion));

			framesWriter.Write(&header, sizeof(header), framesOffset);
			framesOffset += sizeof(header);
			
			Quaternion q;
			for(int joint = 0; joint < info.joints_per_frame; ++joint) 
			{
				// TODO: would rather do this in one call...
				rotsReader.Get(&q, sizeof(q));
				framesWriter.Write(&q, sizeof(q), framesOffset);
				framesOffset += sizeof(q);
			}
		}

		sql_end_transaction(db);
	}
	return result;
}