private void Timer_Tick() { double angle = (0.05f * frame) * Math.PI / 180; var xAxis = new Vector3(1, 0, 0); var zAxis = new Vector3(0, 0, 1); var yAxis = new Vector3(0, 1, 0); var rotation = Matrix.RotationAxis(xAxis, 0); double angleEach = 0; int counter = 0; for (int i = 0; i < NumSegments && i < numBonesInModel; ++i, counter += numSegmentPerBone) { if (i == 0) { boneInternal[0] = rotation; } else { var vp = Vector3.Transform(path[counter - numSegmentPerBone], Matrix.RotationAxis(xAxis, (float)angleEach)).ToVector3(); angleEach += angle; var v = Vector3.Transform(path[counter], Matrix.RotationAxis(xAxis, (float)angleEach)).ToVector3(); var rad = Math.Acos(Vector3.Dot(yAxis, (v - vp).Normalized())); if (angleEach < 0) { rad = -rad; } var rot = Matrix.RotationAxis(xAxis, (float)rad); var trans = Matrix.Translation(v); boneInternal[i] = rot * trans; } } var newBone = new BoneMatricesStruct() { Bones = boneInternal.ToArray() }; context.Post((o) => { Bones = newBone; }, null); if (frame > 40 || frame < -40) { direction = !direction; } if (direction) { ++frame; } else { --frame; } }