static bool Generate(string sourceFileName, string sourceFileHash, int sourceFileSize, int specifiedSize, out string error)
        {
            var text         = $"Generating cubemap \"{Path.GetFileName( sourceFileName )}\"...";
            var notification = Editor.ScreenNotifications.ShowSticky(text);

            var destFileNameBase = GetDestFileNameBase(sourceFileName);

            GetDestFileNames(destFileNameBase, out var infoFileName, out var envFileName, out var irrFileName);

            string temporaryGeneratedFile = "";

            try
            {
                var sourceRealFileName = VirtualPathUtility.GetRealPathByVirtual(sourceFileName);
                {
                    //convert .image to 6 face HDR image

                    if (Path.GetExtension(sourceRealFileName) == ".image")
                    {
                        var image = ResourceManager.LoadResource <Component_Image>(sourceFileName, out error);
                        if (image == null)
                        {
                            return(false);
                        }

                        string[] loadCubeMap6Files = null;
                        string   loadFromOneFile   = null;
                        {
                            if (image.AnyCubemapSideIsSpecified())
                            {
                                if (image.AllCubemapSidesAreaSpecified())
                                {
                                    loadCubeMap6Files = new string[6];
                                    for (int n = 0; n < 6; n++)
                                    {
                                        var v = image.GetLoadCubeSide(n);
                                        if (v != null)
                                        {
                                            loadCubeMap6Files[n] = v.ResourceName;
                                        }

                                        if (string.IsNullOrEmpty(loadCubeMap6Files[n]) || !VirtualFile.Exists(loadCubeMap6Files[n]))
                                        {
                                            loadCubeMap6Files = null;
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                var v = image.LoadFile.Value;
                                loadFromOneFile = v != null ? v.ResourceName : "";
                                if (string.IsNullOrEmpty(loadFromOneFile) || !VirtualFile.Exists(loadFromOneFile))
                                {
                                    loadFromOneFile = null;
                                }
                            }
                        }

                        if (loadFromOneFile != null)
                        {
                            sourceRealFileName = VirtualPathUtility.GetRealPathByVirtual(loadFromOneFile);
                        }
                        else if (loadCubeMap6Files != null)
                        {
                            temporaryGeneratedFile = Path.GetTempPath() + Guid.NewGuid().ToString() + ".hdr";
                            sourceRealFileName     = temporaryGeneratedFile;

                            ImageUtility.Image2D image2D = null;

                            for (int face = 0; face < 6; face++)
                            {
                                if (!ImageUtility.LoadFromVirtualFile(loadCubeMap6Files[face], out var data, out var size, out _, out var format, out _, out _, out error))
                                {
                                    return(false);
                                }

                                if (image2D == null)
                                {
                                    image2D = new ImageUtility.Image2D(PixelFormat.Float32RGB, size * new Vector2I(4, 3));
                                }

                                Vector2I index = Vector2I.Zero;
                                switch (face)
                                {
                                case 0: index = new Vector2I(2, 1); break;

                                case 1: index = new Vector2I(0, 1); break;

                                case 2: index = new Vector2I(1, 0); break;

                                case 3: index = new Vector2I(1, 2); break;

                                case 4: index = new Vector2I(1, 1); break;

                                case 5: index = new Vector2I(3, 1); break;
                                }

                                var faceImage = new ImageUtility.Image2D(format, size, data);
                                image2D.Blit(index * size, faceImage);
                            }

                            if (!ImageUtility.Save(temporaryGeneratedFile, image2D.Data, image2D.Size, 1, image2D.Format, 1, 0, out error))
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            error = "The image wrong configured.";
                            return(false);
                        }
                    }
                }

                int sizeEnv = 32;
                if (specifiedSize == 0)
                {
                    //detect size

                    if (!ImageUtility.LoadFromRealFile(sourceRealFileName, out _, out var sourceSize, out _, out _, out _, out _, out error))
                    {
                        return(false);
                    }

                    //!!!!если кубемапа

                    if (Math.Abs((double)sourceSize.X / (double)sourceSize.Y - 1.333333) <= 0.001)
                    {
                        sizeEnv = sourceSize.X / 4;
                    }
                    else
                    {
                        //!!!!
                        sizeEnv = MathEx.NextPowerOfTwo(sourceSize.X / 3);
                    }

                    if (sizeEnv == 0)
                    {
                        sizeEnv = 1;
                    }
                }
                else
                {
                    sizeEnv = specifiedSize;
                }

                int sizeIrr = 32;

                var destRealFileNameBase = VirtualPathUtility.GetRealPathByVirtual(destFileNameBase);
                var infoRealFileName     = VirtualPathUtility.GetRealPathByVirtual(infoFileName);
                var envRealFileName      = VirtualPathUtility.GetRealPathByVirtual(envFileName);
                var irrRealFileName      = VirtualPathUtility.GetRealPathByVirtual(irrFileName);

                //delete old files
                if (File.Exists(infoRealFileName))
                {
                    File.Delete(infoRealFileName);
                }
                if (File.Exists(envRealFileName))
                {
                    File.Delete(envRealFileName);
                }
                if (File.Exists(irrRealFileName))
                {
                    File.Delete(irrRealFileName);
                }

                var destDirectory = Path.GetDirectoryName(destRealFileNameBase);
                if (!Directory.Exists(destDirectory))
                {
                    Directory.CreateDirectory(destDirectory);
                }

                var irradianceValues = new List <Vector3>();

                if (!GenerateFile(sourceRealFileName, false, sizeEnv, envRealFileName, irradianceValues, out error))
                {
                    return(false);
                }
                if (!GenerateFile(sourceRealFileName, true, sizeIrr, irrRealFileName, null, out error))
                {
                    return(false);
                }

                //make .info file
                {
                    var block = new TextBlock();
                    block.SetAttribute("SourceFileHash", sourceFileHash);
                    block.SetAttribute("SourceFileSize", sourceFileSize.ToString());
                    //block.SetAttribute( "SourceFileFormat", sourceFileFormat.ToString() );

                    for (int n = 0; n < irradianceValues.Count; n++)
                    {
                        block.SetAttribute("Irradiance" + n.ToString(), irradianceValues[n].ToString());
                    }

                    if (!TextBlockUtility.SaveToRealFile(block, infoRealFileName, out error))
                    {
                        return(false);
                    }
                }
            }
            catch (Exception e)
            {
                error = e.Message;
                return(false);
            }
            finally
            {
                notification.Close();

                try
                {
                    if (File.Exists(temporaryGeneratedFile))
                    {
                        File.Delete(temporaryGeneratedFile);
                    }
                }
                catch { }
            }

            error = "";
            return(true);
        }
Example #2
0
        private void ParentMeshInSpace_GetRenderSceneDataAddToFrameData(Component_MeshInSpace sender, ViewportRenderingContext context, GetRenderSceneDataMode mode, ref Component_RenderingPipeline.RenderSceneData.MeshItem item)
        {
            if (!CalculateOnCPU)
            {
                Component_Skeleton skeleton = ReplaceSkeleton;
                if (skeleton == null)
                {
                    skeleton = ParentMeshInSpace?.Mesh.Value?.Skeleton;
                }

                if (skeleton != null)
                {
                    var animation = PlayAnimation.Value;
                    if (animation != null)
                    {
                        UpdateAnimationTime();

                        //settings.animationStates = new AnimationStateItem[ 1 ];
                        //settings.animationStates[ 0 ] = new AnimationStateItem( animation, currentLocalTime, 1 );

                        var skeletonAnimation = animation as Component_SkeletonAnimation;
                        var track             = skeletonAnimation?.Track.Value;

                        if (track != null || CalculateBoneTransforms != null)
                        {
                            Update(skeleton, track, currentAnimationTime);

                            if (transformMatrixRelativeToSkin != null && transformMatrixRelativeToSkin.Length != 0)
                            {
                                item.AnimationData = new Component_RenderingPipeline.RenderSceneData.MeshItem.AnimationDataClass();

                                bool dualQuaternion = false;                                // GetSkinningMode( skeleton ) == Component_Skeleton.SkinningModeEnum.DualQuaternion;
                                if (dualQuaternion)
                                {
                                    item.AnimationData.Mode = 2;
                                }
                                else
                                {
                                    item.AnimationData.Mode = 1;
                                }

                                //create dynamic texture
                                var size         = new Vector2I(4, MathEx.NextPowerOfTwo(transformMatrixRelativeToSkin.Length));
                                var bonesTexture = context.DynamicTexture_Alloc(ViewportRenderingContext.DynamicTextureType.DynamicTexture, Component_Image.TypeEnum._2D, size, PixelFormat.Float32RGBA, 0, false);

                                //try get array from texture to minimize memory allocations
                                var surfaces = bonesTexture.Result.GetData();
                                if (surfaces == null)
                                {
                                    surfaces = new GpuTexture.SurfaceData[] { new GpuTexture.SurfaceData(0, 0, new byte[size.X * size.Y * 16]) }
                                }
                                ;
                                var data = surfaces[0].data;

                                //copy data to the texture
                                unsafe
                                {
                                    fixed(byte *pData2 = data)
                                    {
                                        Matrix4F *pData = (Matrix4F *)pData2;

                                        for (int n = 0; n < transformMatrixRelativeToSkin.Length; n++)
                                        {
                                            pData[n] = transformMatrixRelativeToSkin[n];
                                        }
                                    }
                                }
                                bonesTexture.Result.SetData(new GpuTexture.SurfaceData[] { new GpuTexture.SurfaceData(0, 0, data) });

                                item.AnimationData.BonesTexture = bonesTexture;
                            }
                        }
                    }
                }
            }
        }

        void RenderSkeleton(Viewport viewport)
        {
            // ParentMeshInSpace.Transform is automaticaly applyed to ParentMeshInSpace.Mesh, skeleton must be transformed manually
            var transformMatrix = ParentMeshInSpace?.Transform.Value?.ToMatrix4() ?? Matrix4.Identity;

            var skeletonArrows = GetCurrentAnimatedSkeletonArrows();

            if (skeletonArrows != null)
            {
                var color = new ColorValue(0, 0.5, 1, 0.7);                   //ToDo : Вынести в другое место.
                viewport.Simple3DRenderer.SetColor(color, color * ProjectSettings.Get.HiddenByOtherObjectsColorMultiplier);

                foreach (var arrow in skeletonArrows)
                {
                    viewport.Simple3DRenderer.AddArrow(transformMatrix * arrow.Start, transformMatrix * arrow.End);
                }
            }
        }

        bool CheckNeedModifiableMesh()
        {
            if (CalculateOnCPU)
            {
                if (ReplaceSkeleton.ReferenceSpecified)
                {
                    return(true);
                }
                var mesh = ParentMeshInSpace?.Mesh.Value;
                if (mesh != null && mesh.Skeleton.ReferenceSpecified)
                {
                    return(true);
                }

                if (PlayAnimation.ReferenceSpecified)
                {
                    return(true);
                }
            }

            return(false);
        }

        void UpdateModifiableMesh(ViewportRenderingContext context)
        {
            var originalMesh   = ParentMeshInSpace.Mesh.Value;
            var modifiableMesh = ParentMeshInSpace.ModifiableMesh;

            Component_Skeleton skeleton = ReplaceSkeleton;

            if (skeleton == null)
            {
                skeleton = originalMesh.Skeleton;
            }
            if (skeleton != null)
            {
                //!!!!сериализовывать

                var animation = PlayAnimation.Value;
                if (animation != null)
                {
                    UpdateAnimationTime();

                    //settings.animationStates = new AnimationStateItem[ 1 ];
                    //settings.animationStates[ 0 ] = new AnimationStateItem( animation, currentLocalTime, 1 );

                    var skeletonAnimation = animation as Component_SkeletonAnimation;
                    var track             = skeletonAnimation?.Track.Value;

                    if (track != null || CalculateBoneTransforms != null)
                    {
                        Update(skeleton, track, currentAnimationTime);
                        CalculateCPU(skeleton, originalMesh, modifiableMesh);
                    }
                }

                if (needResetToOriginalMesh)
                {
                    needResetToOriginalMesh = false;
                    if (CalculateOnCPU)
                    {
                        ResetToOriginalMesh(originalMesh, modifiableMesh);
                    }
                }
            }
        }

        /////////////////////////////////////////

        void ResetTime(bool needResetToOriginalMesh)
        {
            if (needResetToOriginalMesh)
            {
                this.needResetToOriginalMesh = true;
            }
            currentEngineTime    = EngineApp.EngineTime;
            currentAnimationTime = (PlayAnimation.Value as Component_SkeletonAnimation)?.TrackStartTime ?? 0;
        }

        void UpdateAnimationTime()
        {
            double t         = EngineApp.EngineTime;
            double increment = t - currentEngineTime;

            currentEngineTime     = t;
            currentAnimationTime += increment * Speed;

            var animation = PlayAnimation.Value as Component_SkeletonAnimation;

            if (animation != null)
            {
                double animationStartTime = animation.TrackStartTime;
                double animationLength    = animation.Length;
                if (animationLength > 0)
                {
                    if (AutoRewind)
                    {
                        while (currentAnimationTime > animationStartTime + animationLength)
                        {
                            currentAnimationTime -= animationLength;
                        }
                        while (currentAnimationTime < animationStartTime)
                        {
                            currentAnimationTime += animationLength;
                        }
                    }
                    else
                    {
                        MathEx.Clamp(ref currentAnimationTime, animationStartTime, animationStartTime + animationLength);
                    }
                }
                else
                {
                    currentAnimationTime = animationStartTime;
                }
            }
            else
            {
                currentAnimationTime = 0;
            }
        }