示例#1
0
        /// <summary>
        /// Applies script state and computes transformations.
        /// </summary>
        /// <param name="viewMatrix"></param>
        /// <param name="parentNode"></param>
        /// <param name="deltaTime"></param>
        /// <param name="matrixRotate"></param>
        public void PrepareForRender(Matrix4x4 viewMatrix, RenderTreeNode parentNode, int deltaTime,
                                     bool matrixRotate = false)
        {
            var frontendObjectData = FrontendObject.Data;
            var size     = frontendObjectData.Size;
            var position = frontendObjectData.Position;
            var rotation = frontendObjectData.Rotation;
            var color    = frontendObjectData.Color;

            if (frontendObjectData is ImageData imageData)
            {
                UpperLeft  = imageData.UpperLeft;
                LowerRight = imageData.LowerRight;
            }

            if (CurrentScript != null &&
                (CurrentScript.Length > 0 || CurrentScript.ChainedId != 0xFFFFFFFF) &&
                CurrentScriptTime >= 0)
            {
                if (CurrentScriptTime >= CurrentScript.Length)
                {
                    if ((CurrentScript.Flags & 1) == 1)
                    {
                        Debug.WriteLine("looping script {0:X} for object {1:X}", CurrentScript.Id, FrontendObject.NameHash);
                        CurrentScriptTime = 0;
                    }
                    else if (CurrentScript.ChainedId != 0xFFFFFFFF)
                    {
                        var nextScript = FrontendObject.Scripts.Find(s => s.Id == CurrentScript.ChainedId) ??
                                         throw new Exception(
                                                   $"Cannot find chained script (object {FrontendObject.NameHash:X}, base script {CurrentScript.Id:X}): {CurrentScript.ChainedId:X}");
                        Debug.WriteLine("activating chained script for object {1:X}: {0}",
                                        nextScript.Name ?? nextScript.Id.ToString("X"), FrontendObject.NameHash);

                        SetScript(nextScript);
                    }
                }

                foreach (var track in CurrentScript.Tracks)
                {
                    switch (track.Offset)
                    {
                    case 0:     // Color
                        color = TrackInterpolation.Interpolate <Color4>(track, CurrentScriptTime);
                        break;

                    case 7:     // Position
                        position = TrackInterpolation.Interpolate <Vector3>(track, CurrentScriptTime);
                        break;

                    case 10:     // Rotation
                        rotation = TrackInterpolation.Interpolate <Quaternion>(track, CurrentScriptTime);
                        break;

                    case 14:     // Size
                        size = TrackInterpolation.Interpolate <Vector3>(track, CurrentScriptTime);
                        break;

                    case 17:     // UpperLeft
                    {
                        if (FrontendObject is IImage <ImageData> )
                        {
                            UpperLeft = TrackInterpolation.Interpolate <Vector2>(track, CurrentScriptTime);
                        }
                        else
                        {
                            throw new Exception("Encountered UpperLeft track for a non-image");
                        }

                        break;
                    }

                    case 19:     // LowerRight
                    {
                        if (FrontendObject is IImage <ImageData> )
                        {
                            LowerRight = TrackInterpolation.Interpolate <Vector2>(track, CurrentScriptTime);
                        }
                        else
                        {
                            throw new Exception("Encountered LowerRight track for a non-image");
                        }

                        break;
                    }

                    default:
                        throw new IndexOutOfRangeException(
                                  $"object {FrontendObject.NameHash:X} script {CurrentScript.Id:X} has unsupported track with offset {track.Offset}");
                    }
                }

                CurrentScriptTime += deltaTime;
            }

            var scaleMatrix  = Matrix4x4.CreateScale(size.X, size.Y, size.Z);
            var rotateMatrix = Matrix4x4.CreateFromQuaternion(rotation);
            var transMatrix  = Matrix4x4.CreateTranslation(position.X, position.Y, position.Z);

            if (matrixRotate)
            {
                ObjectMatrix = scaleMatrix * rotateMatrix * transMatrix * viewMatrix;
            }
            else
            {
                ObjectMatrix = scaleMatrix * transMatrix * viewMatrix;
            }
            ObjectRotation = rotation;
            ObjectColor    = color;

            if (parentNode != null)
            {
                ObjectRotation *= parentNode.ObjectRotation;
                ObjectColor     = Color4.Blend(ObjectColor, parentNode.ObjectColor);
            }
        }