public void Rescale(Vector3 scale, Vector3 position, Quaternion rotation) { for (int w = 0; w < this.Animations.Count; w++) { Animation animation = this.Animations[w]; for (int x = 0; x < animation.Controllers.Count; x++) { AnimationController controller = animation.Controllers[x]; for (int y = 0; y < controller.Layers.Count; y++) { AnimationLayer layer = controller.Layers[y]; if (layer.HasPRSKeyFrames && controller.TargetId == 0) { var newLayer = new AnimationLayer(layer.Version) { KeyType = KeyType.NodePRS }; for (int z = 0; z < layer.Keys.Count; z++) { foreach (var key in layer.Keys) { PRSKey prsKey = (PRSKey)key; var newKey = new PRSKey(KeyType.NodePRS) { Time = prsKey.Time, Position = (prsKey.Position * layer.PositionScale) + position, Rotation = rotation, Scale = (prsKey.Scale * layer.ScaleScale) * scale }; newLayer.Keys.Add(newKey); } } controller.Layers[y] = newLayer; } } } } }
/// <summary> /// Converts splitted Position, Rotation and Scale layers into one NodePRSHalf layer. /// </summary> /// <param name="layers">List of layers.</param> /// <returns>The merged PRS layer. null if fails to merge layers.</returns> internal AnimationLayer ConvertToPRS(List <AnimationLayer> layers) { if (layers.Count < 2 || layers.Count > 3) { return(null); } // Exit if we have an unhandled controller foreach (AnimationLayer layer in layers) { switch (layer.KeyType) { case KeyType.NodePRHalf: case KeyType.NodePRHalf_2: case KeyType.Type31: case KeyType.NodeRHalf: case KeyType.NodeSHalf: case KeyType.NodePSHalf: case KeyType.NodeRSHalf: break; default: return(null); } } // Create new PRS layer AnimationLayer prsLayer = new AnimationLayer(Version) { KeyType = KeyType.NodePRSHalf }; // Feed keys to the new layer foreach (AnimationLayer layer in layers) { for (int i = 0; i < layer.Keys.Count; i++) { var isNewKey = true; float time = layer.Keys[i].Time; // Get existing key or create new one var prsKey = (PRSKey)prsLayer.Keys.FirstOrDefault(k => k.Time == time); if (prsKey != null) { isNewKey = false; } else { prsKey = new PRSKey(prsLayer.KeyType) { Time = time } }; // Set key data if (((PRSKey)layer.Keys[i]).HasPosition) { prsKey.Position = ((PRSKey)layer.Keys[i]).Position; } if (((PRSKey)layer.Keys[i]).HasRotation) { prsKey.Rotation = ((PRSKey)layer.Keys[i]).Rotation; } if (((PRSKey)layer.Keys[i]).HasScale) { prsKey.Scale = ((PRSKey)layer.Keys[i]).Scale; } if (isNewKey) { // Define where to insert the key int count = prsLayer.Keys.Count; for (int j = 0; j < prsLayer.Keys.Count() - 1; j++) { if (prsLayer.Keys[j].Time <= time && prsLayer.Keys[j + 1].Time > time) { prsLayer.Keys.Insert(j + 1, prsKey); break; } } if (count == prsLayer.Keys.Count) { prsLayer.Keys.Add(prsKey); } } } } // Just in case ((PRSKey)prsLayer.Keys[0]).HasPosition = true; ((PRSKey)prsLayer.Keys[0]).HasRotation = true; ((PRSKey)prsLayer.Keys[0]).HasScale = true; // PRS Keys completion for (int i = 1; i < prsLayer.Keys.Count; i++) { if (!((PRSKey)prsLayer.Keys[i]).HasPosition) { ((PRSKey)prsLayer.Keys[i]).Position = ((PRSKey)prsLayer.Keys[i - 1]).Position; } if (!((PRSKey)prsLayer.Keys[i]).HasRotation) { ((PRSKey)prsLayer.Keys[i]).Rotation = ((PRSKey)prsLayer.Keys[i - 1]).Rotation; } if (!((PRSKey)prsLayer.Keys[i]).HasScale) { ((PRSKey)prsLayer.Keys[i]).Scale = ((PRSKey)prsLayer.Keys[i - 1]).Scale; } } prsLayer.PositionScale = layers.FirstOrDefault(l => ((PRSKey)l.Keys[0]).HasPosition)?.PositionScale ?? Vector3.One; prsLayer.ScaleScale = layers.FirstOrDefault(l => ((PRSKey)l.Keys[0]).HasScale)?.ScaleScale ?? Vector3.One; return(prsLayer); } }
protected override void ReadCore(ResourceReader reader) { KeyType = ( KeyType )reader.ReadInt32(); var keyCount = reader.ReadInt32(); var keyTimings = reader.ReadSingles(keyCount); Logger.Debug($"AnimationLayer: Reading type {KeyType} with {keyCount} keys"); for (int i = 0; i < keyCount; i++) { Key key; switch (KeyType) { case KeyType.NodePR: case KeyType.NodePRS: case KeyType.NodePRHalf: case KeyType.NodePRSHalf: case KeyType.NodePRHalf_2: case KeyType.NodeRHalf: case KeyType.NodeSHalf: case KeyType.NodeRSHalf: case KeyType.NodePSHalf: key = new PRSKey(KeyType); break; case KeyType.Vector3: case KeyType.Vector3_2: case KeyType.Vector3_3: case KeyType.Vector3_4: case KeyType.MaterialVector3_5: key = new Vector3Key(KeyType); break; case KeyType.Quaternion: case KeyType.Quaternion_2: key = new QuaternionKey(KeyType); break; case KeyType.Single: case KeyType.Single_2: case KeyType.Single_3: case KeyType.MaterialSingle_4: case KeyType.Single_5: case KeyType.Single_6: case KeyType.CameraFieldOfView: case KeyType.Single_8: case KeyType.SingleAlt_2: case KeyType.MaterialSingle_9: case KeyType.SingleAlt_3: key = new SingleKey(KeyType); break; case KeyType.Single5: case KeyType.Single5_2: case KeyType.Single5Alt: key = new Single5Key(KeyType); break; case KeyType.NodePRSByte: key = new PRSByteKey(); break; case KeyType.Single4Byte: key = new Single4ByteKey(); break; case KeyType.SingleByte: key = new SingleByteKey(); break; case KeyType.Type22: key = new KeyType22(); break; case KeyType.Type31: { if (IsCatherineFullBodyData) { key = new KeyType31FullBody(); } else { key = new KeyType31Dancing(); } } break; default: throw new InvalidDataException($"Unknown/Invalid Key frame type: {KeyType}"); } key.Time = keyTimings[i]; key.Read(reader); Keys.Add(key); } if (UsesScaleVectors) { PositionScale = reader.ReadVector3(); if (!IsCatherineFullBodyData || KeyType != KeyType.Type31) { ScaleScale = reader.ReadVector3(); } } }