| 394 | } |
| 395 | |
| 396 | bool Animation::Save(const StringView& path) |
| 397 | { |
| 398 | if (OnCheckSave(path)) |
| 399 | return true; |
| 400 | ScopeLock lock(Locker); |
| 401 | |
| 402 | // Serialize animation data to the stream |
| 403 | { |
| 404 | MemoryWriteStream stream(4096); |
| 405 | |
| 406 | // Info |
| 407 | stream.Write(103); |
| 408 | stream.Write(Data.Duration); |
| 409 | stream.Write(Data.FramesPerSecond); |
| 410 | stream.Write((byte)Data.RootMotionFlags); |
| 411 | stream.Write(Data.RootNodeName, 13); |
| 412 | |
| 413 | // Animation channels |
| 414 | stream.WriteInt32(Data.Channels.Count()); |
| 415 | for (int32 i = 0; i < Data.Channels.Count(); i++) |
| 416 | { |
| 417 | auto& anim = Data.Channels[i]; |
| 418 | stream.Write(anim.NodeName, 172); |
| 419 | Serialization::Serialize(stream, anim.Position); |
| 420 | Serialization::Serialize(stream, anim.Rotation); |
| 421 | Serialization::Serialize(stream, anim.Scale); |
| 422 | } |
| 423 | |
| 424 | // Animation events |
| 425 | stream.WriteInt32(Events.Count()); |
| 426 | for (int32 i = 0; i < Events.Count(); i++) |
| 427 | { |
| 428 | auto& e = Events[i]; |
| 429 | stream.Write(e.First, 172); |
| 430 | stream.Write(e.Second.GetKeyframes().Count()); |
| 431 | for (const auto& k : e.Second.GetKeyframes()) |
| 432 | { |
| 433 | stream.Write(k.Time); |
| 434 | stream.Write(k.Value.Duration); |
| 435 | stream.Write(k.Value.TypeName, 17); |
| 436 | stream.WriteJson(k.Value.Instance); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | // Nested animations |
| 441 | stream.WriteInt32(NestedAnims.Count()); |
| 442 | for (int32 i = 0; i < NestedAnims.Count(); i++) |
| 443 | { |
| 444 | auto& e = NestedAnims[i]; |
| 445 | stream.Write(e.First, 172); |
| 446 | auto& nestedAnim = e.Second; |
| 447 | Guid id = nestedAnim.Anim.GetID(); |
| 448 | byte flags = 0; |
| 449 | if (nestedAnim.Enabled) |
| 450 | flags |= 1; |
| 451 | if (nestedAnim.Loop) |
| 452 | flags |= 2; |
| 453 | stream.Write(flags); |
nothing calls this directly
no test coverage detected