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); }
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; } }