You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3278667 on 2017/01/31 by Chris.Wood Added extra context to crash analytics and crash reports in the Editor. [UE-41306] - Add context to crash analytics and crash reports (with Editor user activity) When a Slate tab becomes active or foregrounded, we take its LayoutIdentity, Label and Content Widget Type and generate a string from all three. This gives context for what the user was doing. The string is set as the UserActivity and passed to MTBF analytics, crash analytics and crash reporter. Also added filter to the UserActivity tracking system that defaults to Game mode to preserve previous behavior. Editor now switches it to Editor mode and starts setting the activity in this mode. #jira UE-41306 Change 3278637 on 2017/01/30 by Dmitriy.Dyomin Fixed: iOS Device displays textures darker than in Editor #jira UE-41298 Change 3278566 on 2017/01/30 by Jack.Porter Fix #WITH_EDITOR in InstancedStaticMesh.cpp #jira UE-41292 Change 3278195 on 2017/01/30 by Alexis.Matte Fix the re-import skeletal mesh regression, where all material disapear. #jira UE-41294 Change 3278173 on 2017/01/30 by Frank.Fella PlatformMediaSource - Don't allow the user to nest platform media sources, and also fail validation on nested platform media sources just in case they are set outside of the cusomization UI. #Jira UE-40779 Change 3278156 on 2017/01/30 by Josh.Adams - Adding the missed #include line for IsWindowsServer() #jira UE-41304 Change 3278088 on 2017/01/30 by Mike.Beach Mirroring CL 3249423 from Dev-BP. Fix to keep placeholder classes from being needlessly created (when the object they represent already exists) - instead, attempt to lookup and find the existing import objects (which used to be set, but could be cleared during async loading by FLinkerManager::DissociateImportsAndForcedExports()). #jira OR-34038 Change 3278036 on 2017/01/30 by Mike.Beach Mirroring CL 3277671 from Dev-BP. Refactoring FBlueprintCompilerCppBackend::SortNodesInUberGraphExecutionGroup() a bit. Catching cases that weren't acounted for - detecting cyclical logic now when we've pulled a node/statement out of order, and other nodes need to fall through to that logic (not relying on a goto). #jira UE-41188, UE-41189, UE-41186, UE-41037 Change 3277974 on 2017/01/30 by Josh.Adams - Hopeful workaround for COM crash in HandleGameExplorerIntegration function #jira UE-41080 Change 3277951 on 2017/01/30 by Ori.Cohen Fix access violation in physx. #JIRA ODIN-5199 Change 3277773 on 2017/01/30 by Jamie.Dale Fixing crash that could occur with null meta-data #jira UE-41271 Change 3277549 on 2017/01/30 by Max.Chen Sequencer: Back out changelist 3276452 because it breaks other uses of the time snapping interval in the settings. #jira UE-41009 Change 3277510 on 2017/01/30 by Jamie.Dale Fixed localization sometimes having incorrect keys in cooked builds Merged CL# 3276233 and CL# 3277273. #jira UE-41271 Change 3277500 on 2017/01/30 by Michael.Trepka Added -Wno-undefined-var-template on Mac to work around an issue with compiling UHT in Xcode 8.3 #jira UE-41225 Change 3277421 on 2017/01/30 by Arciel.Rekman TestPAL: delete unused test (UE-36984) #jira UE-36984 (Edigrating CL 3267568 from Dev-Platform to Release-4.15) Change 3277410 on 2017/01/30 by Jeff.Fisher UE-41152 more non-unity include fixes. -Matthew Griffin showed me how to run this locally, so I was able to locally reproduce the errors and this fixed them (the previous fixes were insufficient rather than incorrect). #jira UE-41152 Change 3277230 on 2017/01/30 by Jack.Porter Fixed issue with static lighting for Foliage and Instanced Static Meshes where shadows on instances in LOD levels other than LOD 0 was incorrect. #jira UE-39884 Change 3277178 on 2017/01/30 by Allan.Bentham enable FORCE_FLOATS with iOS metal shaders when full precision material setting is set. #jira UE-41253 Change 3277134 on 2017/01/30 by Matthew.Griffin Fixed NonUnity compile issues Change 3276503 on 2017/01/28 by Jeff.Fisher UE-41152 more non-unity include fixes. #jira UE-41152 Change 3276452 on 2017/01/28 by Max.Chen Sequencer: Changed the time snapping interval in the toolbar ui so that it no longer additionally updates the sequencer setting. The value used in the sequencer settings is only used to initialize a new level sequence. #jira UE-41009 Change 3276130 on 2017/01/27 by Phillip.Kavan [UE-40894] Fix data loss issues with non-native Blueprint classes that override inherited component default values from a nativized parent Blueprint class hierarchy. - Mirrored from //UE4/Dev-Blueprints (CL# 3276109). #jira UE-40894 Change 3276013 on 2017/01/27 by Lina.Halper - fix issue with additive pose preview applying twice #jira: UE-41216 #code review:Thomas.Sarkanen Change 3275990 on 2017/01/27 by Mitchell.Wilson Disabling 'Used with skeletal mesh' on some materials to resolve errors and warnings. #jira UE-40736 Change 3275885 on 2017/01/27 by Matt.Kuhlenschmidt Fixed missing slate style assets log warning #jira UE-41148 Change 3275805 on 2017/01/27 by Ori.Cohen Fix incorrect warning about moving simulated bodies during tick group. The existing code would warn if you had a kinematic that was SimulationDisabled (i.e. meaning it's not in the sim scene). #JIRA UE-37270 Change 3275797 on 2017/01/27 by Shaun.Kime In some cases, it was possible to create a SRetainerWidget that does not have a valid scene. This would cause the recorded scene index to be mismatched with the actual rendering index when played back in the future. #jira OR-34919 Change 3275681 on 2017/01/27 by Lina.Halper Dupe change of CL 3273803, 3274129, 3274700 #jira: UE-41163 #code review:Daniel.Wright, Martin.Wilson Change 3275624 on 2017/01/27 by Benn.Gallagher Fixed crash when creating destructible meshes from static meshes with null material interface entries #jira UE-38998 Change 3275601 on 2017/01/27 by Matt.Kuhlenschmidt Fix crash when a kdop collision generation fails and there are existing collision meshes selected. We no longer clear out unrelated collision primitives when kdop generation fails. #jira UE-41220 Change 3275545 on 2017/01/27 by Chris.Bunner Added flag for retreiving debug materials from GetUsedMaterials calls on rendering components. #jira UE-40482 Change 3275522 on 2017/01/27 by Max.Chen Sequencer: Call modify before setting row indices #jira UE-40682 Change 3275518 on 2017/01/27 by Max.Chen Sequencer: Switch to static pointer to fix crash when tearing down curve editor. #jira UE-41105 Change 3275475 on 2017/01/27 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google -Fixing non-unity missing includes. #jira UE-41152 Change 3275387 on 2017/01/27 by Steve.Robb Prevent engine reinstancing on hot reload. Copied from CL# 3265490. #jira UE-40765 Change 3275279 on 2017/01/27 by Josh.Adams - Redoing change3274305in 4.15 #jira UE-40451 Change 3275233 on 2017/01/27 by Luke.Thatcher [PLATFORM] [PS4] [!] Fix share play initialization logic. #jira UE-41209 Change 3275227 on 2017/01/27 by Alex.Delesky Duplicating the fix for UE-40791 from Dev-Editor CL 3265714 - The ForceFeedback thumbnail's Play and Stop icons will now render correctly, and will only be visible while an effect is playing or when the cursor hovers over the icon. #jira UE-40791 Change 3275057 on 2017/01/27 by Peter.Sauerbrei fix for crash after changing the metal shader version #jira ue-41183 Change 3275031 on 2017/01/27 by Matthew.Griffin Added architecture hash to path for Linux generated includes, didn't realize that this was part of the path. Change 3275005 on 2017/01/27 by Matthew.Griffin Re-enabled Cache of cooked platform data during DerivedDataCache commandlet Moved caching DDC of non-host platform data behind an option so it's not done for Installed Build by default Removed other platforms from Launcher Samples and changed 'CookPlatforms' to 'DDCPlatforms' so that its purpose is more clear Change 3274828 on 2017/01/27 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google -Fixing non-unity missing include. #jira UE-41152 Change 3274799 on 2017/01/27 by Arciel.Rekman Fix for installed Linux cross-toolchain (UE-40392). - Pull request #3111 contributed by rubu. #jira UE-40392 Change 3274756 on 2017/01/27 by Max.Chen Sequencer: Update the parent guid with the new possessable guid. This fixes a bug where the parent guid isn't set properly and so folders aren't retained when assign actors and running fix up actor references. #jira UE-41010 Change 3274755 on 2017/01/27 by Max.Chen Sequencer: Call notify movie scene data changed when creating a camera instead of marking the instances as needing a refresh. #jira UE-41019 Change 3274597 on 2017/01/26 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google -Fixing monolithic include warning. #jira UE-41152 Change 3274564 on 2017/01/26 by Mike.Beach Following the example of other nodes with external dependencies (like UK2Node_SwitchEnum), and making sure the struct is preloaded before we use it (the struct needs to have a valid size). #jira UE-41073 Change 3274535 on 2017/01/26 by Mike.Beach Removed ensure that was blocking a wrapper function call to a non-nativized function lib from being generated (while not optimal, the generated code works). #jira UE-41190 Change 3274512 on 2017/01/26 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google Merging cl 3255506 Copyright update for google -note most of the changes went in with the previous 3 androidvr-devvr change integrations, these two were not otherwise changed. -just incrementing the year //depot/Partners/Google/AndroidVR-DevVR/Engine/... to //UE4/Release-4.15/Engine/... #jira UE-41152 #review-3273588 Change 3274511 on 2017/01/26 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google Merging cl 3243495 Adding GoogleVRTransition2D plugin to handle VR->2D->VR transition for daydream app. //depot/Partners/Google/AndroidVR-DevVR/Engine/... to //UE4/Release-4.15/Engine/... #jira UE-41152 #review-3273586 Change 3274510 on 2017/01/26 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google Merging cl 3243494 Update GoogleVR plugin to v1.2. -Upgrade GVR NDK to 1.10.0 -Add easy to use GoogleVR input component, including controller component for daydream and a gaze based reticle component for cardboard. -Make the GoogleVRSplash rendered with depth. -Add built in arm model support in GoogleVR controller plugin. -Add "Use ExternalFilesDir for UE4Game files" option in AndroidRuntimeSetting to support saving game progress without requesting EXTERNAL_STORAGE permission in Andoird 23+ -Remove the "Package for Daydream" option in AndroidRuntimeSetting. -Fix the crash on iOS9 when GoogleVR plugin is enabled.(udn/325432) //depot/Partners/Google/AndroidVR-DevVR/Engine/... to //UE4/Release-4.15/Engine/... #jira UE-41152 #review-3273585 Change 3274509 on 2017/01/26 by Jeff.Fisher UE-41152 Merge Improved Daydream Support from Google Merging cl 3243493 Adding AndroidPermission plugin to handle runtime permission request and check for android api 23 and above. -The plugin works for both daydream and normal Android application. -For Daydream app, it need to work with GoogleVRTransition2D plugin. //depot/Partners/Google/AndroidVR-DevVR/Engine/... to //UE4/Release-4.15/Engine/... #jira UE-41152 #review-3273583 Change 3274485 on 2017/01/26 by Chris.Babcock Fix handling of numbers in textedit (allow decimals) #jira UE-41198 #ue4 #android Change 3274457 on 2017/01/26 by Mike.Beach Fix to CIS warning (fallout from CL 3274362) #jira UE-41072, UE-41071, UE-41070 Change 3274445 on 2017/01/26 by Arciel.Rekman Proper fix for deploying to Linux (UE-40023). - The logic is: if the base path (local to PC, one we are replacing) *ends* with a separator, add the separator to the dest path (one we're mapping to). Previous fix had a last minute change that inverted it. #jira UE-40023 Change 3274428 on 2017/01/26 by Brian.Karis Fixed bloom flickering on high contrast HDR edges when r.TemporalAACatmullRom was enabled. #jira UE-41138 Change 3274362 on 2017/01/26 by Mike.Beach Restructuring how we apply individual (exclusive) Blueprint nativization flags... 1. Explicitly flagging Blueprints as dependencies for nativization (and communicating that to the user) 2. Now applying nativization flag to authoritative config for all dependencies on save 3. Flagging new dependencies (parent or interface) as needing nativization (when required) 4. Ignore bDontNativizeDataOnlyBP setting when nativization mode is set to explicit #jira UE-41072, UE-41071, UE-41070 Change 3274349 on 2017/01/26 by Yannick.Lange VREditor: Fix Laser not hidden on MotionControllers with docked Menu/UI Panels #jira UE-40070 Change 3274301 on 2017/01/26 by Chris.Bunner Added missing material expression tooltips/keywords for new nodes based on 4.15 preview feeback. #jira UE-41193 Change 3274254 on 2017/01/26 by Ryan.Gerleve Fix for IsInGameThread() checks that could fail in debug builds while recording a replay with tick.DoAsyncEndOfFrameTasks and demo.ClientRecordAsyncEndOfFrame enabled. #jira UE-39911 Change 3274121 on 2017/01/26 by Josh.Adams - Fixed build error with landscape gizmo #jira UE-41177 Change 3274114 on 2017/01/26 by Dan.Oconnor Updating all references before calling post edit - prevents objects from being destroyed or created while updating references #jira UE-40121 Change 3273971 on 2017/01/26 by Chris.Bunner Update material instance permutations when we have already set param/switch overrides, then only change the base properties. #jira UE-39754 Change 3273842 on 2017/01/26 by Daniel.Wright Attempt to remove instructions from code features only present in the forward renderer, so we are showing users their graph cost. Allows shader complexity in forward to sortof match deferred. #jira UE-41167 Change 3273750 on 2017/01/26 by Jeff.Fisher UE-41137 //UE4/Main: Step 'Compile Ocean (Win32/Win64)' - 2 Errors - SteamVRController.cpp -Fixing build break for Ocean. Maybe they are using an older compiler? #jira UE-31137 Change 3273602 on 2017/01/26 by Michael.Trepka Fix for UE-41146 #jira UE-41146 Change 3273506 on 2017/01/26 by Maciej.Mroz #jira ODIN-4991, UE-41035 merged cl3273497 from Dev-Blueprints branch Nativization: EX_AddMulticastDelegate - generated code calls TMulticastScriptDelegate::AddUniqe instead of TMulticastScriptDelegate::Add. Change 3273464 on 2017/01/26 by Mitchell.Wilson Resaving asset to resolve warning. #jira UE-41008 Change 3273413 on 2017/01/26 by Marc.Audy Fix crash when audio device fails to initialize #author Andrew.Grant #jira UE-41143 Change 3273391 on 2017/01/26 by Jack.Porter Fixed ensure encountered when using the Copy/Paste sub-tool in sculpt mode #jira UE-40480 Change 3273343 on 2017/01/26 by Matt.Kuhlenschmidt Resetting the preview on a material now properly clears the thumbnail which could have a stale references that was impossible to fix. Fixed on asset exibiting this problem #jira UE-40300 Change 3273243 on 2017/01/26 by Jamie.Dale Speculative fix for an issue where User Defined Enum display names were being lost on upgrade to 4.15 #jira UE-41130 Change 3273235 on 2017/01/26 by Graeme.Thornton Fix for some memory being left hanging around when loading bulk data asyncronously under certain circumstances #jira UE-37815 Change 3273225 on 2017/01/26 by Ben.Cosh This fixes an issue with actor details component selection causing actor selection to get out of sync across undo operations #Jira UE-40753 - [CrashReport] UE4Editor_LevelEditor!FLevelEditorActionCallbacks::Paste_CanExecute() [leveleditoractions.cpp:1602] #Proj Engine Change 3273224 on 2017/01/26 by Josh.Stoddard Increment FDerivedDataPhysXCooker to force recook of PhysX data #jira UE-39791#rb none #lockdown james.golding Change 3273201 on 2017/01/26 by Jack.Porter Fixed problem where UpdateInstanceTransform blueprint function was not updating bounds correctly #jira UE-41126 Change 3273122 on 2017/01/26 by Graeme.Thornton Added some extra log output for situations where a compressed block in an archive doesn't have a valid header #jira UE-38767 Change 3273116 on 2017/01/26 by Benn.Gallagher Fix for crash generating clothing skinning data due to coplanar check triggering a check() on small triangles #jira UE-41112 Change 3273077 on 2017/01/26 by Thomas.Sarkanen Allowed LODs other than LOD0 to have screen sizes greater than 1 #jira UE-41125 - Static mesh LODs other than LOD0 cannot be set to screen sizes greater than 1 Change 3273061 on 2017/01/26 by Matthew.Griffin Disabled code caching data for all platforms until we can figure out why it's filling up DDC cache Change 3272938 on 2017/01/25 by Arciel.Rekman Fix launch on a remote Linux machine (UE-38691). - Device id is now used to get target platform, so should match it exactly. #jira UE-38691 Change 3272816 on 2017/01/25 by Ben.Marsh Fix VS2017 being displayed as 'Visual Studio 15' in the Windows target settings panel. Change 3272590 on 2017/01/25 by Daniel.Wright Workaround for "error X3067: 'GetObjectWorldPosition': ambiguous function call" which happens when FMaterialPixelParameters and FMaterialVertexParameters have the same number of floats with the HLSL compiler. Function overload resolution appears to identify types based on how many floats / ints / etc they contain. #jira UE-41099 Change 3272419 on 2017/01/25 by Arciel.Rekman Linux: fix remote deploying of a packaged build (UE-40023). #jira UE-40023 Change 3272355 on 2017/01/25 by Daniel.Wright Prevent a large shadow depth bias due to low resolution from causing near plane clipping #jira UE-40873 Change 3272196 on 2017/01/25 by tim.gautier Updating TM-UMG content for UI visibility #jira UE-29618 Change 3272114 on 2017/01/25 by Michael.Dupuis #jira UE-29817 : backout of CL from Dev-Editor fixing this jira Change 3271953 on 2017/01/25 by Michael.Trepka Attempt to fix UE-40956 - Rare crash occurs in CoreAudio in Vehicle Game on Mac when quitting. #jira UE-40956 Change 3271945 on 2017/01/25 by Olaf.Piesche Replicating CL 3271564 #jira UE-40980 #udn 325525 Fix uniform buffers for mesh particles; these should really be on the mesh collector, so allocating them as a one frame resource is safe. Change 3271883 on 2017/01/25 by Daniel.Wright UWorld::AreAlwaysLoadedLevelsLoaded takes into account bShouldBeVisible. Fixes reflection captures not getting uploaded when there's an invisible always loaded level, which is supposed to be invisible. #jira UE-40724 Change 3271686 on 2017/01/25 by Marc.Audy Properly fix line endings in all cases when installing a c++ feature pack #jira UE-40939 Change 3271631 on 2017/01/25 by Ryan.Gerleve In UEngine::CommitMapChange, rename the new ULevelStreaming objects so that the main world is their outer. This is more correct in general, and will cause those levels to be added to the correct level collection during FlushLevelStreaming. Also use MoveTemp to add the streaming level list to the main world, so that the fake world will no longer reference them. #jira UE-40524 Change 3271611 on 2017/01/25 by Allan.Bentham Ensure texture's buildsettings are not marked as streamable if the target platform does not support streaming. #jira UE-40927 Change 3271504 on 2017/01/25 by tim.gautier Updated default values of UMG_Behavior #jira UE-29618 Change 3271491 on 2017/01/25 by Luke.Thatcher [PLATFORM] [PS4] [!] Fix bug in AT9 audio cooking. - Maximum mono bitrate is 144kbps, but 100% quality mono tracks were selecting 168kbps, causing the AT9 tool to fail. - Also bumped AT9 engine format to recook potentially broken audio data. #jira UE-40761 Change 3271428 on 2017/01/25 by Chris.Bunner Bug in previous CL. #jira UE-39953 Change3271413on 2017/01/25 by Lina.Halper #DUPEFIX of CL 3270776 #jira: UE-41082 Change 3271403 on 2017/01/25 by tim.gautier Adjusted UMG_Blur intensity settings. #jira UE-29618 # rb cristina.riveron Change 3271300 on 2017/01/25 by Luke.Thatcher [PLATFORM] [PS4] [^] Merge (as edit) fix for NpToolkit2 initialization in 6CPU mode, from //UE4/Dev-Platform to //UE4/Release-4.15 (Original CL 3271215) - Default thread affinity in the InitParams structure is 7 CPUs. - Using this affinity in games with 6CPU mode set in param.sfo causes init() to fail. - We now select 6 or 7 CPU affinity based on what sceKernelGetCpumode reports at runtime. #jira UE-41079 Change 3271197 on 2017/01/25 by Andrew.Rodham Sequencer: Ensure initial evaluation range correctly sets exclusive lower boundary for subsequent evaluations - This prevents us from erroneously evaluating the initial time twice as part of swept evaluations) #jira UE-40758 Change 3270386 on 2017/01/24 by tim.gautier Updated UMG_Blur to include second Low-Quality asset #jira UE-29618 Change 3270267 on 2017/01/24 by Arciel.Rekman Linux: fix not being able to run a packaged build (UE-37016, UE-39648). - Fixed expansion of paths with spaces in the bootstrap script. - Also increased the timeout since large projects can sometimes get killed on start. - Also killed spammy console output. #jira UE-37016 Change 3270203 on 2017/01/24 by Chris.Babcock Fixed issue with Mac and Linux install and uninstall scripts if ANDROID_HOME not set (contributed by nathansizemore) #jira UE-41042 #PR #3160 #ue4 #android Change 3270037 on 2017/01/24 by tim.gautier Checking in UMG_Blur for UMG test coverage #jira UE-29618 Change 3269829 on 2017/01/24 by matt.barnes Adding content for Material Attribute testing #jira UE-29618 Change 3269700 on 2017/01/24 by Josh.Stoddard force relink of PhysX libs #jira UE-39791 #rb ori.cohen #lockdown james.golding Change 3269621 on 2017/01/24 by Allan.Bentham Make sure 'intrinsic_GetHDR32bppEncodeModeES2()' reports no encoding mode when mobileHDR == false #jira UE-41023 Change 3269503 on 2017/01/24 by Josh.Stoddard Integrate PhysX change 3268008 from //UE4/Dev-Physics-Upgrade #jira UE-39791 #lockdown james.golding #rb josh.stoddard Change3269359on 2017/01/24 by Jack.Porter Fix for Web browser widget crash on Android when packaged for Distribution #jira UE-39451 Change 3269316 on 2017/01/24 by Thomas.Sarkanen Fixed non-unity issues with last change for UE-40945 #jira UE-40945 - Crash trying to import facial animations Change 3269047 on 2017/01/23 by Yannick.Lange VREditor: Fix VREditor Laser not hidden on MotionControllers with docked Menu/UI Panels #jira UE-40070 Change 3268824 on 2017/01/23 by Rolando.Caloca UE4.15 - Fix for right eye showing black on VR #jira UE-40900 Change 3268752 on 2017/01/23 by Nick.Whiting Fix for assertion for binding an MSAA'd scene color with a non-MSAA'd texture. #jira UE-39304 Change 3268722 on 2017/01/23 by Olaf.Piesche Replicating 3256329 #jira UE-38615 Removing unnecessary assert that fires when exporting emitters. Change 3268220 on 2017/01/23 by Nick.Whiting Adding in a new CVar (vr.SteamVR.UsePostPresentHandoff), which defaults to 0. When set to 0, we do NOT use the SteamVR PostPresentHandoff, which costs some performance GPU time. When 1, we use the call, and get some extra GPU performance. However, this call is NOT safe for scenes that have frame-behind GPU work, like SceneCapture components and Widget Components #jira UE-40570 Change 3268180 on 2017/01/23 by Marc.Audy PendingKill Actors will no longer register their components when the level is being loaded #jira UE-40505 Change 3268076 on 2017/01/23 by Matthew.Griffin Changed Mac SunTemple cook jobs to use Sample Editor to avoid errors about mismatched files #jira UE-40806 Change 3267997 on 2017/01/23 by Mitchell.Wilson Increased lightmap size on spheres in volumes example to resolve issue with lighting. Corrected misspelling in multiple examples and one UMG asset. #jira UE-40890 UE-40926 UE-40882 UE-40928 UE-40825 UE-40819 Change 3267892 on 2017/01/23 by Mitchell.Wilson Removed preview mesh on M_Bird_Inst that was referencing a static mesh that was removed or renamed to resolve warnings in CIS. #jira UE-40300 Change 3267866 on 2017/01/23 by Thomas.Sarkanen Prevented crash when using Facial Animation importer Also hid the feature behind an experiemental setting flag, as it is not ready for users yet. #jira UE-40945 - Crash trying to import facial animations Change 3267834 on 2017/01/23 by Nick.Darnell An addition to 3255247, this also adds input processing incrementing for double click, and preview mouse down. #jira UE-40313 Change 3267785 on 2017/01/23 by Marc.Audy Put proper line endings when modifying template files when installing feature pack #jira UE-40939 Change 3267761 on 2017/01/23 by Mitchell.Wilson Moved left landscape mesh slightly to hide a seam that can be seen when using VR and looking over the railing. #jira UE-40916 Change 3267632 on 2017/01/23 by Jurre.deBaare Marker syncs not working correctly in Blend Spaces #fix Ensure that SampleIndexWithMarkers is serialized #JIRA UE-40975 [CL 3287682 by Matthew Griffin in Main branch]
1277 lines
43 KiB
C++
1277 lines
43 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LandscapeGizmoActor.h"
|
|
#include "Misc/MessageDialog.h"
|
|
#include "Misc/FileHelper.h"
|
|
#include "Misc/FeedbackContext.h"
|
|
#include "UObject/ConstructorHelpers.h"
|
|
#include "EngineDefines.h"
|
|
#include "RHI.h"
|
|
#include "PrimitiveViewRelevance.h"
|
|
#include "PrimitiveSceneProxy.h"
|
|
#include "MaterialShared.h"
|
|
#include "LandscapeInfo.h"
|
|
#include "Engine/Texture2D.h"
|
|
#include "LandscapeLayerInfoObject.h"
|
|
#include "LandscapeInfoMap.h"
|
|
#include "LandscapeDataAccess.h"
|
|
#include "LandscapeRender.h"
|
|
#include "LandscapeGizmoActiveActor.h"
|
|
#include "LandscapeGizmoRenderComponent.h"
|
|
#include "DynamicMeshBuilder.h"
|
|
#include "Engine/CollisionProfile.h"
|
|
#include "EngineUtils.h"
|
|
#include "Materials/Material.h"
|
|
#include "Materials/MaterialInstanceConstant.h"
|
|
#include "Components/BillboardComponent.h"
|
|
|
|
namespace
|
|
{
|
|
enum PreviewType
|
|
{
|
|
Invalid = -1,
|
|
Both = 0,
|
|
Add = 1,
|
|
Sub = 2,
|
|
};
|
|
}
|
|
|
|
|
|
class FLandscapeGizmoMeshRenderProxy : public FMaterialRenderProxy
|
|
{
|
|
public:
|
|
const FMaterialRenderProxy* const Parent;
|
|
const float TopHeight;
|
|
const float BottomHeight;
|
|
const UTexture2D* AlphaTexture;
|
|
const FLinearColor ScaleBias;
|
|
const FMatrix WorldToLandscapeMatrix;
|
|
|
|
/** Initialization constructor. */
|
|
FLandscapeGizmoMeshRenderProxy(const FMaterialRenderProxy* InParent, const float InTop, const float InBottom, const UTexture2D* InAlphaTexture, const FLinearColor& InScaleBias, const FMatrix& InWorldToLandscapeMatrix)
|
|
: Parent(InParent)
|
|
, TopHeight(InTop)
|
|
, BottomHeight(InBottom)
|
|
, AlphaTexture(InAlphaTexture)
|
|
, ScaleBias(InScaleBias)
|
|
, WorldToLandscapeMatrix(InWorldToLandscapeMatrix)
|
|
{}
|
|
|
|
// FMaterialRenderProxy interface.
|
|
virtual const class FMaterial* GetMaterial(ERHIFeatureLevel::Type InFeatureLevel) const
|
|
{
|
|
return Parent->GetMaterial(InFeatureLevel);
|
|
}
|
|
virtual bool GetVectorValue(const FName ParameterName, FLinearColor* OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
if (ParameterName == FName(TEXT("AlphaScaleBias")))
|
|
{
|
|
*OutValue = ScaleBias;
|
|
return true;
|
|
}
|
|
else
|
|
if (ParameterName == FName(TEXT("MatrixRow1")))
|
|
{
|
|
*OutValue = FLinearColor(WorldToLandscapeMatrix.M[0][0], WorldToLandscapeMatrix.M[0][1], WorldToLandscapeMatrix.M[0][2],WorldToLandscapeMatrix.M[0][3]);
|
|
return true;
|
|
}
|
|
else
|
|
if (ParameterName == FName(TEXT("MatrixRow2")))
|
|
{
|
|
*OutValue = FLinearColor(WorldToLandscapeMatrix.M[1][0], WorldToLandscapeMatrix.M[1][1], WorldToLandscapeMatrix.M[1][2],WorldToLandscapeMatrix.M[1][3]);
|
|
return true;
|
|
}
|
|
else
|
|
if (ParameterName == FName(TEXT("MatrixRow3")))
|
|
{
|
|
*OutValue = FLinearColor(WorldToLandscapeMatrix.M[2][0], WorldToLandscapeMatrix.M[2][1], WorldToLandscapeMatrix.M[2][2],WorldToLandscapeMatrix.M[2][3]);
|
|
return true;
|
|
}
|
|
else
|
|
if (ParameterName == FName(TEXT("MatrixRow4")))
|
|
{
|
|
*OutValue = FLinearColor(WorldToLandscapeMatrix.M[3][0], WorldToLandscapeMatrix.M[3][1], WorldToLandscapeMatrix.M[3][2],WorldToLandscapeMatrix.M[3][3]);
|
|
return true;
|
|
}
|
|
|
|
return Parent->GetVectorValue(ParameterName, OutValue, Context);
|
|
}
|
|
virtual bool GetScalarValue(const FName ParameterName, float* OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
if (ParameterName == FName(TEXT("Top")))
|
|
{
|
|
*OutValue = TopHeight;
|
|
return true;
|
|
}
|
|
else if (ParameterName == FName(TEXT("Bottom")))
|
|
{
|
|
*OutValue = BottomHeight;
|
|
return true;
|
|
}
|
|
return Parent->GetScalarValue(ParameterName, OutValue, Context);
|
|
}
|
|
virtual bool GetTextureValue(const FName ParameterName,const UTexture** OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
if (ParameterName == FName(TEXT("AlphaTexture")))
|
|
{
|
|
// FIXME: This needs to return a black texture if AlphaTexture is NULL.
|
|
// Returning NULL will cause the material to use GWhiteTexture.
|
|
*OutValue = AlphaTexture;
|
|
return true;
|
|
}
|
|
return Parent->GetTextureValue(ParameterName, OutValue, Context);
|
|
}
|
|
};
|
|
|
|
/** Represents a LandscapeGizmoRenderingComponent to the scene manager. */
|
|
class FLandscapeGizmoRenderSceneProxy : public FPrimitiveSceneProxy
|
|
{
|
|
public:
|
|
FMatrix MeshRT;
|
|
FVector XAxis, YAxis, Origin;
|
|
FVector FrustumVerts[8];
|
|
float SampleSizeX, SampleSizeY;
|
|
TArray<FVector> SampledPositions;
|
|
TArray<FVector> SampledNormals;
|
|
bool bHeightmapRendering;
|
|
FLandscapeGizmoMeshRenderProxy* HeightmapRenderProxy;
|
|
FMaterialRenderProxy* GizmoRenderProxy;
|
|
HHitProxy* HitProxy;
|
|
|
|
FLandscapeGizmoRenderSceneProxy(const ULandscapeGizmoRenderComponent* InComponent):
|
|
FPrimitiveSceneProxy(InComponent),
|
|
bHeightmapRendering(false),
|
|
HeightmapRenderProxy(nullptr),
|
|
GizmoRenderProxy(nullptr),
|
|
HitProxy(nullptr)
|
|
{
|
|
#if WITH_EDITOR
|
|
ALandscapeGizmoActiveActor* Gizmo = Cast<ALandscapeGizmoActiveActor>(InComponent->GetOwner());
|
|
if (Gizmo && Gizmo->GizmoMeshMaterial && Gizmo->GizmoDataMaterial && Gizmo->GetRootComponent())
|
|
{
|
|
ULandscapeInfo* LandscapeInfo = Gizmo->TargetLandscapeInfo;
|
|
if (LandscapeInfo && LandscapeInfo->GetLandscapeProxy())
|
|
{
|
|
SampleSizeX = Gizmo->SampleSizeX;
|
|
SampleSizeY = Gizmo->SampleSizeY;
|
|
bHeightmapRendering = (Gizmo->DataType & LGT_Height);
|
|
FTransform LToW = LandscapeInfo->GetLandscapeProxy()->LandscapeActorToWorld();
|
|
const float W = Gizmo->Width / 2;
|
|
const float H = Gizmo->Height / 2;
|
|
const float L = Gizmo->LengthZ;
|
|
// The Gizmo's coordinate space is weird, it's partially relative to the landscape and partially relative to the world
|
|
const FVector GizmoLocation = Gizmo->GetActorLocation();
|
|
const FQuat GizmoRotation = FRotator(0, Gizmo->GetActorRotation().Yaw, 0).Quaternion() * LToW.GetRotation();
|
|
const FVector GizmoScale3D = Gizmo->GetActorScale3D();
|
|
const FTransform GizmoRT = FTransform(GizmoRotation, GizmoLocation, GizmoScale3D);
|
|
|
|
FrustumVerts[0] = Gizmo->FrustumVerts[0] = GizmoRT.TransformPosition(FVector( - W, - H, + L ));
|
|
FrustumVerts[1] = Gizmo->FrustumVerts[1] = GizmoRT.TransformPosition(FVector( + W, - H, + L ));
|
|
FrustumVerts[2] = Gizmo->FrustumVerts[2] = GizmoRT.TransformPosition(FVector( + W, + H, + L ));
|
|
FrustumVerts[3] = Gizmo->FrustumVerts[3] = GizmoRT.TransformPosition(FVector( - W, + H, + L ));
|
|
|
|
FrustumVerts[4] = Gizmo->FrustumVerts[4] = GizmoRT.TransformPosition(FVector( - W, - H, 0 ));
|
|
FrustumVerts[5] = Gizmo->FrustumVerts[5] = GizmoRT.TransformPosition(FVector( + W, - H, 0 ));
|
|
FrustumVerts[6] = Gizmo->FrustumVerts[6] = GizmoRT.TransformPosition(FVector( + W, + H, 0 ));
|
|
FrustumVerts[7] = Gizmo->FrustumVerts[7] = GizmoRT.TransformPosition(FVector( - W, + H, 0 ));
|
|
|
|
XAxis = GizmoRT.TransformPosition(FVector( + W, 0, + L ));
|
|
YAxis = GizmoRT.TransformPosition(FVector( 0, + H, + L ));
|
|
Origin = GizmoRT.TransformPosition(FVector( 0, 0, + L ));
|
|
|
|
const FMatrix WToL = LToW.ToMatrixWithScale().InverseFast();
|
|
const FVector BaseLocation = WToL.TransformPosition(Gizmo->GetActorLocation());
|
|
const float ScaleXY = LandscapeInfo->DrawScale.X;
|
|
|
|
MeshRT = FTranslationMatrix(FVector(-W / ScaleXY + 0.5, -H / ScaleXY + 0.5, 0) * GizmoScale3D) * FRotationTranslationMatrix(FRotator(0, Gizmo->GetActorRotation().Yaw, 0), FVector(BaseLocation.X, BaseLocation.Y, 0)) * LToW.ToMatrixWithScale();
|
|
HeightmapRenderProxy = new FLandscapeGizmoMeshRenderProxy( Gizmo->GizmoMeshMaterial->GetRenderProxy(false), BaseLocation.Z + L, BaseLocation.Z, Gizmo->GizmoTexture, FLinearColor(Gizmo->TextureScale.X, Gizmo->TextureScale.Y, 0, 0), WToL );
|
|
|
|
GizmoRenderProxy = (Gizmo->DataType != LGT_None) ? Gizmo->GizmoDataMaterial->GetRenderProxy(false) : Gizmo->GizmoMaterial->GetRenderProxy(false);
|
|
|
|
// Cache sampled height
|
|
float ScaleX = Gizmo->GetWidth() / Gizmo->CachedWidth / ScaleXY * Gizmo->CachedScaleXY;
|
|
float ScaleY = Gizmo->GetHeight() / Gizmo->CachedHeight / ScaleXY * Gizmo->CachedScaleXY;
|
|
FScaleMatrix Mat(FVector(ScaleX, ScaleY, L));
|
|
FMatrix NormalM = Mat.InverseFast().GetTransposed();
|
|
|
|
int32 SamplingSize = Gizmo->SampleSizeX * Gizmo->SampleSizeY;
|
|
SampledPositions.Empty(SamplingSize);
|
|
SampledNormals.Empty(SamplingSize);
|
|
|
|
for (int32 Y = 0; Y < Gizmo->SampleSizeY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < Gizmo->SampleSizeX; ++X)
|
|
{
|
|
FVector SampledPos = Gizmo->SampledHeight[X + Y * ALandscapeGizmoActiveActor::DataTexSize];
|
|
SampledPos.X *= ScaleX;
|
|
SampledPos.Y *= ScaleY;
|
|
SampledPos.Z = Gizmo->GetLandscapeHeight(SampledPos.Z);
|
|
|
|
FVector SampledNormal = NormalM.TransformVector(Gizmo->SampledNormal[X + Y * ALandscapeGizmoActiveActor::DataTexSize]);
|
|
SampledNormal = SampledNormal.GetSafeNormal();
|
|
|
|
SampledPositions.Add(SampledPos);
|
|
SampledNormals.Add(SampledNormal);
|
|
//MeshBuilder.AddVertex(SampledPos, FVector2D((float)X / (Gizmo->SampleSizeX), (float)Y / (Gizmo->SampleSizeY)), TangentX, SampledNormal^TangentX, SampledNormal, FColor::White );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
~FLandscapeGizmoRenderSceneProxy()
|
|
{
|
|
delete HeightmapRenderProxy;
|
|
HeightmapRenderProxy = NULL;
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
virtual HHitProxy* CreateHitProxies(UPrimitiveComponent* Component, TArray<TRefCountPtr<HHitProxy> >& OutHitProxies) override
|
|
{
|
|
ALandscapeGizmoActiveActor* Gizmo = CastChecked<ALandscapeGizmoActiveActor>(Component->GetOwner());
|
|
HitProxy = new HTranslucentActor(Gizmo, Component);
|
|
OutHitProxies.Add(HitProxy);
|
|
|
|
// by default we're not clickable, to allow the preview heightmap to be non-clickable (only the bounds frame)
|
|
return nullptr;
|
|
}
|
|
#endif
|
|
|
|
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
|
|
{
|
|
//FMemMark Mark(FMemStack::Get());
|
|
#if WITH_EDITOR
|
|
if( GizmoRenderProxy && HeightmapRenderProxy )
|
|
{
|
|
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
|
|
{
|
|
if (VisibilityMap & (1 << ViewIndex))
|
|
{
|
|
const FSceneView* View = Views[ViewIndex];
|
|
FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex);
|
|
|
|
// Axis
|
|
PDI->DrawLine( Origin, XAxis, FLinearColor(1, 0, 0), SDPG_World );
|
|
PDI->DrawLine( Origin, YAxis, FLinearColor(0, 1, 0), SDPG_World );
|
|
|
|
{
|
|
FDynamicMeshBuilder MeshBuilder;
|
|
|
|
const FColor GizmoColor = FColor::White;
|
|
MeshBuilder.AddVertex(FrustumVerts[0], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[1], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[2], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[3], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
MeshBuilder.AddVertex(FrustumVerts[4], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[5], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[6], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[7], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
MeshBuilder.AddVertex(FrustumVerts[1], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[0], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[4], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[5], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
MeshBuilder.AddVertex(FrustumVerts[3], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[2], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[6], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[7], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
MeshBuilder.AddVertex(FrustumVerts[2], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[1], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[5], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[6], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
MeshBuilder.AddVertex(FrustumVerts[0], FVector2D(0, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[3], FVector2D(1, 0), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[7], FVector2D(1, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
MeshBuilder.AddVertex(FrustumVerts[4], FVector2D(0, 1), FVector(1,0,0), FVector(0,1,0), FVector(0,0,1), GizmoColor);
|
|
|
|
for (int32 i = 0; i < 6; ++i)
|
|
{
|
|
int32 Idx = i*4;
|
|
MeshBuilder.AddTriangle( Idx, Idx+2, Idx+1 );
|
|
MeshBuilder.AddTriangle( Idx, Idx+3, Idx+2 );
|
|
}
|
|
|
|
MeshBuilder.GetMesh(FMatrix::Identity, GizmoRenderProxy, SDPG_World, true, false, false, ViewIndex, Collector, HitProxy);
|
|
}
|
|
|
|
if (bHeightmapRendering)
|
|
{
|
|
FDynamicMeshBuilder MeshBuilder;
|
|
|
|
for (int32 Y = 0; Y < SampleSizeY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX; ++X)
|
|
{
|
|
FVector SampledNormal = SampledNormals[X + Y * SampleSizeX];
|
|
FVector TangentX(SampledNormal.Z, 0, -SampledNormal.X);
|
|
TangentX = TangentX.GetSafeNormal();
|
|
|
|
MeshBuilder.AddVertex(SampledPositions[X + Y * SampleSizeX], FVector2D((float)X / (SampleSizeX), (float)Y / (SampleSizeY)), TangentX, SampledNormal^TangentX, SampledNormal, FColor::White);
|
|
}
|
|
}
|
|
|
|
for (int32 Y = 0; Y < SampleSizeY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX; ++X)
|
|
{
|
|
if (X < SampleSizeX - 1 && Y < SampleSizeY - 1)
|
|
{
|
|
MeshBuilder.AddTriangle( (X+0) + (Y+0) * SampleSizeX, (X+1) + (Y+1) * SampleSizeX, (X+1) + (Y+0) * SampleSizeX );
|
|
MeshBuilder.AddTriangle( (X+0) + (Y+0) * SampleSizeX, (X+0) + (Y+1) * SampleSizeX, (X+1) + (Y+1) * SampleSizeX );
|
|
}
|
|
}
|
|
}
|
|
|
|
MeshBuilder.GetMesh(MeshRT, HeightmapRenderProxy , SDPG_World, false, false, ViewIndex, Collector);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
};
|
|
|
|
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
|
|
{
|
|
FPrimitiveViewRelevance Result;
|
|
#if WITH_EDITOR
|
|
const bool bVisible = View->Family->EngineShowFlags.Landscape;
|
|
Result.bDrawRelevance = IsShown(View) && bVisible && !View->bIsGameView && GLandscapeEditRenderMode & ELandscapeEditRenderMode::Gizmo;
|
|
Result.bDynamicRelevance = true;
|
|
// ideally the TranslucencyRelevance should be filled out by the material, here we do it conservative
|
|
Result.bSeparateTranslucencyRelevance = Result.bNormalTranslucencyRelevance = true;
|
|
#endif
|
|
return Result;
|
|
}
|
|
|
|
virtual uint32 GetMemoryFootprint( void ) const override { return( sizeof( *this ) + GetAllocatedSize() ); }
|
|
uint32 GetAllocatedSize( void ) const { return( FPrimitiveSceneProxy::GetAllocatedSize() ); }
|
|
};
|
|
|
|
ULandscapeGizmoRenderComponent::ULandscapeGizmoRenderComponent(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
bHiddenInGame = true;
|
|
bIsEditorOnly = true;
|
|
SetCollisionProfileName(UCollisionProfile::BlockAll_ProfileName);
|
|
}
|
|
|
|
FPrimitiveSceneProxy* ULandscapeGizmoRenderComponent::CreateSceneProxy()
|
|
{
|
|
return new FLandscapeGizmoRenderSceneProxy(this);
|
|
}
|
|
|
|
void ULandscapeGizmoRenderComponent::GetUsedMaterials(TArray<UMaterialInterface*>& OutMaterials, bool bGetDebugMaterials) const
|
|
{
|
|
#if WITH_EDITORONLY_DATA
|
|
ALandscapeGizmoActiveActor* Gizmo = Cast<ALandscapeGizmoActiveActor>(GetOwner());
|
|
if (Gizmo)
|
|
{
|
|
UMaterialInterface* GizmoMat = (Gizmo->DataType != LGT_None) ?
|
|
(UMaterialInterface*)Gizmo->GizmoDataMaterial :
|
|
(UMaterialInterface*)Gizmo->GizmoMaterial;
|
|
|
|
if (GizmoMat)
|
|
{
|
|
OutMaterials.Add(GizmoMat);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
FBoxSphereBounds ULandscapeGizmoRenderComponent::CalcBounds(const FTransform& LocalToWorld) const
|
|
{
|
|
#if WITH_EDITOR
|
|
ALandscapeGizmoActiveActor* Gizmo = Cast<ALandscapeGizmoActiveActor>(GetOwner());
|
|
if (Gizmo)
|
|
{
|
|
ULandscapeInfo* LandscapeInfo = Gizmo->TargetLandscapeInfo;
|
|
if (LandscapeInfo && LandscapeInfo->GetLandscapeProxy())
|
|
{
|
|
FTransform LToW = LandscapeInfo->GetLandscapeProxy()->LandscapeActorToWorld();
|
|
|
|
// We calculate this ourselves, not from Gizmo->FrustrumVerts, as those haven't been updated yet
|
|
// The Gizmo's coordinate space is weird, it's partially relative to the landscape and partially relative to the world
|
|
const FVector GizmoLocation = Gizmo->GetActorLocation();
|
|
const FQuat GizmoRotation = FRotator(0, Gizmo->GetActorRotation().Yaw, 0).Quaternion() * LToW.GetRotation();
|
|
const FVector GizmoScale3D = Gizmo->GetActorScale3D();
|
|
const FTransform GizmoRT = FTransform(GizmoRotation, GizmoLocation, GizmoScale3D);
|
|
const float W = Gizmo->Width / 2;
|
|
const float H = Gizmo->Height / 2;
|
|
const float L = Gizmo->LengthZ;
|
|
return FBoxSphereBounds(FBox(FVector(-W, -H, 0), FVector(+W, +H, +L))).TransformBy(GizmoRT);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return Super::CalcBounds(LocalToWorld);
|
|
}
|
|
|
|
ALandscapeGizmoActor::ALandscapeGizmoActor(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
#if WITH_EDITORONLY_DATA
|
|
SpriteComponent = CreateEditorOnlyDefaultSubobject<UBillboardComponent>(TEXT("Sprite"));
|
|
if (!IsRunningCommandlet() && (SpriteComponent != nullptr))
|
|
{
|
|
// Structure to hold one-time initialization
|
|
struct FConstructorStatics
|
|
{
|
|
ConstructorHelpers::FObjectFinderOptional<UTexture2D> DecalActorIconTexture;
|
|
FName ID_Misc;
|
|
FText NAME_Misc;
|
|
FConstructorStatics()
|
|
: DecalActorIconTexture(TEXT("Texture2D'/Engine/EditorResources/S_DecalActorIcon.S_DecalActorIcon'"))
|
|
, ID_Misc(TEXT("Misc"))
|
|
, NAME_Misc(NSLOCTEXT("SpriteCategory", "Misc", "Misc"))
|
|
{
|
|
}
|
|
};
|
|
static FConstructorStatics ConstructorStatics;
|
|
|
|
SpriteComponent->Sprite = ConstructorStatics.DecalActorIconTexture.Get();
|
|
SpriteComponent->RelativeScale3D = FVector(0.5f, 0.5f, 0.5f);
|
|
SpriteComponent->bHiddenInGame = true;
|
|
SpriteComponent->SpriteInfo.Category = ConstructorStatics.ID_Misc;
|
|
SpriteComponent->SpriteInfo.DisplayName = ConstructorStatics.NAME_Misc;
|
|
SpriteComponent->bIsScreenSizeScaled = true;
|
|
}
|
|
#endif
|
|
|
|
USceneComponent* SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent0"));
|
|
RootComponent = SceneComponent;
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
bEditable = false;
|
|
Width = 1280.0f;
|
|
Height = 1280.0f;
|
|
LengthZ = 1280.0f;
|
|
MarginZ = 512.0f;
|
|
MinRelativeZ = 0.0f;
|
|
RelativeScaleZ = 1.0f;
|
|
#endif // WITH_EDITORONLY_DATA
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
|
|
void ALandscapeGizmoActor::Duplicate(ALandscapeGizmoActor* Gizmo)
|
|
{
|
|
Gizmo->Width = Width;
|
|
Gizmo->Height = Height;
|
|
Gizmo->LengthZ = LengthZ;
|
|
Gizmo->MarginZ = MarginZ;
|
|
//Gizmo->TargetLandscapeInfo = TargetLandscapeInfo;
|
|
|
|
Gizmo->SetActorLocation( GetActorLocation(), false );
|
|
Gizmo->SetActorRotation( GetActorRotation() );
|
|
|
|
if( Gizmo->GetRootComponent() != NULL && GetRootComponent() != NULL )
|
|
{
|
|
Gizmo->GetRootComponent()->SetRelativeScale3D( GetRootComponent()->RelativeScale3D );
|
|
}
|
|
|
|
Gizmo->MinRelativeZ = MinRelativeZ;
|
|
Gizmo->RelativeScaleZ = RelativeScaleZ;
|
|
|
|
Gizmo->ReregisterAllComponents();
|
|
}
|
|
#endif //WITH_EDITOR
|
|
|
|
ALandscapeGizmoActiveActor::ALandscapeGizmoActiveActor(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer
|
|
.DoNotCreateDefaultSubobject(TEXT("Sprite"))
|
|
)
|
|
{
|
|
#if WITH_EDITORONLY_DATA
|
|
if (!IsRunningCommandlet())
|
|
{
|
|
// Structure to hold one-time initialization
|
|
struct FConstructorStatics
|
|
{
|
|
ConstructorHelpers::FObjectFinder<UMaterial> LandscapeGizmo_Mat;
|
|
ConstructorHelpers::FObjectFinder<UMaterialInstanceConstant> LandscapeGizmo_Mat_Copied;
|
|
ConstructorHelpers::FObjectFinder<UMaterial> LandscapeGizmoHeight_Mat;
|
|
FConstructorStatics()
|
|
: LandscapeGizmo_Mat(TEXT("/Engine/EditorLandscapeResources/LandscapeGizmo_Mat"))
|
|
, LandscapeGizmo_Mat_Copied(TEXT("/Engine/EditorLandscapeResources/LandscapeGizmo_Mat_Copied"))
|
|
, LandscapeGizmoHeight_Mat(TEXT("/Engine/EditorLandscapeResources/LandscapeGizmoHeight_Mat"))
|
|
{
|
|
}
|
|
};
|
|
static FConstructorStatics ConstructorStatics;
|
|
|
|
GizmoMaterial = ConstructorStatics.LandscapeGizmo_Mat.Object;
|
|
GizmoDataMaterial = ConstructorStatics.LandscapeGizmo_Mat_Copied.Object;
|
|
GizmoMeshMaterial = ConstructorStatics.LandscapeGizmoHeight_Mat.Object;
|
|
}
|
|
#endif // WITH_EDITORONLY_DATA
|
|
|
|
ULandscapeGizmoRenderComponent* LandscapeGizmoRenderComponent = CreateDefaultSubobject<ULandscapeGizmoRenderComponent>(TEXT("GizmoRendererComponent0"));
|
|
LandscapeGizmoRenderComponent->SetCollisionProfileName(UCollisionProfile::BlockAllDynamic_ProfileName);
|
|
|
|
RootComponent = LandscapeGizmoRenderComponent;
|
|
#if WITH_EDITORONLY_DATA
|
|
bEditable = true;
|
|
Width = 1280.0f;
|
|
Height = 1280.0f;
|
|
LengthZ = 1280.0f;
|
|
MarginZ = 512.0f;
|
|
DataType = LGT_None;
|
|
SampleSizeX = 0;
|
|
SampleSizeY = 0;
|
|
CachedWidth = 0.0f;
|
|
CachedHeight = 0.0f;
|
|
CachedScaleXY = 1.0f;
|
|
#endif // WITH_EDITORONLY_DATA
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void ALandscapeGizmoActiveActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
const FName PropertyName = PropertyChangedEvent.Property ? PropertyChangedEvent.Property->GetFName() : NAME_None;
|
|
if( PropertyName == FName(TEXT("LengthZ")) )
|
|
{
|
|
if (LengthZ < 0)
|
|
{
|
|
LengthZ = MarginZ;
|
|
}
|
|
}
|
|
else if ( PropertyName == FName(TEXT("TargetLandscapeInfo")) )
|
|
{
|
|
SetTargetLandscape(TargetLandscapeInfo);
|
|
}
|
|
// AActor::PostEditChange will ForceUpdateComponents()
|
|
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
}
|
|
|
|
|
|
void ALandscapeGizmoActiveActor::PostEditMove(bool bFinished)
|
|
{
|
|
Super::PostEditMove( bFinished );
|
|
|
|
if (bFinished)
|
|
{
|
|
UnsnappedRotation = FRotator::ZeroRotator;
|
|
}
|
|
}
|
|
|
|
FVector ALandscapeGizmoActiveActor::SnapToLandscapeGrid(const FVector& GizmoLocation) const
|
|
{
|
|
check(TargetLandscapeInfo);
|
|
const FTransform LToW = TargetLandscapeInfo->GetLandscapeProxy()->LandscapeActorToWorld();
|
|
const FVector LandscapeSpaceLocation = LToW.InverseTransformPosition(GizmoLocation);
|
|
const FVector SnappedLandscapeSpaceLocation = LandscapeSpaceLocation.GridSnap(1);
|
|
const FVector ResultLocation = LToW.TransformPosition(SnappedLandscapeSpaceLocation);
|
|
return ResultLocation;
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::EditorApplyTranslation(const FVector& DeltaTranslation, bool bAltDown, bool bShiftDown, bool bCtrlDown)
|
|
{
|
|
if (bSnapToLandscapeGrid)
|
|
{
|
|
const FVector GizmoLocation = GetActorLocation() + DeltaTranslation;
|
|
const FVector ResultLocation = SnapToLandscapeGrid(GizmoLocation);
|
|
|
|
SetActorLocation(ResultLocation, false);
|
|
}
|
|
else
|
|
{
|
|
Super::EditorApplyTranslation(DeltaTranslation, bAltDown, bShiftDown, bCtrlDown);
|
|
}
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
|
|
FRotator ALandscapeGizmoActiveActor::SnapToLandscapeGrid(const FRotator& GizmoRotation) const
|
|
{
|
|
// Snap to multiples of 90 Yaw in landscape coordinate system
|
|
//check(TargetLandscapeInfo && TargetLandscapeInfo->LandscapeProxy);
|
|
//const FTransform LToW = TargetLandscapeInfo->LandscapeProxy->ActorToWorld();
|
|
//const FRotator LandscapeSpaceRotation = (LToW.GetRotation().InverseFast() * GizmoRotation.Quaternion()).Rotator().GetNormalized();
|
|
//const FRotator SnappedLandscapeSpaceRotation = FRotator(0, FMath::GridSnap(LandscapeSpaceRotation.Yaw, 90), 0);
|
|
//const FRotator ResultRotation = (SnappedLandscapeSpaceRotation.Quaternion() * LToW.GetRotation()).Rotator().GetNormalized();
|
|
|
|
// Gizmo rotation is used as if it was relative to the landscape even though it isn't, so snap in world space
|
|
const FRotator ResultRotation = FRotator(0, FMath::GridSnap(GizmoRotation.Yaw, 90), 0);
|
|
return ResultRotation;
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::EditorApplyRotation(const FRotator& DeltaRotation, bool bAltDown, bool bShiftDown, bool bCtrlDown)
|
|
{
|
|
if (bSnapToLandscapeGrid)
|
|
{
|
|
// Based on AActor::EditorApplyRotation
|
|
FRotator GizmoRotation = GetActorRotation() + UnsnappedRotation;
|
|
FRotator Winding, Remainder;
|
|
GizmoRotation.GetWindingAndRemainder(Winding, Remainder);
|
|
const FQuat ActorQ = Remainder.Quaternion();
|
|
const FQuat DeltaQ = DeltaRotation.Quaternion();
|
|
const FQuat ResultQ = DeltaQ * ActorQ;
|
|
const FRotator NewActorRotRem = FRotator( ResultQ );
|
|
FRotator DeltaRot = NewActorRotRem - Remainder;
|
|
DeltaRot.Normalize();
|
|
|
|
GizmoRotation += DeltaRot;
|
|
|
|
const FRotator ResultRotation = SnapToLandscapeGrid(GizmoRotation);
|
|
|
|
UnsnappedRotation = GizmoRotation - ResultRotation;
|
|
UnsnappedRotation.Pitch = 0;
|
|
UnsnappedRotation.Roll = 0;
|
|
UnsnappedRotation.Normalize();
|
|
|
|
SetActorRotation(ResultRotation);
|
|
}
|
|
else
|
|
{
|
|
Super::EditorApplyRotation(DeltaRotation, bAltDown, bShiftDown, bCtrlDown);
|
|
}
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
|
|
ALandscapeGizmoActor* ALandscapeGizmoActiveActor::SpawnGizmoActor()
|
|
{
|
|
// ALandscapeGizmoActor is history for ALandscapeGizmoActiveActor
|
|
ALandscapeGizmoActor* NewActor = GetWorld()->SpawnActor<ALandscapeGizmoActor>();
|
|
Duplicate(NewActor);
|
|
return NewActor;
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::SetTargetLandscape(ULandscapeInfo* LandscapeInfo)
|
|
{
|
|
ULandscapeInfo* PrevInfo = TargetLandscapeInfo;
|
|
if (!LandscapeInfo || LandscapeInfo->HasAnyFlags(RF_BeginDestroyed))
|
|
{
|
|
TargetLandscapeInfo = nullptr;
|
|
if (GetWorld())
|
|
{
|
|
for (const TPair<FGuid, ULandscapeInfo*>& InfoMapPair : ULandscapeInfoMap::GetLandscapeInfoMap(GetWorld()).Map)
|
|
{
|
|
ULandscapeInfo* CandidateInfo = InfoMapPair.Value;
|
|
if (CandidateInfo && !CandidateInfo->HasAnyFlags(RF_BeginDestroyed) && CandidateInfo->GetLandscapeProxy() != nullptr)
|
|
{
|
|
TargetLandscapeInfo = CandidateInfo;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TargetLandscapeInfo = LandscapeInfo;
|
|
}
|
|
|
|
// if there's no copied data, try to move somewhere useful
|
|
if (TargetLandscapeInfo && TargetLandscapeInfo != PrevInfo && DataType == LGT_None)
|
|
{
|
|
MarginZ = TargetLandscapeInfo->DrawScale.Z * 3;
|
|
Width = Height = TargetLandscapeInfo->DrawScale.X * (TargetLandscapeInfo->ComponentSizeQuads+1);
|
|
|
|
float NewLengthZ;
|
|
FVector NewLocation = TargetLandscapeInfo->GetLandscapeCenterPos(NewLengthZ);
|
|
SetLength(NewLengthZ);
|
|
SetActorLocation( NewLocation, false );
|
|
SetActorRotation(FRotator::ZeroRotator);
|
|
}
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::ClearGizmoData()
|
|
{
|
|
DataType = LGT_None;
|
|
SelectedData.Empty();
|
|
LayerInfos.Empty();
|
|
|
|
// If the clipboard contains copied gizmo data, clear it also
|
|
FString ClipboardString;
|
|
FPlatformMisc::ClipboardPaste(ClipboardString);
|
|
const TCHAR* Str = *ClipboardString;
|
|
if (FParse::Command(&Str, TEXT("GizmoData=")))
|
|
{
|
|
FPlatformMisc::ClipboardCopy(TEXT(""));
|
|
}
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::FitToSelection()
|
|
{
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
// Find fit size
|
|
int32 MinX = MAX_int32, MinY = MAX_int32;
|
|
int32 MaxX = MIN_int32, MaxY = MIN_int32;
|
|
TargetLandscapeInfo->GetSelectedExtent(MinX, MinY, MaxX, MaxY);
|
|
if (MinX != MAX_int32)
|
|
{
|
|
float ScaleXY = TargetLandscapeInfo->DrawScale.X;
|
|
Width = ScaleXY * (MaxX - MinX + 1) / (GetRootComponent()->RelativeScale3D.X);
|
|
Height = ScaleXY * (MaxY - MinY + 1) / (GetRootComponent()->RelativeScale3D.Y);
|
|
float NewLengthZ;
|
|
FVector NewLocation = TargetLandscapeInfo->GetLandscapeCenterPos(NewLengthZ, MinX, MinY, MaxX, MaxY);
|
|
SetLength(NewLengthZ);
|
|
SetActorLocation(NewLocation, false);
|
|
SetActorRotation(FRotator::ZeroRotator);
|
|
// Reset Z render scale values...
|
|
MinRelativeZ = 0.f;
|
|
RelativeScaleZ = 1.f;
|
|
ReregisterAllComponents();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::FitMinMaxHeight()
|
|
{
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
float MinZ = HALF_WORLD_MAX, MaxZ = -HALF_WORLD_MAX;
|
|
// Change MinRelativeZ and RelativeZScale to fit Gizmo Box
|
|
for (auto It = SelectedData.CreateConstIterator(); It; ++It )
|
|
{
|
|
const FGizmoSelectData& Data = It.Value();
|
|
MinZ = FMath::Min(MinZ, Data.HeightData);
|
|
MaxZ = FMath::Max(MaxZ, Data.HeightData);
|
|
}
|
|
|
|
if (MinZ != HALF_WORLD_MAX && MaxZ > MinZ + KINDA_SMALL_NUMBER)
|
|
{
|
|
MinRelativeZ = MinZ;
|
|
RelativeScaleZ = 1.f / (MaxZ - MinZ);
|
|
ReregisterAllComponents();
|
|
}
|
|
}
|
|
}
|
|
|
|
float ALandscapeGizmoActiveActor::GetNormalizedHeight(uint16 LandscapeHeight) const
|
|
{
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
ALandscapeProxy* Proxy = TargetLandscapeInfo->GetLandscapeProxy();
|
|
if (Proxy)
|
|
{
|
|
// Need to make it scale...?
|
|
float ZScale = GetLength();
|
|
if (ZScale > KINDA_SMALL_NUMBER)
|
|
{
|
|
FVector LocalGizmoPos = Proxy->LandscapeActorToWorld().InverseTransformPosition(GetActorLocation());
|
|
return FMath::Clamp<float>( (( LandscapeDataAccess::GetLocalHeight(LandscapeHeight) - LocalGizmoPos.Z) * TargetLandscapeInfo->DrawScale.Z) / ZScale, 0.f, 1.f );
|
|
}
|
|
}
|
|
}
|
|
return 0.f;
|
|
}
|
|
|
|
float ALandscapeGizmoActiveActor::GetWorldHeight(float NormalizedHeight) const
|
|
{
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
ALandscapeProxy* Proxy = TargetLandscapeInfo->GetLandscapeProxy();
|
|
if (Proxy)
|
|
{
|
|
float ZScale = GetLength();
|
|
if (ZScale > KINDA_SMALL_NUMBER)
|
|
{
|
|
FVector LocalGizmoPos = Proxy->LandscapeActorToWorld().InverseTransformPosition(GetActorLocation());
|
|
return NormalizedHeight * ZScale + LocalGizmoPos.Z * TargetLandscapeInfo->DrawScale.Z;
|
|
}
|
|
}
|
|
}
|
|
return 0.f;
|
|
}
|
|
|
|
float ALandscapeGizmoActiveActor::GetLandscapeHeight(float NormalizedHeight) const
|
|
{
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
NormalizedHeight = (NormalizedHeight - MinRelativeZ) * RelativeScaleZ;
|
|
float ScaleZ = TargetLandscapeInfo->DrawScale.Z;
|
|
return (GetWorldHeight(NormalizedHeight) / ScaleZ);
|
|
}
|
|
return 0.f;
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::CalcNormal()
|
|
{
|
|
int32 SquaredDataTex = DataTexSize * DataTexSize;
|
|
if (SampledHeight.Num() == SquaredDataTex && SampleSizeX > 0 && SampleSizeY > 0 )
|
|
{
|
|
if (SampledNormal.Num() != SquaredDataTex)
|
|
{
|
|
SampledNormal.Empty(SquaredDataTex);
|
|
SampledNormal.AddZeroed(SquaredDataTex);
|
|
}
|
|
for (int32 Y = 0; Y < SampleSizeY-1; ++Y)
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX-1; ++X)
|
|
{
|
|
FVector Vert00 = SampledHeight[X + Y*DataTexSize];
|
|
FVector Vert01 = SampledHeight[X + (Y+1)*DataTexSize];
|
|
FVector Vert10 = SampledHeight[X+1 + Y*DataTexSize];
|
|
FVector Vert11 = SampledHeight[X+1 + (Y+1)*DataTexSize];
|
|
|
|
FVector FaceNormal1 = ((Vert00-Vert10) ^ (Vert10-Vert11)).GetSafeNormal();
|
|
FVector FaceNormal2 = ((Vert11-Vert01) ^ (Vert01-Vert00)).GetSafeNormal();
|
|
|
|
// contribute to the vertex normals.
|
|
SampledNormal[X + Y*DataTexSize] += FaceNormal1;
|
|
SampledNormal[X + (Y+1)*DataTexSize] += FaceNormal2;
|
|
SampledNormal[X+1 + Y*DataTexSize] += FaceNormal1 + FaceNormal2;
|
|
SampledNormal[X+1 + (Y+1)*DataTexSize] += FaceNormal1 + FaceNormal2;
|
|
}
|
|
}
|
|
for (int32 Y = 0; Y < SampleSizeY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX; ++X)
|
|
{
|
|
SampledNormal[X + Y*DataTexSize] = SampledNormal[X + Y*DataTexSize].GetSafeNormal();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::SampleData(int32 SizeX, int32 SizeY)
|
|
{
|
|
if (TargetLandscapeInfo && GizmoTexture)
|
|
{
|
|
// Rasterize rendering Texture...
|
|
int32 TexSizeX = FMath::Min(ALandscapeGizmoActiveActor::DataTexSize, SizeX);
|
|
int32 TexSizeY = FMath::Min(ALandscapeGizmoActiveActor::DataTexSize, SizeY);
|
|
SampleSizeX = TexSizeX;
|
|
SampleSizeY = TexSizeY;
|
|
|
|
// Update Data Texture...
|
|
//DataTexture->SetFlags(RF_Transactional);
|
|
//DataTexture->Modify();
|
|
|
|
TextureScale = FVector2D( (float)SizeX / FMath::Max(ALandscapeGizmoActiveActor::DataTexSize, SizeX), (float)SizeY / FMath::Max(ALandscapeGizmoActiveActor::DataTexSize, SizeY));
|
|
uint8* TexData = GizmoTexture->Source.LockMip(0);
|
|
int32 GizmoTexSizeX = GizmoTexture->Source.GetSizeX();
|
|
for (int32 Y = 0; Y < TexSizeY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < TexSizeX; ++X)
|
|
{
|
|
float TexX = static_cast<float>(X) * SizeX / TexSizeX;
|
|
float TexY = static_cast<float>(Y) * SizeY / TexSizeY;
|
|
int32 LX = FMath::FloorToInt(TexX);
|
|
int32 LY = FMath::FloorToInt(TexY);
|
|
|
|
float FracX = TexX - LX;
|
|
float FracY = TexY - LY;
|
|
|
|
FGizmoSelectData* Data00 = SelectedData.Find(FIntPoint(LX, LY));
|
|
FGizmoSelectData* Data10 = SelectedData.Find(FIntPoint(LX+1, LY));
|
|
FGizmoSelectData* Data01 = SelectedData.Find(FIntPoint(LX, LY+1));
|
|
FGizmoSelectData* Data11 = SelectedData.Find(FIntPoint(LX+1, LY+1));
|
|
|
|
// Invert Tex Data to show selected region more visible
|
|
TexData[X + Y*GizmoTexSizeX] = 255 - FMath::Lerp(
|
|
FMath::Lerp(Data00 ? Data00->Ratio : 0, Data10 ? Data10->Ratio : 0, FracX),
|
|
FMath::Lerp(Data01 ? Data01->Ratio : 0, Data11 ? Data11->Ratio : 0, FracX),
|
|
FracY
|
|
) * 255;
|
|
|
|
if (DataType & LGT_Height)
|
|
{
|
|
float NormalizedHeight = FMath::Lerp(
|
|
FMath::Lerp(Data00 ? Data00->HeightData : 0, Data10 ? Data10->HeightData : 0, FracX),
|
|
FMath::Lerp(Data01 ? Data01->HeightData : 0, Data11 ? Data11->HeightData : 0, FracX),
|
|
FracY
|
|
);
|
|
|
|
SampledHeight[X + Y*GizmoTexSizeX] = FVector(LX, LY, NormalizedHeight);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (DataType & LGT_Height)
|
|
{
|
|
CalcNormal();
|
|
}
|
|
|
|
GizmoTexture->TemporarilyDisableStreaming();
|
|
FUpdateTextureRegion2D Region(0, 0, 0, 0, TexSizeX, TexSizeY);
|
|
GizmoTexture->UpdateTextureRegions(0, 1, &Region, GizmoTexSizeX, sizeof(uint8), TexData);
|
|
FlushRenderingCommands();
|
|
GizmoTexture->Source.UnlockMip(0);
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
}
|
|
|
|
LANDSCAPE_API void ALandscapeGizmoActiveActor::Import( int32 VertsX, int32 VertsY, uint16* HeightData, TArray<ULandscapeLayerInfoObject*> ImportLayerInfos, uint8* LayerDataPointers[] )
|
|
{
|
|
if (VertsX <= 0 || VertsY <= 0 || HeightData == NULL || TargetLandscapeInfo == NULL || GizmoTexture == NULL || (ImportLayerInfos.Num() && !LayerDataPointers) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
GWarn->BeginSlowTask( NSLOCTEXT("Landscape", "BeginImportingGizmoDataTask", "Importing Gizmo Data"), true);
|
|
|
|
ClearGizmoData();
|
|
|
|
CachedScaleXY = TargetLandscapeInfo->DrawScale.X;
|
|
CachedWidth = CachedScaleXY * VertsX; // (DrawScale * DrawScale3D.X);
|
|
CachedHeight = CachedScaleXY * VertsY; // (DrawScale * DrawScale3D.Y);
|
|
|
|
float CurrentWidth = GetWidth();
|
|
float CurrentHeight = GetHeight();
|
|
LengthZ = GetLength();
|
|
|
|
FVector Scale3D = FVector(CurrentWidth / CachedWidth, CurrentHeight / CachedHeight, 1.f);
|
|
GetRootComponent()->SetRelativeScale3D(Scale3D);
|
|
|
|
Width = CachedWidth;
|
|
Height = CachedHeight;
|
|
|
|
DataType = ELandscapeGizmoType(DataType | LGT_Height);
|
|
if (ImportLayerInfos.Num())
|
|
{
|
|
DataType = ELandscapeGizmoType(DataType | LGT_Weight);
|
|
}
|
|
|
|
for (int32 Y = 0; Y < VertsY; ++Y)
|
|
{
|
|
for (int32 X = 0; X < VertsX; ++X)
|
|
{
|
|
FGizmoSelectData Data;
|
|
Data.Ratio = 1.f;
|
|
Data.HeightData = (float)HeightData[X + Y*VertsX] / 65535.f; //GetNormalizedHeight(HeightData[X + Y*VertsX]);
|
|
for (int32 i = 0; i < ImportLayerInfos.Num(); ++i)
|
|
{
|
|
Data.WeightDataMap.Add( ImportLayerInfos[i], LayerDataPointers[i][X + Y*VertsX] );
|
|
}
|
|
SelectedData.Add(FIntPoint(X, Y), Data);
|
|
}
|
|
}
|
|
|
|
SampleData(VertsX, VertsY);
|
|
|
|
for (auto It = ImportLayerInfos.CreateConstIterator(); It; ++It)
|
|
{
|
|
LayerInfos.Add(*It);
|
|
}
|
|
|
|
GWarn->EndSlowTask();
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::Export(int32 Index, TArray<FString>& Filenames)
|
|
{
|
|
//guard around case where landscape has no layer structs
|
|
if (Filenames.Num() == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool bExportOneTarget = (Filenames.Num() == 1);
|
|
|
|
if (TargetLandscapeInfo)
|
|
{
|
|
int32 MinX = MAX_int32, MinY = MAX_int32;
|
|
int32 MaxX = MIN_int32, MaxY = MIN_int32;
|
|
for (const TPair<FIntPoint, FGizmoSelectData>& SelectedDataPair : SelectedData)
|
|
{
|
|
const FIntPoint Key = SelectedDataPair.Key;
|
|
if (MinX > Key.X) MinX = Key.X;
|
|
if (MaxX < Key.X) MaxX = Key.X;
|
|
if (MinY > Key.Y) MinY = Key.Y;
|
|
if (MaxY < Key.Y) MaxY = Key.Y;
|
|
}
|
|
|
|
if (MinX != MAX_int32)
|
|
{
|
|
GWarn->BeginSlowTask( NSLOCTEXT("Landscape", "BeginExportingGizmoDataTask", "Exporting Gizmo Data"), true);
|
|
|
|
TArray<uint8> HeightData;
|
|
if (!bExportOneTarget || Index == -1)
|
|
{
|
|
HeightData.AddZeroed((1+MaxX-MinX)*(1+MaxY-MinY)*sizeof(uint16));
|
|
}
|
|
uint16* pHeightData = (uint16*)HeightData.GetData();
|
|
|
|
TArray<TArray<uint8> > WeightDatas;
|
|
for( int32 i=1;i<Filenames.Num();i++ )
|
|
{
|
|
TArray<uint8> WeightData;
|
|
if (!bExportOneTarget || Index == i-1)
|
|
{
|
|
WeightData.AddZeroed((1+MaxX-MinX)*(1+MaxY-MinY));
|
|
}
|
|
WeightDatas.Add(WeightData);
|
|
}
|
|
|
|
for (int32 Y = MinY; Y <= MaxY; ++Y)
|
|
{
|
|
for (int32 X = MinX; X <= MaxX; ++X)
|
|
{
|
|
const FGizmoSelectData* Data = SelectedData.Find(FIntPoint(X, Y));
|
|
if (Data)
|
|
{
|
|
int32 Idx = (X-MinX) + Y *(1+MaxX-MinX);
|
|
if (!bExportOneTarget || Index == -1)
|
|
{
|
|
pHeightData[Idx] = FMath::Clamp<uint16>(Data->HeightData * 65535.f, 0, 65535);
|
|
}
|
|
|
|
for( int32 i=1;i<Filenames.Num();i++ )
|
|
{
|
|
if (!bExportOneTarget || Index == i-1)
|
|
{
|
|
TArray<uint8>& WeightData = WeightDatas[i-1];
|
|
WeightData[Idx] = FMath::Clamp<uint8>(Data->WeightDataMap.FindRef(LayerInfos[i-1]), 0, 255);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bExportOneTarget || Index == -1)
|
|
{
|
|
FFileHelper::SaveArrayToFile(HeightData,*Filenames[0]);
|
|
}
|
|
|
|
for( int32 i=1;i<Filenames.Num();i++ )
|
|
{
|
|
if (!bExportOneTarget || Index == i-1)
|
|
{
|
|
FFileHelper::SaveArrayToFile(WeightDatas[i-1],*Filenames[bExportOneTarget ? 0 : i]);
|
|
}
|
|
}
|
|
|
|
GWarn->EndSlowTask();
|
|
}
|
|
else
|
|
{
|
|
FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "LandscapeGizmoExport_Warning", "Landscape Gizmo has no copyed data. You need to choose proper targets and copy it to Gizmo."));
|
|
}
|
|
}
|
|
}
|
|
|
|
void ALandscapeGizmoActiveActor::ExportToClipboard()
|
|
{
|
|
if (TargetLandscapeInfo && DataType != LGT_None)
|
|
{
|
|
//GWarn->BeginSlowTask( TEXT("Exporting Gizmo Data From Clipboard"), true);
|
|
|
|
FString ClipboardString(TEXT("GizmoData="));
|
|
|
|
ClipboardString += FString::Printf(TEXT(" Type=%d,TextureScaleX=%g,TextureScaleY=%g,SampleSizeX=%d,SampleSizeY=%d,CachedWidth=%g,CachedHeight=%g,CachedScaleXY=%g "),
|
|
(int32)DataType, TextureScale.X, TextureScale.Y, SampleSizeX, SampleSizeY, CachedWidth, CachedHeight, CachedScaleXY);
|
|
|
|
for (int32 Y = 0; Y < SampleSizeY; ++Y )
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX; ++X)
|
|
{
|
|
FVector& V = SampledHeight[X + Y * DataTexSize];
|
|
ClipboardString += FString::Printf(TEXT("%d %d %d "), (int32)V.X, (int32)V.Y, *(int32*)(&V.Z) );
|
|
}
|
|
}
|
|
|
|
ClipboardString += FString::Printf(TEXT("LayerInfos= "));
|
|
|
|
for (ULandscapeLayerInfoObject* LayerInfo : LayerInfos)
|
|
{
|
|
ClipboardString += FString::Printf(TEXT("%s "), *LayerInfo->GetPathName() );
|
|
}
|
|
|
|
ClipboardString += FString::Printf(TEXT("Region= "));
|
|
|
|
for (const TPair<FIntPoint, FGizmoSelectData>& SelectedDataPair : SelectedData)
|
|
{
|
|
const FIntPoint Key = SelectedDataPair.Key;
|
|
const FGizmoSelectData& Data = SelectedDataPair.Value;
|
|
ClipboardString += FString::Printf(TEXT("%d %d %d %d %d "), Key.X, Key.Y, *(int32*)(&Data.Ratio), *(int32*)(&Data.HeightData), Data.WeightDataMap.Num());
|
|
|
|
for (const TPair<ULandscapeLayerInfoObject*, float>& WeightDataPair : Data.WeightDataMap)
|
|
{
|
|
ClipboardString += FString::Printf(TEXT("%d %d "), LayerInfos.Find(WeightDataPair.Key), *(int32*)(&WeightDataPair.Value));
|
|
}
|
|
}
|
|
|
|
FPlatformMisc::ClipboardCopy(*ClipboardString);
|
|
|
|
//GWarn->EndSlowTask();
|
|
}
|
|
}
|
|
|
|
#define MAX_GIZMO_PROP_TEXT_LENGTH 1024*1024*8
|
|
|
|
void ALandscapeGizmoActiveActor::ImportFromClipboard()
|
|
{
|
|
FString ClipboardString;
|
|
FPlatformMisc::ClipboardPaste(ClipboardString);
|
|
const TCHAR* Str = *ClipboardString;
|
|
|
|
if(FParse::Command(&Str,TEXT("GizmoData=")))
|
|
{
|
|
int32 ClipBoardSize = ClipboardString.Len();
|
|
if (ClipBoardSize > MAX_GIZMO_PROP_TEXT_LENGTH)
|
|
{
|
|
if( EAppReturnType::Yes != FMessageDialog::Open( EAppMsgType::YesNo,
|
|
FText::Format(NSLOCTEXT("UnrealEd", "LandscapeGizmoImport_Warning", "Landscape Gizmo is about to import large amount data ({0}MB) from the clipboard, which will take some time. Do you want to proceed?"),
|
|
FText::AsNumber(ClipBoardSize >> 20) ) ) )
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
GWarn->BeginSlowTask( NSLOCTEXT("Landscape", "BeginImportingGizmoDataFromClipboardTask", "Importing Gizmo Data From Clipboard"), true);
|
|
|
|
FParse::Next(&Str);
|
|
|
|
|
|
int32 ReadNum = 0;
|
|
|
|
uint8 Type = 0;
|
|
ReadNum += FParse::Value(Str, TEXT("Type="), Type) ? 1 : 0;
|
|
DataType = (ELandscapeGizmoType)Type;
|
|
|
|
ReadNum += FParse::Value(Str, TEXT("TextureScaleX="), TextureScale.X) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("TextureScaleY="), TextureScale.Y) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("SampleSizeX="), SampleSizeX) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("SampleSizeY="), SampleSizeY) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("CachedWidth="), CachedWidth) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("CachedHeight="), CachedHeight) ? 1 : 0;
|
|
ReadNum += FParse::Value(Str, TEXT("CachedScaleXY="), CachedScaleXY) ? 1 : 0;
|
|
|
|
if (ReadNum > 0)
|
|
{
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
|
|
int32 SquaredDataTex = DataTexSize * DataTexSize;
|
|
if (SampledHeight.Num() != SquaredDataTex)
|
|
{
|
|
SampledHeight.Empty(SquaredDataTex);
|
|
SampledHeight.AddZeroed(SquaredDataTex);
|
|
}
|
|
|
|
// For Sample Height...
|
|
TCHAR* StopStr;
|
|
for (int32 Y = 0; Y < SampleSizeY; ++Y )
|
|
{
|
|
for (int32 X = 0; X < SampleSizeX; ++X)
|
|
{
|
|
FVector& V = SampledHeight[X + Y * DataTexSize];
|
|
V.X = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
V.Y = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
//V.Z = FCString::Atof(Str);
|
|
*((int32*)(&V.Z)) = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
}
|
|
}
|
|
|
|
CalcNormal();
|
|
|
|
TCHAR StrBuf[1024];
|
|
if(FParse::Command(&Str,TEXT("LayerInfos=")))
|
|
{
|
|
while( !FParse::Command(&Str,TEXT("Region=")) )
|
|
{
|
|
FParse::Next(&Str);
|
|
int32 i = 0;
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
StrBuf[i++] = *Str;
|
|
Str++;
|
|
}
|
|
StrBuf[i] = 0;
|
|
LayerInfos.Add( LoadObject<ULandscapeLayerInfoObject>(NULL, StrBuf) );
|
|
}
|
|
}
|
|
|
|
//if(FParse::Command(&Str,TEXT("Region=")))
|
|
{
|
|
while (*Str)
|
|
{
|
|
FParse::Next(&Str);
|
|
int32 X, Y, LayerNum;
|
|
FGizmoSelectData Data;
|
|
X = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
Y = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
*((int32*)(&Data.Ratio)) = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
*((int32*)(&Data.HeightData)) = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
LayerNum = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
for (int32 i = 0; i < LayerNum; ++i)
|
|
{
|
|
int32 LayerIndex = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
float Weight;
|
|
*((int32*)(&Weight)) = FCString::Strtoi(Str, &StopStr, 10);
|
|
while (!FChar::IsWhitespace(*Str))
|
|
{
|
|
Str++;
|
|
}
|
|
FParse::Next(&Str);
|
|
Data.WeightDataMap.Add(LayerInfos[LayerIndex], Weight);
|
|
}
|
|
SelectedData.Add(FIntPoint(X, Y), Data);
|
|
}
|
|
}
|
|
}
|
|
|
|
GWarn->EndSlowTask();
|
|
|
|
ReregisterAllComponents();
|
|
}
|
|
}
|
|
#endif //WITH_EDITOR
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
/** Returns SpriteComponent subobject **/
|
|
UBillboardComponent* ALandscapeGizmoActor::GetSpriteComponent() const { return SpriteComponent; }
|
|
#endif
|