private AnimationObject GetAnimationObject(Animation animation, Dictionary <int, AnimationObject> animationObjects, ushort objectId) { if (animationObjects.ContainsKey(objectId)) { return(animationObjects[objectId]); } var animationObject = new AnimationObject { Animation = animation, ID = objectId }; animationObjects.Add(objectId, animationObject); return(animationObject); }
private AnimationFrame GetAnimationFrame(AnimationObject animationObject, int frameTime) { var animationFrames = animationObject.AnimationFrames; if (animationFrames.ContainsKey(frameTime)) { return(animationFrames[frameTime]); } var frame = new AnimationFrame { FrameTime = frameTime, AnimationObject = animationObject }; animationFrames.Add(frameTime, frame); return(frame); }
private void ProcessAnimationObject(AnimationObject animationObject, int frameIndex, Matrix4?parentMatrix, AnimationObject selectedAnimationObject = null, RootEntity selectedEntity = null) { var animationFrames = animationObject.AnimationFrames; var totalFrames = animationFrames.Count; var localMatrix = Matrix4.Identity; for (var f = 0; f <= frameIndex && f < totalFrames; f++) { if (!animationFrames.ContainsKey(f)) { continue; } var matrix = Matrix4.Identity; var sumFrame = animationFrames[f]; if (sumFrame.Rotation != null) { var r = Matrix4.CreateFromQuaternion(sumFrame.Rotation.Value); matrix = matrix * r; } else if (sumFrame.EulerRotation != null) { var r = GeomUtils.CreateR(sumFrame.EulerRotation.Value); matrix = matrix * r; } if (sumFrame.Scale != null) { var scale = (Vector3)sumFrame.Scale; var s = GeomUtils.CreateS(scale.X); matrix = matrix * s; } if (sumFrame.Translation != null) { var translation = (Vector3)sumFrame.Translation; var t = GeomUtils.CreateT(translation); matrix = matrix * t; } var absoluteMatrixValue = sumFrame.AbsoluteMatrix; if (!absoluteMatrixValue) { matrix = matrix * localMatrix; } localMatrix = matrix; } Matrix4 worldMatrix; if (parentMatrix != null) { worldMatrix = localMatrix * parentMatrix.Value; _scene.SkeletonBatch.AddLine(Vector3.TransformPosition(Vector3.One, parentMatrix.Value), Vector3.TransformPosition(Vector3.One, worldMatrix), animationObject == selectedAnimationObject ? Color.Blue : Color.Red); } else { worldMatrix = localMatrix; } if (selectedEntity != null) { var objectId = animationObject.TMDID.GetValueOrDefault(); if (objectId > 0) { var models = selectedEntity.GetModelsWithTMDID(objectId - 1); foreach (var model in models) { _scene.MeshBatch.BindModelBatch(model, _animationProcessIndex++, worldMatrix, _scene.TextureBinder); } } } foreach (var childObject in animationObject.Children) { ProcessAnimationObject(childObject, frameIndex, worldMatrix, selectedAnimationObject, selectedEntity); } }
public void SetupAnimationFrame(int frame, AnimationObject animationObject = null, RootEntity selectedEntity = null) { _scene.SkeletonBatch.Reset(); _animationProcessIndex = 0; ProcessAnimationObject(_animation.RootAnimationObject, frame, null, animationObject, selectedEntity); }
private Animation ParseTOD(BinaryReader reader) { var version = reader.ReadByte(); var resolution = reader.ReadUInt16(); var frameCount = reader.ReadUInt32(); if (frameCount == 0 || frameCount > 10000) { return(null); } var animation = new Animation(); var rootAnimationObject = new AnimationObject(); var animationObjects = new Dictionary <int, AnimationObject>(); for (var f = 0; f < frameCount; f++) { //var frameTop = reader.BaseStream.Position; var frameSize = reader.ReadUInt16(); var packetCount = reader.ReadUInt16(); var frameNumber = reader.ReadUInt32(); if (frameNumber != f) { return(null); } if (packetCount == 0) { continue; } //if (packetCount > 50000) //{ // return null; //} for (var p = 0; p < packetCount; p++) { var packetTop = reader.BaseStream.Position; var objectId = reader.ReadUInt16(); var packetTypeAndFlag = reader.ReadByte(); var packetType = (packetTypeAndFlag & 0xF); var flag = (packetTypeAndFlag & 0xF0) >> 0x4; var packetLength = reader.ReadByte(); var animationObject = GetAnimationObject(animation, animationObjects, objectId); var animationFrame = GetAnimationFrame(animationObject, f); switch (packetType) { //case 0x00: //Attribute // var attribute1 = reader.ReadUInt32(); // var attribute2 = reader.ReadUInt32(); // break; case 0x01: //Coordinate var matrixType = (flag & 0x1); var rotation = (flag & 0x2) >> 0x1; var scaling = (flag & 0x4) >> 0x2; var translation = (flag & 0x8) >> 0x3; if (rotation != 0x00) { var rx = (reader.ReadInt32() / 4096f) * GeomUtils.Deg2Rad; var ry = (reader.ReadInt32() / 4096f) * GeomUtils.Deg2Rad; var rz = (reader.ReadInt32() / 4096f) * GeomUtils.Deg2Rad; animationFrame.EulerRotation = new Vector3(rx, ry, rz); } if (scaling != 0x00) { var sx = reader.ReadInt16() / 4096f; var sy = reader.ReadInt16() / 4096f; var sz = reader.ReadInt16() / 4096f; reader.ReadUInt16(); animationFrame.Scale = new Vector3(sx, sy, sz); } if (translation != 0x00) { float tx = reader.ReadInt32(); float ty = reader.ReadInt32(); float tz = reader.ReadInt32(); animationFrame.Translation = new Vector3(tx, ty, tz); } animationFrame.AbsoluteMatrix = matrixType == 0x00; //if ((reader.BaseStream.Position - packetTop) / 4 != packetLength) //{ // return null; //} break; case 0x02: //TMD data ID animationObject.TMDID = reader.ReadUInt16(); reader.ReadUInt16(); //if ((reader.BaseStream.Position - packetTop) / 4 != packetLength) //{ // return null; //} break; case 0x03: //Parent Object ID animationObject.ParentID = reader.ReadUInt16(); reader.ReadUInt16(); //if ((reader.BaseStream.Position - packetTop) / 4 != packetLength) //{ // return null; //} break; case 0x04: float r00 = reader.ReadInt16() / 4096f; float r01 = reader.ReadInt16() / 4096f; float r02 = reader.ReadInt16() / 4096f; float r10 = reader.ReadInt16() / 4096f; float r11 = reader.ReadInt16() / 4096f; float r12 = reader.ReadInt16() / 4096f; float r20 = reader.ReadInt16() / 4096f; float r21 = reader.ReadInt16() / 4096f; float r22 = reader.ReadInt16() / 4096f; reader.ReadInt16(); var x = reader.ReadInt32(); var y = reader.ReadInt32(); var z = reader.ReadInt32(); var matrix = new Matrix3( new Vector3(r00, r01, r02), new Vector3(r10, r11, r12), new Vector3(r20, r21, r22) ); animationFrame.Translation = new Vector3(x, y, z); animationFrame.Rotation = matrix.ExtractRotation(); animationFrame.Scale = matrix.ExtractScale(); animationFrame.AbsoluteMatrix = true; //if ((reader.BaseStream.Position - packetTop) / 4 != packetLength) //{ // return null; //} break; //case 0x08: //object control // switch (flag) // { // case 0x00: // break; // case 0x01: // break; // } // break; default: reader.BaseStream.Position = packetTop + (packetLength * 4); break; } } } foreach (var animationObject in animationObjects.Values) { if (animationObject.ParentID != 0 && animationObjects.ContainsKey(animationObject.ParentID)) { var parent = animationObjects[animationObject.ParentID]; animationObject.Parent = parent; parent.Children.Add(animationObject); continue; } animationObject.Parent = rootAnimationObject; rootAnimationObject.Children.Add(animationObject); } animation.RootAnimationObject = rootAnimationObject; animation.FrameCount = frameCount; animation.ObjectCount = animationObjects.Count; animation.FPS = 1f / resolution * 60f; return(animation); }