├── .gitignore ├── .gitmodules ├── Config ├── DefaultEditor.ini ├── DefaultEditorPerProjectUserSettings.ini ├── DefaultEngine.ini ├── DefaultGame.ini └── DefaultInput.ini ├── Content ├── Geometry │ └── Meshes │ │ ├── 1M_Cube.uasset │ │ ├── 1M_Cube_Chamfer.uasset │ │ ├── CubeMaterial.uasset │ │ └── TemplateFloor.uasset ├── VehicleAdv │ ├── ArenaMesh │ │ ├── BumpWave.uasset │ │ ├── BumpWaveSmall.uasset │ │ ├── BumpWedge.uasset │ │ ├── CubeMaterial.uasset │ │ ├── LoopBig.uasset │ │ ├── LoopSmall.uasset │ │ ├── RampLarge.uasset │ │ ├── RampTwist.uasset │ │ ├── RoadSegment_01.uasset │ │ ├── StraightFull.uasset │ │ ├── StraightHalf.uasset │ │ ├── StraightQuarter.uasset │ │ ├── Turn_45.uasset │ │ ├── Turn_90.uasset │ │ ├── Turn_90Large.uasset │ │ ├── pole.uasset │ │ └── turn_22andhalf.uasset │ ├── Materials │ │ ├── Fixed_Template_Master.uasset │ │ ├── Landscape.uasset │ │ ├── MasterGrid.uasset │ │ ├── MasterSolidColor.uasset │ │ └── MaterialInstances │ │ │ ├── BlackGrid.uasset │ │ │ ├── LandscapeNoHole.uasset │ │ │ ├── RedGrid.uasset │ │ │ ├── SolidOrange.uasset │ │ │ ├── SolidRed.uasset │ │ │ └── Template_BaseBlue.uasset │ ├── PhysicsMaterials │ │ ├── NonSlippery.uasset │ │ └── Slippery.uasset │ ├── Sound │ │ ├── Engine_Loop_Cue.uasset │ │ ├── Engine_Speed_01_Loop.uasset │ │ ├── Engine_Speed_02_Loop.uasset │ │ ├── Engine_Speed_03_Loop.uasset │ │ ├── Engine_Speed_04_Loop.uasset │ │ ├── Engine_Speed_05_Loop.uasset │ │ ├── Engine_Speed_06_Loop.uasset │ │ └── Engine_att.uasset │ ├── Textures │ │ ├── VehicleJoystick_BackgroundL.uasset │ │ └── VehicleJoystick_BackgroundR.uasset │ └── Vehicle │ │ ├── LeftVirtualJoystickOnly.uasset │ │ ├── VehicleAnimationBlueprint.uasset │ │ ├── VehicleBodyCollision.uasset │ │ ├── VehiclePhysicsAsset.uasset │ │ ├── VehicleSkeleton.uasset │ │ ├── Vehicle_SkelMesh.uasset │ │ └── WheelData │ │ ├── Vehicle_BackTireConfig.uasset │ │ ├── Vehicle_BackTireType_TireConfig.uasset │ │ ├── Vehicle_FrontTireConfig.uasset │ │ └── Vehicle_FrontTireType_TireConfig.uasset └── VehicleAdvCPP │ └── Maps │ ├── LayerInfo │ ├── Desert_LayerInfo.uasset │ └── Track_LayerInfo.uasset │ └── VehicleAdvExampleMap.umap ├── Pavilion.uproject ├── Plugins └── PavilionPlugin │ ├── .gitignore │ ├── BuildThirdParty.sh │ ├── Content │ ├── ACR-01.uasset │ ├── BasicRobotPartMaterial.uasset │ └── f_x_stealth.uasset │ ├── PavilionPlugin.uplugin │ ├── Resources │ └── Icon128.png │ └── Source │ ├── PavilionPlugin │ ├── PavilionPlugin.Build.cs │ ├── Private │ │ ├── PavilionPlugin.cpp │ │ ├── RobotActor.cpp │ │ ├── RobotMeshComponent.cpp │ │ └── UnrealEventPort.cpp │ └── Public │ │ ├── PavilionPlugin.h │ │ ├── RobotActor.h │ │ ├── RobotMeshComponent.h │ │ └── UnrealEventPort.h │ └── ThirdParty │ ├── assimp │ └── assimp.Build.cs │ ├── capnproto │ └── capnproto.Build.cs │ ├── cros │ └── cros.Build.cs │ ├── ignition │ └── ignition.Build.cs │ └── sdformat │ ├── Private │ └── Placeholder.cpp │ └── sdformat.Build.cs ├── README.md └── Source ├── Pavilion.Target.cs ├── Pavilion ├── Pavilion.Build.cs ├── Pavilion.cpp ├── Pavilion.h ├── PavilionGameMode.cpp ├── PavilionGameMode.h ├── PavilionHud.cpp ├── PavilionHud.h ├── PavilionPawn.cpp ├── PavilionPawn.h ├── PavilionWheelFront.cpp ├── PavilionWheelFront.h ├── PavilionWheelRear.cpp └── PavilionWheelRear.h └── PavilionEditor.Target.cs /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | 22 | # Compiled Static libraries 23 | *.lai 24 | *.la 25 | *.a 26 | *.lib 27 | 28 | # Executables 29 | *.exe 30 | *.out 31 | *.app 32 | *.ipa 33 | 34 | # These project files can be generated by the engine 35 | *.xcodeproj 36 | *.xcworkspace 37 | *.sln 38 | *.suo 39 | *.opensdf 40 | *.sdf 41 | *.VC.db 42 | *.VC.opendb 43 | 44 | # Precompiled Assets 45 | SourceArt/**/*.png 46 | SourceArt/**/*.tga 47 | 48 | # Binary Files 49 | Binaries/* 50 | Plugins/*/Binaries/* 51 | 52 | # Builds 53 | Build/* 54 | 55 | # Whitelist PakBlacklist-.txt files 56 | !Build/*/ 57 | Build/*/** 58 | !Build/*/PakBlacklist*.txt 59 | 60 | # Don't ignore icon files in Build 61 | !Build/**/*.ico 62 | 63 | # Built data for maps 64 | *_BuiltData.uasset 65 | 66 | # Configuration files generated by the Editor 67 | Saved/* 68 | 69 | # Compiled source files for the engine to use 70 | Intermediate/* 71 | Plugins/*/Intermediate/* 72 | 73 | # Cache files for the editor to use 74 | DerivedDataCache/* 75 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Plugins/PavilionPlugin/ThirdParty/Source/sdformat"] 2 | path = Plugins/PavilionPlugin/ThirdParty/Source/sdformat 3 | url = https://github.com/ProfFan/sdformat.git 4 | branch = nortti 5 | [submodule "Plugins/PavilionPlugin/ThirdParty/Source/assimp"] 6 | path = Plugins/PavilionPlugin/ThirdParty/Source/assimp 7 | url = https://github.com/ProfFan/assimp.git 8 | branch = devel-nortti 9 | [submodule "Plugins/PavilionPlugin/ThirdParty/Source/capnproto"] 10 | path = Plugins/PavilionPlugin/ThirdParty/Source/capnproto 11 | url = https://github.com/capnproto/capnproto.git 12 | branch = release-0.7.0 13 | [submodule "Plugins/PavilionPlugin/ThirdParty/Source/cros"] 14 | path = Plugins/PavilionPlugin/ThirdParty/Source/cros 15 | url = https://github.com/ProfFan/cros.git 16 | branch = master 17 | [submodule "Plugins/RuntimeMeshComponent"] 18 | path = Plugins/RuntimeMeshComponent 19 | url = https://github.com/ProfFan/RuntimeMeshComponent.git 20 | branch = metal-bugfix 21 | -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- 1 | [UnrealEd.SimpleMap] 2 | SimpleMapName=/Game/VehicleAdv/Maps/VehicleAdvExampleMap 3 | 4 | [EditoronlyBP] 5 | bAllowClassAndBlueprintPinMatching=true 6 | bReplaceBlueprintWithClass= true 7 | bDontLoadBlueprintOutsideEditor= true 8 | bBlueprintIsNotBlueprintType= true 9 | [/Script/HardwareTargeting.HardwareTargetingSettings] 10 | TargetedHardwareClass=0 11 | DefaultGraphicsPerformance=0 12 | 13 | -------------------------------------------------------------------------------- /Config/DefaultEditorPerProjectUserSettings.ini: -------------------------------------------------------------------------------- 1 | [ContentBrowser] 2 | ContentBrowserTab1.SelectedPaths=/Game/VehicleAdv -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GameMapsSettings] 2 | EditorStartupMap=/Game/VehicleAdvCPP/Maps/VehicleAdvExampleMap 3 | LocalMapOptions= 4 | TransitionMap= 5 | bUseSplitscreen=True 6 | TwoPlayerSplitscreenLayout=Horizontal 7 | ThreePlayerSplitscreenLayout=FavorTop 8 | GameInstanceClass=/Script/Engine.GameInstance 9 | GameDefaultMap=/Game/VehicleAdvCPP/Maps/VehicleAdvExampleMap 10 | ServerDefaultMap=/Engine/Maps/Entry 11 | GlobalDefaultGameMode=/Script/Pavilion.PavilionGameMode 12 | GlobalDefaultServerGameMode=None 13 | 14 | [/Script/IOSRuntimeSettings.IOSRuntimeSettings] 15 | MinimumiOSVersion=IOS_9 16 | 17 | 18 | [/Script/Engine.Engine] 19 | +ActiveGameNameRedirects=(OldGameName="TP_VehicleAdv",NewGameName="/Script/Pavilion") 20 | +ActiveGameNameRedirects=(OldGameName="/Script/TP_VehicleAdv",NewGameName="/Script/Pavilion") 21 | +ActiveClassRedirects=(OldClassName="TP_VehicleAdvWheelRear",NewClassName="PavilionWheelRear") 22 | +ActiveClassRedirects=(OldClassName="TP_VehicleAdvWheelFront",NewClassName="PavilionWheelFront") 23 | +ActiveClassRedirects=(OldClassName="TP_VehicleAdvPawn",NewClassName="PavilionPawn") 24 | +ActiveClassRedirects=(OldClassName="TP_VehicleAdvHud",NewClassName="PavilionHud") 25 | +ActiveClassRedirects=(OldClassName="TP_VehicleAdvGameMode",NewClassName="PavilionGameMode") 26 | 27 | [/Script/HardwareTargeting.HardwareTargetingSettings] 28 | TargetedHardwareClass=Desktop 29 | AppliedTargetedHardwareClass=Desktop 30 | DefaultGraphicsPerformance=Maximum 31 | AppliedDefaultGraphicsPerformance=Maximum 32 | 33 | [/Script/Engine.PhysicsSettings] 34 | DefaultGravityZ=-980.000000 35 | DefaultTerminalVelocity=4000.000000 36 | DefaultFluidFriction=0.300000 37 | SimulateScratchMemorySize=262144 38 | RagdollAggregateThreshold=4 39 | TriangleMeshTriangleMinAreaThreshold=5.000000 40 | bEnableAsyncScene=False 41 | bEnableShapeSharing=False 42 | bEnablePCM=True 43 | bEnableStabilization=False 44 | bWarnMissingLocks=True 45 | bEnable2DPhysics=False 46 | LockedAxis=Invalid 47 | DefaultDegreesOfFreedom=Full3D 48 | BounceThresholdVelocity=200.000000 49 | FrictionCombineMode=Average 50 | RestitutionCombineMode=Average 51 | MaxAngularVelocity=3600.000000 52 | MaxDepenetrationVelocity=0.000000 53 | ContactOffsetMultiplier=0.020000 54 | MinContactOffset=2.000000 55 | MaxContactOffset=8.000000 56 | bSimulateSkeletalMeshOnDedicatedServer=True 57 | DefaultShapeComplexity=CTF_UseSimpleAndComplex 58 | bDefaultHasComplexCollision=True 59 | bSuppressFaceRemapTable=False 60 | bSupportUVFromHitResults=False 61 | bDisableActiveActors=False 62 | bDisableCCD=False 63 | bEnableEnhancedDeterminism=False 64 | MaxPhysicsDeltaTime=0.033333 65 | bSubstepping=True 66 | bSubsteppingAsync=False 67 | MaxSubstepDeltaTime=0.005000 68 | MaxSubsteps=12 69 | SyncSceneSmoothingFactor=0.000000 70 | AsyncSceneSmoothingFactor=0.990000 71 | InitialAverageFrameRate=0.016667 72 | PhysXTreeRebuildRate=10 73 | 74 | [/Script/Engine.RendererSettings] 75 | r.BasePassOutputsVelocity=True 76 | -------------------------------------------------------------------------------- /Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=90B0FBEE814E57D3950D038B91C7340D 3 | ProjectName=Vehicle Game Template 4 | -------------------------------------------------------------------------------- /Config/DefaultInput.ini: -------------------------------------------------------------------------------- 1 | [/Script/Engine.InputSettings] 2 | +AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 3 | +AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 4 | +AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 5 | +AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 6 | +AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) 7 | +AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) 8 | bUseMouseForTouch=False 9 | +ActionMappings=(ActionName="Handbrake",Key=SpaceBar,bShift=False,bCtrl=False,bAlt=False,bCmd=False) 10 | +ActionMappings=(ActionName="Handbrake",Key=Gamepad_LeftShoulder,bShift=False,bCtrl=False,bAlt=False,bCmd=False) 11 | +ActionMappings=(ActionName="SwitchCamera",Key=Tab,bShift=False,bCtrl=False,bAlt=False,bCmd=False) 12 | +ActionMappings=(ActionName="ResetVR",Key=R,bShift=False,bCtrl=True,bAlt=False,bCmd=False) 13 | +ActionMappings=(ActionName="ResetVR",Key=MotionController_Left_Grip1,bShift=False,bCtrl=False,bAlt=False,bCmd=False) 14 | +ActionMappings=(ActionName="SwitchCamera",Key=Gamepad_Special_Left,bShift=False,bCtrl=False,bAlt=False,bCmd=False) 15 | +AxisMappings=(AxisName="MoveForward",Key=W,Scale=1.000000) 16 | +AxisMappings=(AxisName="MoveForward",Key=S,Scale=-1.000000) 17 | +AxisMappings=(AxisName="MoveForward",Key=Up,Scale=1.000000) 18 | +AxisMappings=(AxisName="MoveForward",Key=Down,Scale=-1.000000) 19 | +AxisMappings=(AxisName="MoveForward",Key=Gamepad_FaceButton_Bottom,Scale=1.000000) 20 | +AxisMappings=(AxisName="MoveRight",Key=A,Scale=-1.000000) 21 | +AxisMappings=(AxisName="MoveRight",Key=D,Scale=1.000000) 22 | +AxisMappings=(AxisName="MoveRight",Key=Left,Scale=-1.000000) 23 | +AxisMappings=(AxisName="MoveRight",Key=Right,Scale=1.000000) 24 | +AxisMappings=(AxisName="MoveRight",Key=Gamepad_LeftX,Scale=1.000000) 25 | +AxisMappings=(AxisName="LookUp",Key=MouseY,Scale=1.000000) 26 | +AxisMappings=(AxisName="LookRight",Key=MouseX,Scale=1.000000) 27 | +AxisMappings=(AxisName="MoveForward",Key=Gamepad_RightTriggerAxis,Scale=1.000000) 28 | +AxisMappings=(AxisName="MoveForward",Key=Gamepad_LeftTriggerAxis,Scale=-1.000000) 29 | +AxisMappings=(AxisName="LookUp",Key=Gamepad_RightY,Scale=-1.000000) 30 | +AxisMappings=(AxisName="LookRight",Key=Gamepad_RightX,Scale=1.000000) 31 | +AxisMappings=(AxisName="MoveForward",Key=Gamepad_LeftY,Scale=1.000000) 32 | +AxisMappings=(AxisName="MoveForward",Key=GenericUSBController_Axis2,Scale=-2.000000) 33 | +AxisMappings=(AxisName="MoveForward",Key=GenericUSBController_Axis3,Scale=1.000000) 34 | +AxisMappings=(AxisName="MoveRight",Key=GenericUSBController_Axis1,Scale=3.000000) 35 | DefaultTouchInterface=/Game/VehicleAdv/Vehicle/LeftVirtualJoystickOnly.LeftVirtualJoystickOnly 36 | ConsoleKey=None 37 | +ConsoleKeys=Tilde 38 | 39 | [/Script/RawInput.RawInputSettings] 40 | +DeviceConfigurations=(VendorID="0x046D",ProductID="0xC262",AxisProperties=((bEnabled=False),(Key=GenericUSBController_Axis1,Offset=-0.500000),(bEnabled=False),(Key=GenericUSBController_Axis2,bInverted=True,Offset=1.000000),(Key=GenericUSBController_Axis3,bInverted=True,Offset=1.000000)),ButtonProperties=((Key=GenericUSBController_Button1),(Key=GenericUSBController_Button2),(Key=GenericUSBController_Button3),(Key=GenericUSBController_Button4),(Key=GenericUSBController_Button5),(Key=GenericUSBController_Button6),(Key=GenericUSBController_Button7),(Key=GenericUSBController_Button8),(Key=GenericUSBController_Button9),(Key=GenericUSBController_Button10),(Key=GenericUSBController_Button11),(Key=GenericUSBController_Button12))) 41 | 42 | 43 | -------------------------------------------------------------------------------- /Content/Geometry/Meshes/1M_Cube.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/Geometry/Meshes/1M_Cube.uasset -------------------------------------------------------------------------------- /Content/Geometry/Meshes/1M_Cube_Chamfer.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/Geometry/Meshes/1M_Cube_Chamfer.uasset -------------------------------------------------------------------------------- /Content/Geometry/Meshes/CubeMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/Geometry/Meshes/CubeMaterial.uasset -------------------------------------------------------------------------------- /Content/Geometry/Meshes/TemplateFloor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/Geometry/Meshes/TemplateFloor.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/BumpWave.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/BumpWave.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/BumpWaveSmall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/BumpWaveSmall.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/BumpWedge.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/BumpWedge.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/CubeMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/CubeMaterial.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/LoopBig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/LoopBig.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/LoopSmall.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/LoopSmall.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/RampLarge.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/RampLarge.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/RampTwist.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/RampTwist.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/RoadSegment_01.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/RoadSegment_01.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/StraightFull.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/StraightFull.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/StraightHalf.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/StraightHalf.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/StraightQuarter.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/StraightQuarter.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/Turn_45.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/Turn_45.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/Turn_90.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/Turn_90.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/Turn_90Large.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/Turn_90Large.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/pole.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/pole.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/ArenaMesh/turn_22andhalf.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/ArenaMesh/turn_22andhalf.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/Fixed_Template_Master.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/Fixed_Template_Master.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/Landscape.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/Landscape.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MasterGrid.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MasterGrid.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MasterSolidColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MasterSolidColor.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/BlackGrid.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/BlackGrid.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/LandscapeNoHole.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/LandscapeNoHole.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/RedGrid.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/RedGrid.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/SolidOrange.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/SolidOrange.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/SolidRed.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/SolidRed.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Materials/MaterialInstances/Template_BaseBlue.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Materials/MaterialInstances/Template_BaseBlue.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/PhysicsMaterials/NonSlippery.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/PhysicsMaterials/NonSlippery.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/PhysicsMaterials/Slippery.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/PhysicsMaterials/Slippery.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Loop_Cue.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Loop_Cue.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_01_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_01_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_02_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_02_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_03_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_03_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_04_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_04_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_05_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_05_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_Speed_06_Loop.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_Speed_06_Loop.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Sound/Engine_att.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Sound/Engine_att.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Textures/VehicleJoystick_BackgroundL.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Textures/VehicleJoystick_BackgroundL.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Textures/VehicleJoystick_BackgroundR.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Textures/VehicleJoystick_BackgroundR.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/LeftVirtualJoystickOnly.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/LeftVirtualJoystickOnly.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/VehicleAnimationBlueprint.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/VehicleAnimationBlueprint.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/VehicleBodyCollision.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/VehicleBodyCollision.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/VehiclePhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/VehiclePhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/VehicleSkeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/VehicleSkeleton.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/Vehicle_SkelMesh.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/Vehicle_SkelMesh.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/WheelData/Vehicle_BackTireConfig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/WheelData/Vehicle_BackTireConfig.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/WheelData/Vehicle_BackTireType_TireConfig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/WheelData/Vehicle_BackTireType_TireConfig.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/WheelData/Vehicle_FrontTireConfig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/WheelData/Vehicle_FrontTireConfig.uasset -------------------------------------------------------------------------------- /Content/VehicleAdv/Vehicle/WheelData/Vehicle_FrontTireType_TireConfig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdv/Vehicle/WheelData/Vehicle_FrontTireType_TireConfig.uasset -------------------------------------------------------------------------------- /Content/VehicleAdvCPP/Maps/LayerInfo/Desert_LayerInfo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdvCPP/Maps/LayerInfo/Desert_LayerInfo.uasset -------------------------------------------------------------------------------- /Content/VehicleAdvCPP/Maps/LayerInfo/Track_LayerInfo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdvCPP/Maps/LayerInfo/Track_LayerInfo.uasset -------------------------------------------------------------------------------- /Content/VehicleAdvCPP/Maps/VehicleAdvExampleMap.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Content/VehicleAdvCPP/Maps/VehicleAdvExampleMap.umap -------------------------------------------------------------------------------- /Pavilion.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "{00045E7C-08D6-7ECB-6C5B-072670A6A2AD}", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "Pavilion", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default" 11 | } 12 | ], 13 | "Plugins": [ 14 | { 15 | "Name": "PhysXVehicles", 16 | "Enabled": true 17 | }, 18 | { 19 | "Name": "RawInput", 20 | "Enabled": true 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | ThirdParty/Build 2 | ThirdParty/Release 3 | Source/ThirdParty/*/Public/* -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/BuildThirdParty.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! [[ -e "./ThirdParty/Release" ]]; then 4 | echo "Please run this script from the plugin folder!" 5 | exit 1 6 | fi 7 | 8 | abort() 9 | { 10 | echo >&2 ' 11 | *************** 12 | *** ERROR *** 13 | *************** 14 | ' 15 | echo "Exiting..." >&2 16 | exit 1 17 | } 18 | 19 | trap 'abort' ERR 20 | 21 | set -e 22 | 23 | TOPDIR=`pwd` 24 | TP_DIR=$TOPDIR/ThirdParty 25 | TP_REL_DIR=$TOPDIR/ThirdParty/Release 26 | 27 | UE_TP_DIR=$TOPDIR/Source/ThirdParty 28 | 29 | echo "Updating dependencies" 30 | 31 | git submodule update --init 32 | 33 | echo "Building dependencies" 34 | 35 | mkdir -p "$TP_DIR/Build" 36 | mkdir -p "$TP_DIR/Release" 37 | 38 | #------------- 39 | # Cap'n Proto 40 | #------------- 41 | 42 | ( 43 | cd "$TP_DIR/Build" 44 | mkdir -p capnproto 45 | cd capnproto 46 | cmake $TP_DIR/Source/capnproto -DCMAKE_CXX_FLAGS="-O3 -fno-rtti -fno-exceptions" -DCMAKE_INSTALL_PREFIX="$TP_REL_DIR/capnproto" -DBUILD_TESTING=0 47 | make -j install 48 | ) 49 | 50 | #------------- 51 | # cROS 52 | #------------- 53 | 54 | ( 55 | cd "$TP_DIR/Build" 56 | mkdir -p cros 57 | cd cros 58 | cmake $TP_DIR/Source/cros -DCMAKE_CXX_FLAGS="-O3 -fno-rtti -fno-exceptions" -DCMAKE_INSTALL_PREFIX="$TP_REL_DIR/cros" -DBUILD_TESTING=0 59 | make -j install 60 | ) 61 | 62 | #------------- 63 | # assimp 64 | #------------- 65 | 66 | ( 67 | cd "$TP_DIR/Build" 68 | mkdir -p assimp 69 | cd assimp 70 | cmake $TP_DIR/Source/assimp -DCMAKE_C_FLAGS="-fno-rtti" -DCMAKE_CXX_FLAGS="-O3 -fno-rtti" -DCMAKE_INSTALL_PREFIX="$TP_REL_DIR/assimp" -DASSIMP_BUILD_COLLADA_IMPORTER=ON -DASSIMP_BUILD_DAE_IMPORTER=ON -DASSIMP_BUILD_FBX_IMPORTER=ON -DASSIMP_BUILD_STL_IMPORTER=ON -DASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT=FALSE -DASSIMP_BUILD_IFC_IMPORTER=OFF -DASSIMP_BUILD_ASSIMP_TOOLS=OFF -DASSIMP_BUILD_TESTS=OFF -DASSIMP_BUILD_ZLIB=ON -DCMAKE_BUILD_TYPE=Release 71 | make -j install 72 | ) 73 | 74 | #------------- 75 | # ignition-math 76 | #------------- 77 | 78 | ( 79 | cd "$TP_DIR/Source" 80 | if [! -d "ignition-math" ]; then 81 | curl https://bitbucket.org/ignitionrobotics/ign-math/get/ignition-math4_4.0.0.tar.bz2 -o ignition-math4_4.0.0.tar.bz2 82 | tar -xjf ignition-math4_4.0.0.tar.bz2 83 | mv ignitionrobotics-ign-math-054f8a99081f ignition-math 84 | fi 85 | 86 | cd "$TP_DIR/Build" 87 | mkdir -p ignition-math 88 | cd ignition-math 89 | cmake $TP_DIR/Source/ignition-math -DCMAKE_C_FLAGS="-fno-rtti" -DCMAKE_CXX_FLAGS="-O3 -fno-rtti" -DCMAKE_INSTALL_PREFIX="$TP_REL_DIR/ignition-math" -DCMAKE_BUILD_TYPE=Release 90 | make -j install 91 | if [[ "$OSTYPE" == "darwin"* ]]; then 92 | install_name_tool -add_rpath "@loader_path/../../ThirdParty/Release/ignition-math/lib" "$TP_REL_DIR/ignition-math/lib/libignition-math4.4.dylib" 93 | fi 94 | ) 95 | 96 | #------------- 97 | # sdformat 98 | #------------- 99 | 100 | ( 101 | cd "$TP_DIR/Build" 102 | mkdir -p sdformat 103 | cd sdformat 104 | cmake $TP_DIR/Source/sdformat -DCMAKE_C_FLAGS_ALL="-fno-rtti -fno-exceptions" -DCMAKE_CXX_FLAGS="-O3 -fno-rtti -fno-exceptions" -DCMAKE_INSTALL_PREFIX="$TP_REL_DIR/sdformat" -DCMAKE_BUILD_TYPE=Release 105 | make -j install 106 | if [[ "$OSTYPE" == "darwin"* ]]; then 107 | install_name_tool -add_rpath "$TP_REL_DIR/ignition-math/lib" "$TP_REL_DIR/sdformat/lib/libsdformat.dylib" 108 | install_name_tool -id "@rpath/libsdformat.6.dylib" "$TP_REL_DIR/sdformat/lib/libsdformat.dylib" 109 | fi 110 | ) 111 | 112 | #---------------------- 113 | # Finalize UBT Modules 114 | #---------------------- 115 | 116 | if [[ "$OSTYPE" == "darwin"* ]]; then 117 | DEPTH_ARG="-depth" 118 | else 119 | DEPTH_ARG="-maxdepth" 120 | fi 121 | 122 | ( 123 | cd $TP_REL_DIR/capnproto/include 124 | mkdir -p $UE_TP_DIR/capnproto/Public 125 | for i in $(find . $DEPTH_ARG 1); do 126 | cp -Rf $i/. $UE_TP_DIR/capnproto/Public/$i 127 | done 128 | ) 129 | 130 | ( 131 | cd $TP_REL_DIR/cros/include 132 | mkdir -p $UE_TP_DIR/cros/Public 133 | for i in $(find . $DEPTH_ARG 1); do 134 | cp -Rf $i/. $UE_TP_DIR/cros/Public/$i 135 | done 136 | ) 137 | 138 | ( 139 | cd $TP_REL_DIR/assimp/include 140 | mkdir -p $UE_TP_DIR/assimp/Public 141 | for i in $(find . $DEPTH_ARG 1); do 142 | cp -Rf $i/. $UE_TP_DIR/assimp/Public/$i 143 | done 144 | ) 145 | 146 | ( 147 | cd $TP_REL_DIR/sdformat/include/sdformat-6.0 148 | mkdir -p $UE_TP_DIR/sdformat/Public 149 | for i in $(find . $DEPTH_ARG 1); do 150 | cp -Rf $i/. $UE_TP_DIR/sdformat/Public/$i 151 | done 152 | ) 153 | 154 | ( 155 | if [[ "$OSTYPE" == "darwin"* ]]; then 156 | BOOST_DIR="/usr/local/opt/boost/include/boost" 157 | else 158 | BOOST_DIR="/usr/include/boost" 159 | fi 160 | 161 | cd $BOOST_DIR 162 | 163 | mkdir -p $UE_TP_DIR/sdformat/Public/boost/type_traits 164 | cp -Rf ./type_traits/. $UE_TP_DIR/sdformat/Public/boost/type_traits 165 | cp -f ./any.hpp $UE_TP_DIR/sdformat/Public/boost/ 166 | cp -f ./variant.hpp $UE_TP_DIR/sdformat/Public/boost/ 167 | cp -f ./version.hpp $UE_TP_DIR/sdformat/Public/boost/ 168 | cp -f ./config.hpp $UE_TP_DIR/sdformat/Public/boost/ 169 | cp -f ./throw_exception.hpp $UE_TP_DIR/sdformat/Public/boost/ 170 | cp -f ./blank_fwd.hpp $UE_TP_DIR/sdformat/Public/boost/ 171 | cp -f ./static_assert.hpp $UE_TP_DIR/sdformat/Public/boost/ 172 | cp -f ./limits.hpp $UE_TP_DIR/sdformat/Public/boost/ 173 | cp -f ./current_function.hpp $UE_TP_DIR/sdformat/Public/boost/ 174 | cp -f ./assert.hpp $UE_TP_DIR/sdformat/Public/boost/ 175 | cp -f ./cstdint.hpp $UE_TP_DIR/sdformat/Public/boost/ 176 | cp -f ./call_traits.hpp $UE_TP_DIR/sdformat/Public/boost/ 177 | cp -Rf ./utility/. $UE_TP_DIR/sdformat/Public/boost/utility 178 | cp -Rf ./exception/. $UE_TP_DIR/sdformat/Public/boost/exception 179 | cp -Rf ./variant/. $UE_TP_DIR/sdformat/Public/boost/variant 180 | cp -Rf ./preprocessor/. $UE_TP_DIR/sdformat/Public/boost/preprocessor 181 | cp -Rf ./integer/. $UE_TP_DIR/sdformat/Public/boost/integer 182 | cp -f ./integer_fwd.hpp $UE_TP_DIR/sdformat/Public/boost/ 183 | cp -f ./aligned_storage.hpp $UE_TP_DIR/sdformat/Public/boost/ 184 | cp -f ./checked_delete.hpp $UE_TP_DIR/sdformat/Public/boost/ 185 | cp -f ./blank.hpp $UE_TP_DIR/sdformat/Public/boost/ 186 | cp -Rf ./core/. $UE_TP_DIR/sdformat/Public/boost/core 187 | cp -Rf ./mpl/. $UE_TP_DIR/sdformat/Public/boost/mpl 188 | cp -Rf ./detail/. $UE_TP_DIR/sdformat/Public/boost/detail 189 | cp -Rf ./move/. $UE_TP_DIR/sdformat/Public/boost/move 190 | cp -Rf ./functional/. $UE_TP_DIR/sdformat/Public/boost/functional 191 | cp -Rf ./type_index/. $UE_TP_DIR/sdformat/Public/boost/type_index 192 | cp -Rf ./math/. $UE_TP_DIR/sdformat/Public/boost/math 193 | cp -f ./type_index.hpp $UE_TP_DIR/sdformat/Public/boost/ 194 | cp -Rf ./container_hash/. $UE_TP_DIR/sdformat/Public/boost/container_hash 195 | mkdir -p $UE_TP_DIR/sdformat/Public/boost/config 196 | cp -Rf ./config/. $UE_TP_DIR/sdformat/Public/boost/config 197 | ) 198 | 199 | ( 200 | cd $TP_REL_DIR/ignition-math/include/ignition/math4 201 | mkdir -p $UE_TP_DIR/ignition/Public 202 | for i in $(find . $DEPTH_ARG 1); do 203 | cp -Rf $i/. $UE_TP_DIR/ignition/Public/$i 204 | done 205 | ) -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Content/ACR-01.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Plugins/PavilionPlugin/Content/ACR-01.uasset -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Content/BasicRobotPartMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Plugins/PavilionPlugin/Content/BasicRobotPartMaterial.uasset -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Content/f_x_stealth.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Plugins/PavilionPlugin/Content/f_x_stealth.uasset -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/PavilionPlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "PavilionPlugin", 6 | "Description": "The Pavilion Robot Simulator", 7 | "Category": "Other", 8 | "CreatedBy": "Fan Jiang", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "Installed": false, 16 | "Modules": [ 17 | { 18 | "Name": "PavilionPlugin", 19 | "Type": "Developer", 20 | "LoadingPhase": "Default" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoreRC/Pavilion/c11563f35375046e56f34d2ca413a45f7978eeed/Plugins/PavilionPlugin/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/PavilionPlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class PavilionPlugin : ModuleRules 6 | { 7 | public PavilionPlugin(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | bEnableExceptions = true; 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | "capnproto", 30 | "cros", 31 | "assimp", 32 | "ignition", 33 | "sdformat", 34 | "RuntimeMeshComponent", 35 | // ... add other public dependencies that you statically link with here ... 36 | } 37 | ); 38 | 39 | 40 | PrivateDependencyModuleNames.AddRange( 41 | new string[] 42 | { 43 | "CoreUObject", 44 | "Engine", 45 | "Slate", 46 | "SlateCore", 47 | "capnproto", 48 | "cros", 49 | "assimp", 50 | "ignition", 51 | "sdformat", 52 | "VHACD", 53 | "RuntimeMeshComponent", 54 | "ImageWrapper", "RenderCore", 55 | // ... add private dependencies that you statically link with here ... 56 | } 57 | ); 58 | 59 | 60 | DynamicallyLoadedModuleNames.AddRange( 61 | new string[] 62 | { 63 | // ... add any modules that your module loads dynamically here ... 64 | } 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Private/PavilionPlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionPlugin.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FPavilionPluginModule" 6 | 7 | void FPavilionPluginModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FPavilionPluginModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FPavilionPluginModule, PavilionPlugin) -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Private/RobotActor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Fan Jiang All Rights Reserved. This source file is subject to multiple Chinese and International Copyright Laws and Patents. Unauthorized Redistribution is strictly prohibited. 2 | 3 | #include "RobotActor.h" 4 | 5 | class LStream : public std::stringbuf{ 6 | protected: 7 | int sync() { 8 | UE_LOG(LogTemp, Log, TEXT("%s"), *FString(str().c_str())); 9 | str(""); 10 | return std::stringbuf::sync(); 11 | } 12 | }; 13 | 14 | FRotator ARobotActor::URDFRotationToUnreal(ignition::math::Quaterniond quat) { 15 | return FRotator(FQuat(quat.X(),quat.Y(),quat.Z(),quat.W())); 16 | } 17 | 18 | FVector ARobotActor::URDFPositionToUnreal(ignition::math::Vector3d vec) { 19 | return FVector(vec.X() * 100.0, vec.Y() * -100.0, vec.Z() * 100.0); 20 | } 21 | 22 | FString ARobotActor::GetRealPathFromURI(std::string uri){ 23 | // NOTE: URI looks like model://pr2/meshes/shoulder_v0/shoulder_pan.dae 24 | if(uri.find("model://") != 0){ 25 | return FString(); 26 | } 27 | 28 | return FPaths::ConvertRelativePathToFull(FPaths::ConvertRelativePathToFull(FPaths::GetPath(URDFPath),".."), uri.substr(8,uri.length()-8).c_str()); 29 | } 30 | 31 | // Sets default values 32 | ARobotActor::ARobotActor(const FObjectInitializer& ObjectInitializer ): Super(ObjectInitializer) 33 | { 34 | 35 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 36 | PrimaryActorTick.bCanEverTick = true; 37 | 38 | RootComponent = CreateDefaultSubobject("UnrealRoot"); 39 | 40 | UE_LOG(LogTemp, Warning, TEXT("ARobotActor ctor(ObjectInitializer)")); 41 | 42 | LoadModelOnCreation(ObjectInitializer); 43 | } 44 | 45 | void ARobotActor::LoadModelOnCreation(const FObjectInitializer& ObjectInitializer){ 46 | LStream Stream; 47 | std::cout.rdbuf(&Stream); 48 | 49 | std::string filename(TCHAR_TO_UTF8(*URDFPath)); 50 | 51 | sdf::SDFPtr sdfElement(new sdf::SDF()); 52 | sdf::init(sdfElement); 53 | if (!sdf::readFile(filename, sdfElement)) 54 | { 55 | UE_LOG(LogTemp, Warning, TEXT("%s is not a valid SDF file!"), *URDFPath); 56 | return; 57 | } 58 | 59 | // start parsing model 60 | const sdf::ElementPtr rootElement = sdfElement->Root(); 61 | if (!rootElement->HasElement("model")) 62 | { 63 | UE_LOG(LogTemp, Warning, TEXT("%s is not a valid model SDF file!"), *URDFPath); 64 | return; 65 | } 66 | 67 | // Now we have a good model 68 | // Let's begin the initialization 69 | 70 | const sdf::ElementPtr modelElement = rootElement->GetElement("model"); 71 | const std::string modelName = modelElement->Get("name"); 72 | std::cout << "Found " << modelName << " model!" << std::endl; 73 | 74 | // parse model links 75 | sdf::ElementPtr linkElement = modelElement->GetElement("link"); 76 | int linkCount = 0; 77 | while (linkElement) 78 | { 79 | const std::string linkName = linkElement->Get("name"); 80 | std::cout << "Found " << linkName << " link in " 81 | << modelName << " model!" << std::endl; 82 | 83 | auto linkPose = linkElement->Get("pose"); 84 | std::cout << "Pose: " << linkPose << std::endl; 85 | 86 | { 87 | auto rotString = URDFRotationToUnreal(linkPose.Rot()).ToString(); 88 | auto locString = URDFPositionToUnreal(linkPose.Pos()).ToString(); 89 | std::cout << "Unreal Pose:" << TCHAR_TO_UTF8(*rotString) << "," << TCHAR_TO_UTF8(*locString) << std::endl; 90 | } 91 | 92 | 93 | auto linkObject = CreateDefaultSubobject(FName(linkName.c_str())); 94 | // static ConstructorHelpers::FObjectFinder< UStaticMesh > meshFinder( TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere") ); 95 | // linkObject->SetStaticMesh( meshFinder.Object ); 96 | 97 | 98 | // Replace the Unreal RootComponent 99 | if(linkCount != 0) { 100 | linkObject->SetupAttachment(RootComponent); 101 | } else { 102 | RootComponent = linkObject; 103 | } 104 | 105 | linkObject->InitSphereRadius(0.1f); 106 | linkObject->SetMobility(EComponentMobility::Movable); 107 | linkObject->SetSimulatePhysics(true); 108 | linkObject->SetVisibility(false, false); 109 | 110 | if(linkCount != 0) { 111 | //linkObject->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); 112 | linkObject->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 113 | linkObject->SetCollisionResponseToAllChannels(ECR_Block); 114 | } else { 115 | linkObject->InitSphereRadius(.1f); 116 | linkObject->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 117 | linkObject->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block); 118 | } 119 | 120 | linkObject->RelativeLocation = URDFPositionToUnreal(linkPose.Pos()); 121 | linkObject->RelativeRotation = URDFRotationToUnreal(linkPose.Rot()); 122 | 123 | { 124 | sdf::ElementPtr visualElement = linkElement->GetElement("visual"); 125 | while (visualElement) { 126 | 127 | std::cout << "Got visual " << visualElement->GetAttribute("name")->GetAsString() << " on it" 128 | << std::endl; 129 | 130 | if (visualElement->HasElement("geometry")) { 131 | sdf::ElementPtr geometryElement = visualElement->GetElement("geometry"); 132 | if (geometryElement->HasElement("mesh")) { 133 | auto uri = geometryElement->GetElement("mesh")->Get("uri"); 134 | std::cout << "Got mesh " << uri << " on it" << std::endl; 135 | 136 | { 137 | auto geometryName = FName(visualElement->GetAttribute("name")->GetAsString().c_str()); 138 | auto geometryObject = CreateDefaultSubobject(geometryName); 139 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 140 | 141 | if(!attachSuccess){ 142 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 143 | } 144 | // geometryObject->SetupAttachment(linkObject); 145 | geometryObject->ModelPath = GetRealPathFromURI(uri); 146 | if (geometryElement->GetElement("mesh")->HasElement("scale")) { 147 | auto meshScale = geometryElement->GetElement("mesh")->Get("scale"); 148 | geometryObject->ModelScaleTransform *= FVector(meshScale.X(), meshScale.Y(), meshScale.Z()); 149 | } 150 | geometryObject->CollisionPath = FString(); 151 | if (visualElement->HasElement("pose")) { 152 | geometryObject->RelativeLocation = URDFPositionToUnreal(visualElement->Get("pose").Pos()); 153 | geometryObject->RelativeRotation = URDFRotationToUnreal(visualElement->Get("pose").Rot()); 154 | } 155 | } 156 | } 157 | if (geometryElement->HasElement("cylinder")) { 158 | auto cyl = geometryElement->GetElement("cylinder"); 159 | std::cout << "Got cylinder rad:" << cyl->Get("radius") << " , len:" 160 | << cyl->Get("length") << " on it" << std::endl; 161 | { 162 | auto geometryName = FName(visualElement->GetAttribute("name")->GetAsString().c_str()); 163 | auto geometryObject = CreateDefaultSubobject(geometryName); 164 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 165 | 166 | if(!attachSuccess){ 167 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 168 | } 169 | geometryObject->MeshType = ERobotMeshType::Cylinder; 170 | geometryObject->CylinderSize = FVector2D(cyl->Get("radius"),cyl->Get("length")); 171 | 172 | if (visualElement->HasElement("pose")) { 173 | geometryObject->RelativeLocation = URDFPositionToUnreal(visualElement->Get("pose").Pos()); 174 | geometryObject->RelativeRotation = URDFRotationToUnreal(visualElement->Get("pose").Rot()); 175 | } 176 | } 177 | } 178 | if (geometryElement->HasElement("box")) { 179 | auto box = geometryElement->GetElement("box"); 180 | std::cout << "Got box:" << box->Get("size") << " on it" << std::endl; 181 | { 182 | auto geometryName = FName(visualElement->GetAttribute("name")->GetAsString().c_str()); 183 | auto geometryObject = CreateDefaultSubobject(geometryName); 184 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 185 | 186 | if(!attachSuccess){ 187 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 188 | } 189 | geometryObject->MeshType = ERobotMeshType::Box; 190 | auto boxSize = box->Get("size"); 191 | geometryObject->BoxSize = FVector(boxSize.X(), boxSize.Y(), boxSize.Z()); 192 | 193 | if (visualElement->HasElement("pose")) { 194 | geometryObject->RelativeLocation = URDFPositionToUnreal(visualElement->Get("pose").Pos()); 195 | geometryObject->RelativeRotation = URDFRotationToUnreal(visualElement->Get("pose").Rot()); 196 | } 197 | } 198 | } 199 | } 200 | visualElement = visualElement->GetNextElement("visual"); 201 | } 202 | } 203 | 204 | { 205 | sdf::ElementPtr collisionElement = linkElement->GetElement("collision"); 206 | while (collisionElement) { 207 | 208 | std::cout << "Got collision " << collisionElement->GetAttribute("name")->GetAsString() << " on it" 209 | << std::endl; 210 | if (collisionElement->HasElement("geometry")) { 211 | sdf::ElementPtr geometryElement = collisionElement->GetElement("geometry"); 212 | 213 | if (geometryElement->HasElement("mesh")) { 214 | auto uri = geometryElement->GetElement("mesh")->Get("uri"); 215 | std::cout << "Got collision mesh " << uri << " on it" << std::endl; 216 | 217 | { 218 | auto geometryName = FName(collisionElement->GetAttribute("name")->GetAsString().c_str()); 219 | auto geometryObject = CreateDefaultSubobject(geometryName); 220 | geometryObject->CollisionPath = GetRealPathFromURI(uri); 221 | if (geometryElement->GetElement("mesh")->HasElement("scale")) { 222 | auto meshScale = geometryElement->GetElement("mesh")->Get("scale"); 223 | geometryObject->CollisionScaleTransform *= FVector(meshScale.X(), meshScale.Y(), meshScale.Z()); 224 | } 225 | geometryObject->ModelPath = FString(); 226 | // geometryObject->SetupAttachment(linkObject); 227 | 228 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 229 | geometryObject->WeldTo(linkObject); 230 | 231 | UE_LOG(LogTemp, Warning, TEXT("Attaching collision to %s"), *(linkObject->GetName())); 232 | 233 | if(!attachSuccess){ 234 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 235 | } 236 | 237 | if (collisionElement->HasElement("pose")) { 238 | geometryObject->RelativeLocation = URDFPositionToUnreal(collisionElement->Get("pose").Pos()); 239 | geometryObject->RelativeRotation = URDFRotationToUnreal(collisionElement->Get("pose").Rot()); 240 | } 241 | 242 | { 243 | //set up the constraint instance with all the desired values 244 | FConstraintInstance ConstraintInstance; 245 | 246 | //set values here, see functions I am sharing with you below 247 | ConstraintInstance.SetAngularSwing1Motion(EAngularConstraintMotion::ACM_Locked); 248 | ConstraintInstance.SetAngularSwing2Motion(EAngularConstraintMotion::ACM_Locked); 249 | ConstraintInstance.SetAngularTwistMotion(EAngularConstraintMotion::ACM_Locked); 250 | 251 | ConstraintInstance.SetLinearXMotion(ELinearConstraintMotion::LCM_Locked); 252 | ConstraintInstance.SetLinearYMotion(ELinearConstraintMotion::LCM_Locked); 253 | ConstraintInstance.SetLinearZMotion(ELinearConstraintMotion::LCM_Locked); 254 | 255 | ConstraintInstance.SetLinearBreakable(false, 0); 256 | ConstraintInstance.SetAngularBreakable(false, 0); 257 | 258 | ConstraintInstance.ProfileInstance.LinearLimit.bSoftConstraint = 0; 259 | ConstraintInstance.ProfileInstance.TwistLimit.bSoftConstraint = 0; 260 | ConstraintInstance.SetDisableCollision(true); 261 | 262 | auto constraintName = FName((collisionElement->GetAttribute("name")->GetAsString() + "_" + linkName).c_str()); 263 | 264 | UPhysicsConstraintComponent* ConstraintComp = CreateDefaultSubobject(constraintName); 265 | if(!ConstraintComp) 266 | { 267 | //UE_LOG constraint UObject could not be created! 268 | return; 269 | } 270 | 271 | ConstraintComp->ConstraintInstance = ConstraintInstance; 272 | 273 | //Attach to Root! 274 | ConstraintComp->SetupAttachment(RootComponent); 275 | 276 | //~~~ Init Constraint ~~~ 277 | ConstraintComp->SetConstrainedComponents(linkObject, NAME_None, geometryObject, NAME_None); 278 | 279 | } 280 | 281 | } 282 | } 283 | if (geometryElement->HasElement("cylinder")) { 284 | auto cyl = geometryElement->GetElement("cylinder"); 285 | std::cout << "Got cylinder rad:" << cyl->Get("radius") << " , len:" 286 | << cyl->Get("length") << " on it" << std::endl; 287 | { 288 | auto geometryName = FName(collisionElement->GetAttribute("name")->GetAsString().c_str()); 289 | auto geometryObject = CreateDefaultSubobject(geometryName); 290 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 291 | 292 | if(!attachSuccess){ 293 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 294 | } 295 | geometryObject->MeshType = ERobotMeshType::Cylinder; 296 | geometryObject->CylinderSize = FVector2D(cyl->Get("radius"),cyl->Get("length")); 297 | 298 | if (collisionElement->HasElement("pose")) { 299 | geometryObject->RelativeLocation = URDFPositionToUnreal(collisionElement->Get("pose").Pos()); 300 | geometryObject->RelativeRotation = URDFRotationToUnreal(collisionElement->Get("pose").Rot()); 301 | } 302 | } 303 | } 304 | if (geometryElement->HasElement("box")) { 305 | auto box = geometryElement->GetElement("box"); 306 | std::cout << "Got box:" << box->Get("size") << " on it" << std::endl; 307 | { 308 | auto geometryName = FName(collisionElement->GetAttribute("name")->GetAsString().c_str()); 309 | auto geometryObject = CreateDefaultSubobject(geometryName); 310 | bool attachSuccess = geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 311 | 312 | if(!attachSuccess){ 313 | UE_LOG(LogTemp, Error, TEXT("ATTACHMENT FAILED for %s"), *(geometryName.ToString())); 314 | } 315 | 316 | geometryObject->MeshType = ERobotMeshType::Box; 317 | auto boxSize = box->Get("size"); 318 | geometryObject->BoxSize = FVector(boxSize.X(), boxSize.Y(), boxSize.Z()); 319 | 320 | if (collisionElement->HasElement("pose")) { 321 | geometryObject->RelativeLocation = URDFPositionToUnreal(collisionElement->Get("pose").Pos()); 322 | geometryObject->RelativeRotation = URDFRotationToUnreal(collisionElement->Get("pose").Rot()); 323 | } 324 | } 325 | } 326 | } 327 | collisionElement = collisionElement->GetNextElement("collision"); 328 | } 329 | } 330 | 331 | linkCount++; 332 | linkElement = linkElement->GetNextElement("link"); 333 | } 334 | 335 | // parse model joints 336 | sdf::ElementPtr jointElement = modelElement->GetElement("joint"); 337 | while (jointElement) 338 | { 339 | const std::string jointName = jointElement->Get("name"); 340 | std::cout << "Found " << jointName << " joint in " 341 | << modelName << " model!" << std::endl; 342 | 343 | const sdf::ElementPtr parentElement = jointElement->GetElement("parent"); 344 | const std::string parentLinkName = parentElement->Get(); 345 | 346 | const sdf::ElementPtr childElement = jointElement->GetElement("child"); 347 | const std::string childLinkName = childElement->Get(); 348 | 349 | std::cout << "Joint " << jointName << " connects " << parentLinkName 350 | << " link to " << childLinkName << " link" << std::endl; 351 | 352 | jointElement = jointElement->GetNextElement("joint"); 353 | } 354 | } 355 | 356 | void ARobotActor::LoadModel(const FTransform &Transform){ 357 | LStream Stream; 358 | std::cout.rdbuf(&Stream); 359 | 360 | std::string filename(TCHAR_TO_UTF8(*URDFPath)); 361 | 362 | sdf::SDFPtr sdfElement(new sdf::SDF()); 363 | sdf::init(sdfElement); 364 | if (!sdf::readFile(filename, sdfElement)) 365 | { 366 | UE_LOG(LogTemp, Warning, TEXT("%s is not a valid SDF file!"), *URDFPath); 367 | return; 368 | } 369 | 370 | // start parsing model 371 | const sdf::ElementPtr rootElement = sdfElement->Root(); 372 | if (!rootElement->HasElement("model")) 373 | { 374 | UE_LOG(LogTemp, Warning, TEXT("%s is not a valid model SDF file!"), *URDFPath); 375 | return; 376 | } 377 | 378 | // Now we have a good model 379 | // Let's begin the initialization 380 | 381 | const sdf::ElementPtr modelElement = rootElement->GetElement("model"); 382 | const std::string modelName = modelElement->Get("name"); 383 | std::cout << "Found " << modelName << " model!" << std::endl; 384 | 385 | // parse model links 386 | sdf::ElementPtr linkElement = modelElement->GetElement("link"); 387 | int linkCount = 0; 388 | while (linkElement) 389 | { 390 | const std::string linkName = linkElement->Get("name"); 391 | std::cout << "Found " << linkName << " link in " 392 | << modelName << " model!" << std::endl; 393 | 394 | auto linkPose = linkElement->Get("pose"); 395 | std::cout << "Pose: " << linkPose << std::endl; 396 | 397 | { 398 | auto rotString = URDFRotationToUnreal(linkPose.Rot()).ToString(); 399 | auto locString = URDFPositionToUnreal(linkPose.Pos()).ToString(); 400 | std::cout << "Unreal Pose:" << TCHAR_TO_UTF8(*rotString) << "," << TCHAR_TO_UTF8(*locString) << std::endl; 401 | } 402 | 403 | 404 | auto linkObject = NewObject(this, FName(linkName.c_str())); 405 | linkObject->RegisterComponent(); 406 | 407 | if(linkCount != 0) { 408 | linkObject->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform); 409 | } else { 410 | if(RootComponent){ 411 | RootComponent->UnregisterComponent(); 412 | } 413 | RootComponent = linkObject; 414 | RootComponent->SetWorldTransform(Transform); 415 | } 416 | 417 | linkObject->InitSphereRadius(1.f); 418 | linkObject->SetMobility(EComponentMobility::Movable); 419 | linkObject->SetSimulatePhysics(true); 420 | linkObject->SetVisibility(false, false); 421 | 422 | if(linkCount != 0) { 423 | linkObject->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 424 | linkObject->SetCollisionResponseToAllChannels(ECR_Ignore); 425 | linkObject->SetRelativeLocation(URDFPositionToUnreal(linkPose.Pos())); 426 | linkObject->SetRelativeRotation(URDFRotationToUnreal(linkPose.Rot())); 427 | } else { 428 | linkObject->InitSphereRadius(.1f); 429 | linkObject->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 430 | linkObject->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); 431 | } 432 | 433 | // End link process 434 | 435 | sdf::ElementPtr visualElement = linkElement->GetElement("visual"); 436 | while(visualElement){ 437 | 438 | std::cout << "Got visual " << visualElement->GetAttribute("name")->GetAsString() << " on it" << std::endl; 439 | 440 | if(visualElement->HasElement("geometry")){ 441 | sdf::ElementPtr geometryElement = visualElement->GetElement("geometry"); 442 | if(geometryElement->HasElement("mesh")){ 443 | auto uri = geometryElement->GetElement("mesh")->Get("uri"); 444 | std::cout << "Got mesh " << uri << " on it" << std::endl; 445 | 446 | { 447 | auto geometryName = FName(visualElement->GetAttribute("name")->GetAsString().c_str()); 448 | auto geometryObject = NewObject(this, geometryName); 449 | geometryObject->ModelPath = GetRealPathFromURI(uri); 450 | if(geometryElement->GetElement("mesh")->HasElement("scale")){ 451 | auto meshScale = geometryElement->GetElement("mesh")->Get("scale"); 452 | geometryObject->ModelScaleTransform *= FVector(meshScale.X(), meshScale.Y(), meshScale.Z()); 453 | } 454 | geometryObject->CollisionPath = FString(); 455 | geometryObject->AttachToComponent(linkObject, FAttachmentTransformRules::KeepRelativeTransform); 456 | if(visualElement->HasElement("pose")){ 457 | geometryObject->SetRelativeLocation(URDFPositionToUnreal(visualElement->Get("pose").Pos())); 458 | geometryObject->SetRelativeRotation(URDFRotationToUnreal(visualElement->Get("pose").Rot())); 459 | } 460 | geometryObject->RegisterComponent(); 461 | } 462 | } 463 | if(geometryElement->HasElement("cylinder")){ 464 | auto cyl = geometryElement->GetElement("cylinder"); 465 | std::cout << "Got cylinder rad:" << cyl->Get("radius") << " , len:" << cyl->Get("length") << " on it" << std::endl; 466 | } 467 | if(geometryElement->HasElement("box")){ 468 | auto box = geometryElement->GetElement("box"); 469 | std::cout << "Got box:" << box->Get("size") << " on it" << std::endl; 470 | } 471 | } 472 | visualElement = visualElement->GetNextElement("visual"); 473 | } 474 | 475 | 476 | sdf::ElementPtr collisionElement = linkElement->GetElement("collision"); 477 | while(collisionElement){ 478 | 479 | std::cout << "Got collision " << collisionElement->GetAttribute("name")->GetAsString() << " on it" << std::endl; 480 | if(collisionElement->HasElement("geometry")) { 481 | sdf::ElementPtr geometryElement = collisionElement->GetElement("geometry"); 482 | 483 | if (geometryElement->HasElement("mesh")) { 484 | auto uri = geometryElement->GetElement("mesh")->Get("uri"); 485 | std::cout << "Got mesh " << uri << " on it" << std::endl; 486 | 487 | { 488 | auto geometryName = FName(collisionElement->GetAttribute("name")->GetAsString().c_str()); 489 | auto geometryObject = NewObject(this, geometryName); 490 | geometryObject->CollisionPath = GetRealPathFromURI(uri); 491 | if (geometryElement->GetElement("mesh")->HasElement("scale")) { 492 | auto meshScale = geometryElement->GetElement("mesh")->Get("scale"); 493 | geometryObject->CollisionScaleTransform *= FVector(meshScale.X(), meshScale.Y(), meshScale.Z()); 494 | } 495 | geometryObject->ModelPath = FString(); 496 | 497 | auto rule = FAttachmentTransformRules(EAttachmentRule::KeepRelative, EAttachmentRule::KeepRelative, EAttachmentRule::KeepWorld, false); 498 | 499 | geometryObject->AttachToComponent(linkObject, rule); 500 | geometryObject->RegisterComponent(); 501 | 502 | if (collisionElement->HasElement("pose")) { 503 | geometryObject->SetRelativeLocation(URDFPositionToUnreal(collisionElement->Get("pose").Pos())); 504 | geometryObject->SetRelativeRotation(URDFRotationToUnreal(collisionElement->Get("pose").Rot())); 505 | } 506 | 507 | { 508 | //set up the constraint instance with all the desired values 509 | FConstraintInstance ConstraintInstance; 510 | 511 | //set values here, see functions I am sharing with you below 512 | ConstraintInstance.SetAngularSwing1Motion(EAngularConstraintMotion::ACM_Locked); 513 | ConstraintInstance.SetAngularSwing2Motion(EAngularConstraintMotion::ACM_Locked); 514 | ConstraintInstance.SetAngularTwistMotion(EAngularConstraintMotion::ACM_Locked); 515 | 516 | ConstraintInstance.SetLinearXMotion(ELinearConstraintMotion::LCM_Locked); 517 | ConstraintInstance.SetLinearYMotion(ELinearConstraintMotion::LCM_Locked); 518 | ConstraintInstance.SetLinearZMotion(ELinearConstraintMotion::LCM_Locked); 519 | 520 | ConstraintInstance.SetLinearBreakable(false, 0); 521 | ConstraintInstance.SetAngularBreakable(false, 0); 522 | 523 | ConstraintInstance.ProfileInstance.LinearLimit.bSoftConstraint = 0; 524 | ConstraintInstance.ProfileInstance.TwistLimit.bSoftConstraint = 0; 525 | ConstraintInstance.SetDisableCollision(true); 526 | 527 | auto constraintName = FName((collisionElement->GetAttribute("name")->GetAsString() + "_" + linkName).c_str()); 528 | 529 | UPhysicsConstraintComponent* ConstraintComp = NewObject(this, constraintName); 530 | if(!ConstraintComp) 531 | { 532 | //UE_LOG constraint UObject could not be created! 533 | return; 534 | } 535 | 536 | ConstraintComp->ConstraintInstance = ConstraintInstance; 537 | 538 | //Attach to Root! 539 | ConstraintComp->SetupAttachment(linkObject); 540 | 541 | //~~~ Init Constraint ~~~ 542 | ConstraintComp->SetConstrainedComponents(linkObject, NAME_None, geometryObject, NAME_None); 543 | 544 | } 545 | } 546 | } 547 | if (geometryElement->HasElement("cylinder")) { 548 | auto cyl = geometryElement->GetElement("cylinder"); 549 | std::cout << "Got cylinder rad:" << cyl->Get("radius") << " , len:" 550 | << cyl->Get("length") << " on it" << std::endl; 551 | } 552 | if (geometryElement->HasElement("box")) { 553 | auto box = geometryElement->GetElement("box"); 554 | std::cout << "Got box:" << box->Get("size") << " on it" << std::endl; 555 | } 556 | } 557 | collisionElement = collisionElement->GetNextElement("collision"); 558 | } 559 | 560 | linkCount++; 561 | linkElement = linkElement->GetNextElement("link"); 562 | } 563 | 564 | // parse model joints 565 | sdf::ElementPtr jointElement = modelElement->GetElement("joint"); 566 | while (jointElement) 567 | { 568 | const std::string jointName = jointElement->Get("name"); 569 | std::cout << "Found " << jointName << " joint in " 570 | << modelName << " model!" << std::endl; 571 | 572 | const sdf::ElementPtr parentElement = jointElement->GetElement("parent"); 573 | const std::string parentLinkName = parentElement->Get(); 574 | 575 | const sdf::ElementPtr childElement = jointElement->GetElement("child"); 576 | const std::string childLinkName = childElement->Get(); 577 | 578 | std::cout << "Joint " << jointName << " connects " << parentLinkName 579 | << " link to " << childLinkName << " link" << std::endl; 580 | 581 | jointElement = jointElement->GetNextElement("joint"); 582 | } 583 | } 584 | 585 | void ARobotActor::PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent){ 586 | 587 | Super::PostEditChangeProperty(PropertyChangedEvent); 588 | 589 | if(PropertyChangedEvent.GetPropertyName() == FName("URDFPath")){ 590 | { 591 | TInlineComponentArray PrimComponents; 592 | this->GetComponents(PrimComponents); 593 | for(auto comp: PrimComponents){ 594 | // if(comp==RootComponent) continue; 595 | 596 | comp->UnregisterComponent(); 597 | comp->ConditionalBeginDestroy(); 598 | } 599 | } 600 | LoadModel(GetTransform()); 601 | } 602 | } 603 | 604 | void ARobotActor::OnConstruction(const FTransform &Transform){ 605 | 606 | Super::OnConstruction(Transform); 607 | 608 | // { 609 | // TInlineComponentArray PrimComponents; 610 | // this->GetComponents(PrimComponents); 611 | // for(auto comp: PrimComponents){ 612 | // // if(comp==RootComponent) continue; 613 | // 614 | // comp->UnregisterComponent(); 615 | // comp->ConditionalBeginDestroy(); 616 | // } 617 | // } 618 | // 619 | // LoadModel(Transform); 620 | } 621 | 622 | // Called when the game starts or when spawned 623 | void ARobotActor::BeginPlay() 624 | { 625 | Super::BeginPlay(); 626 | 627 | } 628 | 629 | // Called every frame 630 | void ARobotActor::Tick(float DeltaTime) 631 | { 632 | Super::Tick(DeltaTime); 633 | 634 | } 635 | 636 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Private/RobotMeshComponent.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Fan Jiang All Rights Reserved. This source file is subject to multiple Chinese and International Copyright Laws and Patents. Unauthorized Redistribution is strictly prohibited. 2 | 3 | #include "RobotMeshComponent.h" 4 | #include "RuntimeMeshShapeGenerator.h" 5 | #include "IImageWrapper.h" 6 | #include "IImageWrapperModule.h" 7 | #include "RenderUtils.h" 8 | 9 | #include "ThirdParty/VHACD/public/VHACD.h" 10 | 11 | URobotMeshComponent::URobotMeshComponent(const FObjectInitializer& ObjectInitializer) 12 | : Super(ObjectInitializer) 13 | { 14 | //GetBodySetup()->bGenerateMirroredCollision = true; 15 | static ConstructorHelpers::FObjectFinder FoundMaterial(TEXT("/PavilionPlugin/BasicRobotPartMaterial.BasicRobotPartMaterial")); 16 | if (FoundMaterial.Succeeded()) 17 | { 18 | BaseMaterial = FoundMaterial.Object; 19 | } 20 | 21 | this->SetMobility(EComponentMobility::Movable); 22 | 23 | } 24 | 25 | void URobotMeshComponent::InitializeComponent() 26 | { 27 | Super::InitializeComponent(); 28 | // your code 29 | 30 | } 31 | 32 | void URobotMeshComponent::OnRegister() 33 | { 34 | // your code 35 | Super::OnRegister(); 36 | 37 | Super::SetCollisionUseComplexAsSimple(false); 38 | 39 | clear(); 40 | int32 secCount; 41 | FString errCode; 42 | 43 | Super::ClearAllMeshSections(); 44 | Super::ClearAllMeshCollisionSections(); 45 | 46 | switch (MeshType) { 47 | case ERobotMeshType::Mesh: 48 | if(ComponentType != ERobotComponentType::Collision && !ModelPath.IsEmpty() && openMesh(ModelPath, secCount, errCode)){ 49 | Super::CreateMeshSection(0, _vertices[0], _indices[0], _normals[0], _uvs[0], _vertexColors[0], _tangents[0], false, EUpdateFrequency::Average, ESectionUpdateFlags::None, false, false); 50 | 51 | //Super::ContainsPhysicsTriMeshData(true); 52 | 53 | if(_materials.Num() > 0){ 54 | UE_LOG(LogTemp, Warning, TEXT("Material Count %d"), _materials.Num()); 55 | Super::SetMaterial(0, _materials[0]); 56 | } 57 | } else { 58 | FRuntimeMeshDataPtr Data = GetOrCreateRuntimeMesh()->GetRuntimeMeshData(); 59 | Data->EnterSerializedMode(); 60 | 61 | Data->CreateMeshSection(0, false, false, 1, false, false, EUpdateFrequency::Average); 62 | 63 | auto Section = Data->BeginSectionUpdate(0); 64 | 65 | URuntimeMeshShapeGenerator::CreateBoxMesh(FVector(0.1,0.1,0.1), *Section.Get()); 66 | 67 | Section->Commit(); 68 | UE_LOG(LogTemp, Warning, TEXT("Cannot read visual model: %s"), *errCode); 69 | } 70 | 71 | this->SetSimulatePhysics(true); 72 | this->SetCollisionObjectType(ECC_PhysicsBody); 73 | this->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 74 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block); 75 | 76 | if(ComponentType != ERobotComponentType::Visual && openCollisionMesh(CollisionPath, errCode)){ 77 | 78 | auto name = this->GetName(); 79 | UE_LOG(LogTemp, Warning, TEXT("Collision loaded: %s"), *name); 80 | } else { 81 | this->SetSimulatePhysics(false); 82 | this->SetCollisionObjectType(ECC_PhysicsBody); 83 | this->SetCollisionEnabled(ECollisionEnabled::NoCollision); 84 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); 85 | } 86 | break; 87 | case ERobotMeshType::Cylinder: 88 | if(ComponentType != ERobotComponentType::Collision) { 89 | FRuntimeMeshDataPtr Data = GetOrCreateRuntimeMesh()->GetRuntimeMeshData(); 90 | Data->EnterSerializedMode(); 91 | 92 | Data->CreateMeshSection(0, false, false, 1, false, false, EUpdateFrequency::Average); 93 | 94 | auto Section = Data->BeginSectionUpdate(0); 95 | 96 | URuntimeMeshShapeGenerator::CreateBoxMesh(FVector(100 * CylinderSize.X, 100 * CylinderSize.X, 100 * CylinderSize.Y), *Section.Get()); 97 | 98 | Section->Commit(); 99 | UE_LOG(LogTemp, Warning, TEXT("Cannot read visual model: %s"), *errCode); 100 | } 101 | 102 | this->SetSimulatePhysics(true); 103 | this->SetCollisionObjectType(ECC_PhysicsBody); 104 | this->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 105 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block); 106 | 107 | if(ComponentType != ERobotComponentType::Visual){ 108 | 109 | auto name = this->GetName(); 110 | UE_LOG(LogTemp, Warning, TEXT("Collision loaded: %s"), *name); 111 | } else { 112 | this->SetSimulatePhysics(false); 113 | this->SetCollisionObjectType(ECC_PhysicsBody); 114 | this->SetCollisionEnabled(ECollisionEnabled::NoCollision); 115 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); 116 | } 117 | break; 118 | case ERobotMeshType::Box: 119 | if(ComponentType != ERobotComponentType::Collision) { 120 | FRuntimeMeshDataPtr Data = GetOrCreateRuntimeMesh()->GetRuntimeMeshData(); 121 | Data->EnterSerializedMode(); 122 | 123 | Data->CreateMeshSection(0, false, false, 1, false, false, EUpdateFrequency::Average); 124 | 125 | auto Section = Data->BeginSectionUpdate(0); 126 | 127 | URuntimeMeshShapeGenerator::CreateBoxMesh(BoxSize, *Section.Get()); 128 | 129 | Section->Commit(); 130 | UE_LOG(LogTemp, Warning, TEXT("Cannot read visual model: %s"), *errCode); 131 | } 132 | 133 | this->SetSimulatePhysics(true); 134 | this->SetCollisionObjectType(ECC_PhysicsBody); 135 | this->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics); 136 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block); 137 | 138 | if(ComponentType != ERobotComponentType::Visual){ 139 | 140 | auto name = this->GetName(); 141 | UE_LOG(LogTemp, Warning, TEXT("Collision loaded: %s"), *name); 142 | } else { 143 | this->SetSimulatePhysics(false); 144 | this->SetCollisionObjectType(ECC_PhysicsBody); 145 | this->SetCollisionEnabled(ECollisionEnabled::NoCollision); 146 | this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore); 147 | } 148 | break; 149 | } 150 | 151 | } 152 | 153 | void URobotMeshComponent::PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent){ 154 | 155 | 156 | Super::PostEditChangeProperty(PropertyChangedEvent); 157 | } 158 | 159 | bool URobotMeshComponent::openCollisionMesh(FString path, FString& ErrorCode){ 160 | Assimp::Importer importer; 161 | std::string filename(TCHAR_TO_UTF8(*path)); 162 | const aiScene* scene; 163 | 164 | if(MakeLeftHanded) { 165 | scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_MaxQuality | 166 | aiProcess_FlipUVs | 167 | aiProcess_MakeLeftHanded); 168 | } else { 169 | scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_MaxQuality | 170 | aiProcess_FlipUVs); 171 | } 172 | 173 | if (!scene) 174 | { 175 | ErrorCode = importer.GetErrorString(); 176 | UE_LOG(LogTemp, Warning, TEXT("Collision Load Error: %s"), *ErrorCode); 177 | return false; 178 | } 179 | 180 | Super::ClearAllConvexCollisionSections(); 181 | 182 | FTransform transV; 183 | transV.SetScale3D(CollisionScaleTransform); 184 | 185 | UE_LOG(LogTemp, Warning, TEXT("Number of Collision Meshes: %u"), scene->mNumMeshes); 186 | for (uint32 i = 0; i < scene->mNumMeshes; i++) { 187 | aiMesh* mesh = scene->mMeshes[i]; 188 | TArray vertices; 189 | TArray indices; 190 | 191 | vertices.Empty(); 192 | vertices.Reserve(mesh->mNumVertices); 193 | 194 | indices.Empty(); 195 | indices.Reserve(mesh->mNumFaces); 196 | 197 | for (unsigned int j = 0; j < mesh->mNumVertices; j++) { 198 | FVector vertex, normal; 199 | // process vertex positions, normals and UVs 200 | vertex.X = mesh->mVertices[j].x; 201 | vertex.Y = mesh->mVertices[j].y; 202 | vertex.Z = mesh->mVertices[j].z; 203 | 204 | if(ApplyTransformation){ 205 | vertex = transV.TransformVector(vertex); 206 | } 207 | vertices.Add(vertex); 208 | } 209 | 210 | for (uint32 j = 0; j < mesh->mNumFaces; j++) { 211 | aiFace face = mesh->mFaces[j]; 212 | if(ApplyTransformation){ 213 | indices.Add(face.mIndices[0]); 214 | indices.Add(face.mIndices[1]); 215 | indices.Add(face.mIndices[2]); 216 | } else { 217 | indices.Add(face.mIndices[2]); 218 | indices.Add(face.mIndices[1]); 219 | indices.Add(face.mIndices[0]); 220 | } 221 | } 222 | // Super::AddConvexCollisionSection(vertices); 223 | DecomposeMeshToHulls(_convexCollision, vertices, indices, 0.001, 64); 224 | UE_LOG(LogTemp, Warning, TEXT("Decomposing Mesh to Hulls: %d to %d"), mesh->mNumVertices, _convexCollision.Num()); 225 | for(auto c: _convexCollision){ 226 | UE_LOG(LogTemp, Warning, TEXT("Hull Added: %d"), c.Num()); 227 | //Super::CreateMeshSection(2, _vertices[0], _indices[0], _normals[0], _uvs[0], _vertexColors[0], _tangents[0], false, EUpdateFrequency::Average, ESectionUpdateFlags::None, false, false); 228 | Super::AddConvexCollisionSection(c); 229 | } 230 | // for(auto c: _convexCollision){ 231 | // UE_LOG(LogTemp, Warning, TEXT("Hull Added")); 232 | // 233 | // Super::AddConvexCollisionSection(c); 234 | // FRuntimeMeshDataPtr Data = GetOrCreateRuntimeMesh()->GetRuntimeMeshData(); 235 | // Data->EnterSerializedMode(); 236 | // Data->SetCollisionConvexMeshes(_convexCollision); 237 | // //Data->CreateMeshSection(0, false, false, 1, false, true, EUpdateFrequency::Average); 238 | // 239 | // //auto Section = Data->BeginSectionUpdate(0); 240 | // 241 | // URuntimeMeshShapeGenerator::CreateBoxMesh(FVector(0.1,0.1,0.1), *Section.Get()); 242 | // 243 | // Section->Commit(); 244 | // } 245 | } 246 | UE_LOG(LogTemp, Warning, TEXT("CollisionMesh Loaded")); 247 | return true; 248 | } 249 | 250 | void URobotMeshComponent::OnCreatePhysicsState() { 251 | // FRuntimeMeshDataPtr Data = GetOrCreateRuntimeMesh()->GetRuntimeMeshData(); 252 | // Data->SetCollisionConvexMeshes(_convexCollision); 253 | 254 | Super::OnCreatePhysicsState(); 255 | } 256 | 257 | bool URobotMeshComponent::openMesh(FString path, int32& SectionCount, FString& ErrorCode) 258 | { 259 | Assimp::Importer importer; 260 | std::string filename(TCHAR_TO_UTF8(*path)); 261 | const aiScene* scene; 262 | 263 | if(MakeLeftHanded) { 264 | scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_MaxQuality | 265 | aiProcess_FlipUVs | 266 | aiProcess_MakeLeftHanded | 267 | aiProcess_GlobalScale); 268 | } else { 269 | scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_MaxQuality | 270 | aiProcess_FlipUVs | aiProcess_GlobalScale 271 | ); 272 | } 273 | 274 | if (!scene) 275 | { 276 | ErrorCode = importer.GetErrorString(); 277 | return false; 278 | } 279 | _meshCurrentlyProcessed = 0; 280 | 281 | // if(ApplyTransformation){ 282 | // UE_LOG(LogTemp, Warning, TEXT("Trying to apply transform")); 283 | // aiMatrix4x4 scalingMat; 284 | // aiVector3D scale(10.f, -10.f, 10.f); // Assimp -> Unreal 285 | // aiMatrix4x4::Scaling(scale, scalingMat); 286 | // if(scene->mRootNode->mChildren[0]){ 287 | // aiMatrix4x4 rootMat(scene->mRootNode->mChildren[0]->mTransformation); 288 | // 289 | // scene->mRootNode->mChildren[0]->mTransformation = scalingMat * rootMat; 290 | // } 291 | // } 292 | 293 | processNode(scene->mRootNode, scene); 294 | SectionCount = _meshCurrentlyProcessed; 295 | 296 | if (scene->HasMaterials()) 297 | { 298 | for (unsigned int ii = 0; ii < scene->mNumMaterials; ++ii) 299 | { 300 | // if(_materials.Num() < scene->mNumMaterials){ 301 | // _materials.AddZeroed(); 302 | // _textures.AddZeroed(); 303 | // } 304 | 305 | processMaterial(scene->mMaterials[ii], scene); 306 | } 307 | } 308 | 309 | return true; 310 | } 311 | 312 | bool URobotMeshComponent::getSection(int32 index, TArray& Vertices, TArray& Faces, TArray& Normals, TArray& UV, TArray& Tangents) 313 | { 314 | if (index>=_meshCurrentlyProcessed) 315 | { 316 | return false; 317 | } 318 | Vertices = _vertices[index]; 319 | Faces = _indices[index]; 320 | Normals = _normals[index]; 321 | UV = _uvs[index]; 322 | Tangents = _tangents[index]; 323 | return true; 324 | } 325 | 326 | void URobotMeshComponent::clear() 327 | { 328 | _vertices.Empty(); 329 | _indices.Empty(); 330 | _normals.Empty(); 331 | _uvs.Empty(); 332 | _tangents.Empty(); 333 | _vertexColors.Empty(); 334 | _materials.Empty(); 335 | _textures.Empty(); 336 | _tnormals.Empty(); 337 | _meshCurrentlyProcessed = 0; 338 | } 339 | 340 | void URobotMeshComponent::processNode(aiNode* node, const aiScene* scene) 341 | { 342 | for (uint32 i = 0; i < node->mNumMeshes; i++) { 343 | aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; 344 | processMesh(mesh, node, scene); 345 | ++_meshCurrentlyProcessed; 346 | UE_LOG(LogTemp, Warning, TEXT("processNode got mesh %d on %d"), i, node->mName.length); 347 | } 348 | uint32 nodes = node->mNumMeshes; 349 | // do the same for all of its children 350 | for (uint32 i = 0; i < node->mNumChildren; i++) { 351 | processNode(node->mChildren[i], scene); 352 | } 353 | } 354 | 355 | void URobotMeshComponent::processMesh(aiMesh* mesh, const aiNode* node, const aiScene* scene) 356 | { 357 | 358 | // the very first time this method runs, we'll need to create the empty arrays 359 | // we can't really do that in the class constructor because we don't know how many meshes we'll read, and this data can change between imports 360 | if (_vertices.Num() <= _meshCurrentlyProcessed) { 361 | _vertices.AddZeroed(); 362 | _normals.AddZeroed(); 363 | _uvs.AddZeroed(); 364 | _tangents.AddZeroed(); 365 | _vertexColors.AddZeroed(); 366 | _indices.AddZeroed(); 367 | } 368 | 369 | // we check whether the current data to read has a different amount of vertices compared to the last time we generated the mesh 370 | // if so, it means we'll need to recreate the mesh and resupply new indices. 371 | if (mesh->mNumVertices != _vertices[_meshCurrentlyProcessed].Num()) 372 | _requiresFullRecreation = true; 373 | 374 | // we reinitialize the arrays for the new data we're reading 375 | _vertices[_meshCurrentlyProcessed].Empty(); 376 | _normals[_meshCurrentlyProcessed].Empty(); 377 | _uvs[_meshCurrentlyProcessed].Empty(); 378 | // this if actually seems useless, seeing what it does without it 379 | //if (_requiresFullRecreation) { 380 | _tangents[_meshCurrentlyProcessed].Empty(); 381 | _vertexColors[_meshCurrentlyProcessed].Empty(); 382 | _indices[_meshCurrentlyProcessed].Empty(); 383 | //} 384 | 385 | FTransform transV; 386 | FTransform transN; 387 | 388 | transV.SetScale3D(ModelScaleTransform); // Assimp -> Unreal 389 | transN.SetScale3D(NormalTransform); 390 | 391 | // HACK! 392 | aiMatrix4x4 nodeTransform = node->mTransformation; 393 | 394 | UE_LOG(LogTemp, Warning, TEXT("NODE SCALE: %f"), nodeTransform.Determinant()); 395 | 396 | if(abs(nodeTransform.Determinant()-1.0)<0.001){ 397 | // TODO: Investigate the real cause, now a hack 398 | transV.SetScale3D(10.0 * transV.GetScale3D()); 399 | transN.SetScale3D(10.0 * transN.GetScale3D()); 400 | } 401 | 402 | for (unsigned int i = 0; i < mesh->mNumVertices; i++) { 403 | FVector vertex, normal; 404 | // process vertex positions, normals and UVs 405 | vertex.X = mesh->mVertices[i].x; 406 | vertex.Y = mesh->mVertices[i].y; 407 | vertex.Z = mesh->mVertices[i].z; 408 | 409 | 410 | normal.X = mesh->mNormals[i].x; 411 | normal.Y = mesh->mNormals[i].y; 412 | normal.Z = mesh->mNormals[i].z; 413 | 414 | if(ApplyTransformation){ 415 | //UE_LOG(LogTemp, Warning, TEXT("Trying to apply transform on mesh")); 416 | vertex = transV.TransformVector(vertex); 417 | normal = transN.TransformVector(normal); 418 | //trans.InverseTr 419 | } 420 | 421 | // if the mesh contains tex coords 422 | if (mesh->mTextureCoords[0]) { 423 | FVector2D uvs; 424 | uvs.X = mesh->mTextureCoords[0][i].x; 425 | uvs.Y = mesh->mTextureCoords[0][i].y; 426 | _uvs[_meshCurrentlyProcessed].Add(uvs); 427 | } 428 | else { 429 | _uvs[_meshCurrentlyProcessed].Add(FVector2D(0.f, 0.f)); 430 | } 431 | _vertices[_meshCurrentlyProcessed].Add(vertex); 432 | _normals[_meshCurrentlyProcessed].Add(normal); 433 | } 434 | 435 | _requiresFullRecreation = true; 436 | 437 | if (_requiresFullRecreation) { 438 | // process indices 439 | for (uint32 i = 0; i < mesh->mNumFaces; i++) { 440 | aiFace face = mesh->mFaces[i]; 441 | if(ApplyTransformation){ 442 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[0]); 443 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[1]); 444 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[2]); 445 | } else { 446 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[2]); 447 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[1]); 448 | _indices[_meshCurrentlyProcessed].Add(face.mIndices[0]); 449 | } 450 | } 451 | } 452 | } 453 | 454 | void URobotMeshComponent::processMaterial(aiMaterial* material, const aiScene* scene){ 455 | if(BaseMaterial == nullptr) return; 456 | 457 | UMaterialInstanceDynamic* unrealMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this); 458 | aiString diffuse_map, normal_map; 459 | UE_LOG(LogTemp, Warning, TEXT("Loading Material")); 460 | if((material->GetTexture(aiTextureType_DIFFUSE, 0, &diffuse_map))==aiReturn_SUCCESS){ 461 | FString TextureName = diffuse_map.data; 462 | FString LongTextureName = FPaths::ConvertRelativePathToFull(FPaths::GetPath(ModelPath), TextureName); 463 | UE_LOG(LogTemp, Warning, TEXT("Located Texture at %s"), *TextureName); 464 | UE_LOG(LogTemp, Warning, TEXT("Raw Path at %s"), *LongTextureName); 465 | 466 | UTexture* unrealTexture = LoadImageFromDisk(this, LongTextureName); 467 | if(unrealTexture!=nullptr) { 468 | _textures.Add(unrealTexture); 469 | UE_LOG(LogTemp, Warning, TEXT("Setting Texture BaseColorParam")); 470 | unrealMaterial->SetTextureParameterValue("BaseColorParam", unrealTexture); 471 | } else { 472 | UE_LOG(LogTemp, Error, TEXT("LoadImageFromDisk failed")); 473 | } 474 | 475 | if((material->GetTexture(aiTextureType_NORMALS, 0, &normal_map))==aiReturn_SUCCESS){ 476 | FString NormalName = normal_map.data; 477 | UTexture* unrealNormal = LoadImageFromDisk(this, FPaths::ConvertRelativePathToFull(FPaths::GetPath(ModelPath), NormalName)); 478 | if(unrealNormal!=nullptr) { 479 | _tnormals.Add(unrealNormal); 480 | UE_LOG(LogTemp, Warning, TEXT("Setting NormalParam")); 481 | unrealMaterial->SetTextureParameterValue("NormalParam", unrealNormal); 482 | } else { 483 | UE_LOG(LogTemp, Error, TEXT("LoadImageFromDisk failed")); 484 | } 485 | } 486 | 487 | _materials.Add(unrealMaterial); 488 | } else { 489 | _materials.Add(unrealMaterial); 490 | } 491 | } 492 | 493 | UTexture2D* URobotMeshComponent::LoadTextureFromPath(const FString& Path) 494 | { 495 | if (Path.IsEmpty()) return NULL; 496 | 497 | return Cast(StaticLoadObject(UTexture2D::StaticClass(), NULL, *(Path))); 498 | } 499 | 500 | UTexture2D* URobotMeshComponent::LoadImageFromDisk(UObject* Outer, const FString& ImagePath) 501 | { 502 | // Check if the file exists first 503 | if (!FPaths::FileExists(ImagePath)) 504 | { 505 | UE_LOG(LogTemp, Error, TEXT("File not found: %s"), *ImagePath); 506 | return nullptr; 507 | } 508 | 509 | // Load the compressed byte data from the file 510 | TArray FileData; 511 | if (!FFileHelper::LoadFileToArray(FileData, *ImagePath)) 512 | { 513 | UE_LOG(LogTemp, Error, TEXT("Failed to load file: %s"), *ImagePath); 514 | return nullptr; 515 | } 516 | 517 | // Detect the image type using the ImageWrapper module 518 | IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); 519 | 520 | EImageFormat ImageFormat = ImageWrapperModule.DetectImageFormat(FileData.GetData(), FileData.Num()); 521 | if (ImageFormat == EImageFormat::Invalid) 522 | { 523 | UE_LOG(LogTemp, Error, TEXT("Unrecognized image file format: %s"), *ImagePath); 524 | return nullptr; 525 | } 526 | 527 | // Create an image wrapper for the detected image format 528 | TSharedPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(ImageFormat); 529 | if (!ImageWrapper.IsValid()) 530 | { 531 | UE_LOG(LogTemp, Error, TEXT("Failed to create image wrapper for file: %s"), *ImagePath); 532 | return nullptr; 533 | } 534 | 535 | // Decompress the image data 536 | const TArray* RawData = nullptr; 537 | ImageWrapper->SetCompressed(FileData.GetData(), FileData.Num()); 538 | ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, RawData); 539 | if (RawData == nullptr) 540 | { 541 | UE_LOG(LogTemp, Error, TEXT("Failed to decompress image file: %s"), *ImagePath); 542 | return nullptr; 543 | } 544 | 545 | // Create the texture and upload the uncompressed image data 546 | FString TextureBaseName = TEXT("Texture_") + FPaths::GetBaseFilename(ImagePath); 547 | return CreateTexture(Outer, *RawData, ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), EPixelFormat::PF_B8G8R8A8, FName(*TextureBaseName)); 548 | } 549 | 550 | UTexture2D* URobotMeshComponent::CreateTexture(UObject* Outer, const TArray& PixelData, int32 InSizeX, int32 InSizeY, EPixelFormat InFormat, FName BaseName) 551 | { 552 | // Shamelessly copied from UTexture2D::CreateTransient with a few modifications 553 | if (InSizeX <= 0 || InSizeY <= 0 || 554 | (InSizeX % GPixelFormats[InFormat].BlockSizeX) != 0 || 555 | (InSizeY % GPixelFormats[InFormat].BlockSizeY) != 0) 556 | { 557 | UE_LOG(LogTemp, Warning, TEXT("Invalid parameters specified for UImageLoader::CreateTexture()")); 558 | return nullptr; 559 | } 560 | 561 | // Most important difference with UTexture2D::CreateTransient: we provide the new texture with a name and an owner 562 | FName TextureName = MakeUniqueObjectName(Outer, UTexture2D::StaticClass(), BaseName); 563 | UTexture2D* NewTexture = NewObject(Outer, TextureName, RF_Transient); 564 | 565 | NewTexture->PlatformData = new FTexturePlatformData(); 566 | NewTexture->PlatformData->SizeX = InSizeX; 567 | NewTexture->PlatformData->SizeY = InSizeY; 568 | NewTexture->PlatformData->PixelFormat = InFormat; 569 | 570 | // Allocate first mipmap and upload the pixel data 571 | int32 NumBlocksX = InSizeX / GPixelFormats[InFormat].BlockSizeX; 572 | int32 NumBlocksY = InSizeY / GPixelFormats[InFormat].BlockSizeY; 573 | FTexture2DMipMap* Mip = new(NewTexture->PlatformData->Mips) FTexture2DMipMap(); 574 | Mip->SizeX = InSizeX; 575 | Mip->SizeY = InSizeY; 576 | Mip->BulkData.Lock(LOCK_READ_WRITE); 577 | void* TextureData = Mip->BulkData.Realloc(NumBlocksX * NumBlocksY * GPixelFormats[InFormat].BlockBytes); 578 | FMemory::Memcpy(TextureData, PixelData.GetData(), PixelData.Num()); 579 | Mip->BulkData.Unlock(); 580 | 581 | NewTexture->UpdateResource(); 582 | return NewTexture; 583 | } 584 | 585 | using namespace VHACD; 586 | 587 | class FMyVHACDProgressCallback : public IVHACD::IUserCallback 588 | { 589 | public: 590 | FMyVHACDProgressCallback(void) {} 591 | ~FMyVHACDProgressCallback() {}; 592 | 593 | void Update(const double overallProgress, const double stageProgress, const double operationProgress, const char * const stage, const char * const operation) 594 | { 595 | //FString StatusString = FString::Printf(TEXT("Processing [%s]..."), ANSI_TO_TCHAR(stage)); 596 | 597 | //GWarn->StatusUpdate(stageProgress*10.f, 1000, FText::FromString(StatusString)); 598 | //GWarn->StatusUpdate(overallProgress*10.f, 1000, FText::FromString(StatusString)); 599 | }; 600 | }; 601 | 602 | void URobotMeshComponent::DecomposeMeshToHulls(TArray< TArray >& ConvexMeshes, const TArray& InVertices, const TArray& InIndices, float InAccuracy, int32 InMaxHullVerts) 603 | { 604 | 605 | bool bSuccess = false; 606 | 607 | // Validate input by checking bounding box 608 | FBox VertBox(ForceInit); 609 | for (FVector Vert : InVertices) 610 | { 611 | VertBox += Vert; 612 | } 613 | 614 | // If box is invalid, or the largest dimension is less than 1 unit, or smallest is less than 0.1, skip trying to generate collision (V-HACD often crashes...) 615 | if (VertBox.IsValid == 0 || VertBox.GetSize().GetMax() < 0.1f || VertBox.GetSize().GetMin() < 0.1f) 616 | { 617 | UE_LOG(LogTemp, Error, TEXT("Object too small for V-HACD: %f, %f"), VertBox.GetSize().GetMax(), VertBox.GetSize().GetMin()); 618 | return; 619 | } 620 | 621 | FMyVHACDProgressCallback VHACD_Callback; 622 | 623 | IVHACD::Parameters VHACD_Params; 624 | VHACD_Params.m_resolution = 100000; // Maximum number of voxels generated during the voxelization stage (default=100,000, range=10,000-16,000,000) 625 | VHACD_Params.m_maxNumVerticesPerCH = InMaxHullVerts; // Controls the maximum number of triangles per convex-hull (default=64, range=4-1024) 626 | VHACD_Params.m_concavity = 0.3f * (1.f - FMath::Clamp(InAccuracy, 0.f, 1.f)); // Maximum allowed concavity (default=0.0025, range=0.0-1.0) 627 | VHACD_Params.m_callback = &VHACD_Callback; 628 | VHACD_Params.m_oclAcceleration = true; 629 | VHACD_Params.m_minVolumePerCH = 0.003f; // this should be around 1 / (3 * m_resolution ^ (1/3)) 630 | 631 | 632 | IVHACD* InterfaceVHACD = CreateVHACD(); 633 | 634 | const float* const Verts = (float*)InVertices.GetData(); 635 | const unsigned int NumVerts = InVertices.Num(); 636 | const uint32_t* const Tris = (uint32_t*)InIndices.GetData(); 637 | const unsigned int NumTris = InIndices.Num() / 3; 638 | 639 | bSuccess = InterfaceVHACD->Compute(Verts, NumVerts, Tris, NumTris, VHACD_Params); 640 | 641 | if(bSuccess) 642 | { 643 | // Clean out old hulls 644 | ConvexMeshes.Empty(); 645 | 646 | // Iterate over each result hull 647 | int32 NumHulls = InterfaceVHACD->GetNConvexHulls(); 648 | 649 | ConvexMeshes.AddDefaulted(NumHulls); 650 | for(int32 HullIdx=0; HullIdxGetConvexHull(HullIdx, Hull); 654 | 655 | 656 | ConvexMeshes[HullIdx].Reserve(Hull.m_nPoints); 657 | 658 | for (uint32 VertIdx = 0; VertIdx < Hull.m_nPoints; VertIdx++) 659 | { 660 | FVector V; 661 | V.X = (float)(Hull.m_points[(VertIdx * 3) + 0]); 662 | V.Y = (float)(Hull.m_points[(VertIdx * 3) + 1]); 663 | V.Z = (float)(Hull.m_points[(VertIdx * 3) + 2]); 664 | 665 | ConvexMeshes[HullIdx].Add(V); 666 | } 667 | } 668 | } 669 | 670 | 671 | InterfaceVHACD->Clean(); 672 | InterfaceVHACD->Release(); 673 | } 674 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Private/UnrealEventPort.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #include "UnrealEventPort.h" 4 | 5 | UnrealEventPort::UnrealEventPort() 6 | { 7 | } 8 | 9 | UnrealEventPort::~UnrealEventPort() 10 | { 11 | } 12 | 13 | bool UnrealEventPort::wait() { 14 | // If events are already pending, they will be processed and we return immediately thereafter 15 | // Otherwise, we block until new events arrive 16 | return false; 17 | } 18 | 19 | bool UnrealEventPort::poll() { 20 | // Process any pending events, but don't block 21 | return false; 22 | } 23 | 24 | void UnrealEventPort::setRunnable(bool runnable) { 25 | isRunnable = runnable; 26 | } 27 | 28 | void UnrealEventPort::run() { 29 | if (kjLoop) 30 | kjLoop->run(); 31 | } 32 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Public/PavilionPlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | class FPavilionPluginModule : public IModuleInterface 9 | { 10 | public: 11 | 12 | /** IModuleInterface implementation */ 13 | virtual void StartupModule() override; 14 | virtual void ShutdownModule() override; 15 | }; 16 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Public/RobotActor.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Fan Jiang All Rights Reserved. This source file is subject to multiple Chinese and International Copyright Laws and Patents. Unauthorized Redistribution is strictly prohibited. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Components/SceneComponent.h" 8 | #include "RobotMeshComponent.h" 9 | #include "PhysicsEngine/PhysicsConstraintComponent.h" 10 | #include "DrawDebugHelpers.h" 11 | #include 12 | #include 13 | #include "RobotActor.generated.h" 14 | 15 | UCLASS() 16 | class PAVILIONPLUGIN_API ARobotActor : public AActor 17 | { 18 | GENERATED_BODY() 19 | 20 | public: 21 | // Sets default values for this actor's properties 22 | ARobotActor(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); 23 | 24 | protected: 25 | // Called when the game starts or when spawned 26 | virtual void BeginPlay() override; 27 | 28 | void LoadModel(const FTransform &Transform); 29 | void LoadModelOnCreation(const FObjectInitializer& ObjectInitializer); 30 | FRotator URDFRotationToUnreal(ignition::math::Quaterniond); 31 | FVector URDFPositionToUnreal(ignition::math::Vector3d); 32 | 33 | FString GetRealPathFromURI(std::string uri); 34 | public: 35 | // Called every frame 36 | virtual void Tick(float DeltaTime) override; 37 | 38 | virtual void OnConstruction(const FTransform &Transform) override; 39 | 40 | virtual void PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent) override; 41 | 42 | UPROPERTY(EditAnywhere) 43 | FString URDFPath = TEXT("/Users/proffan/Notebooks/Robotics/SDF/pr2/model.sdf"); 44 | 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Public/RobotMeshComponent.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Fan Jiang All Rights Reserved. This source file is subject to multiple Chinese and International Copyright Laws and Patents. Unauthorized Redistribution is strictly prohibited. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "RuntimeMeshComponent.h" 7 | //#include "ProceduralMeshComponent.h" 8 | #include "UObject/ConstructorHelpers.h" 9 | #include "Misc/Paths.h" 10 | #include "PixelFormat.h" 11 | #include "assimp/Importer.hpp" 12 | #include "assimp/scene.h" 13 | #include "assimp/vector3.h" 14 | #include "assimp/postprocess.h" 15 | #include "RobotMeshComponent.generated.h" 16 | 17 | UENUM(BlueprintType) 18 | enum class ERobotMeshType : uint8 19 | { 20 | Mesh = 0, 21 | Cylinder, 22 | Box 23 | }; 24 | 25 | UENUM(BlueprintType) 26 | enum class ERobotComponentType : uint8 27 | { 28 | Visual = 0, 29 | Collision, 30 | Both 31 | }; 32 | 33 | /** 34 | * 35 | */ 36 | UCLASS(hidecategories = (Object, LOD), meta = (BlueprintSpawnableComponent), ClassGroup = Rendering) 37 | class PAVILIONPLUGIN_API URobotMeshComponent : public URuntimeMeshComponent 38 | { 39 | GENERATED_UCLASS_BODY() 40 | 41 | public: 42 | 43 | UFUNCTION(BlueprintCallable, Category = "Assimp") 44 | bool openMesh(FString path, int32& SectionCount, FString& ErrorCode); 45 | 46 | UFUNCTION(BlueprintCallable, Category = "Assimp") 47 | bool openCollisionMesh(FString path, FString& ErrorCode); 48 | 49 | UFUNCTION(BlueprintCallable, Category = "Assimp") 50 | bool getSection(int32 index, TArray& Vertices, TArray& Faces, TArray& Normals, TArray& UV, TArray& Tangents); 51 | 52 | UFUNCTION(BlueprintCallable, Category = "Assimp") 53 | void clear(); 54 | 55 | virtual void InitializeComponent() override; 56 | 57 | virtual void OnRegister() override; 58 | 59 | virtual void OnCreatePhysicsState() override; 60 | 61 | virtual void PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent) override; 62 | 63 | UPROPERTY(EditAnywhere) 64 | FString ModelPath = TEXT("/Users/proffan/Notebooks/Robotics/SDF/pr2/meshes/gripper_v0/l_finger_tip.dae"); 65 | 66 | UPROPERTY(EditAnywhere) 67 | FString CollisionPath = TEXT("/Users/proffan/Notebooks/Robotics/SDF/pr2/meshes/gripper_v0/l_finger_tip.stl"); 68 | 69 | UPROPERTY(EditAnywhere) 70 | UMaterialInterface* BaseMaterial; 71 | 72 | UPROPERTY(EditAnywhere) 73 | bool MakeLeftHanded = false; 74 | 75 | UPROPERTY(EditAnywhere) 76 | bool ApplyTransformation = true; 77 | 78 | UPROPERTY(EditAnywhere) 79 | FVector ModelScaleTransform = FVector(10.f, -10.f, 10.f); 80 | 81 | UPROPERTY(EditAnywhere) 82 | FVector CollisionScaleTransform = FVector(100.f, -100.f, 100.f); 83 | 84 | UPROPERTY(EditAnywhere) 85 | FVector NormalTransform = FVector(0.1f, -0.1f, 0.1f); 86 | 87 | UPROPERTY(EditAnywhere) 88 | ERobotMeshType MeshType = ERobotMeshType::Mesh; 89 | 90 | UPROPERTY(EditAnywhere) 91 | ERobotComponentType ComponentType = ERobotComponentType::Both; 92 | 93 | UPROPERTY(EditAnywhere) 94 | FVector2D CylinderSize = FVector2D(0.f, 0.f); 95 | 96 | UPROPERTY(EditAnywhere) 97 | FVector BoxSize = FVector(0.f, 0.f, 0.f); 98 | private: 99 | int32 _selectedVertex; 100 | int32 _meshCurrentlyProcessed; 101 | bool _addModifier; 102 | int _lastModifiedTime; 103 | bool _requiresFullRecreation; 104 | 105 | TArray> _vertices; 106 | TArray> _indices; 107 | TArray> _normals; 108 | TArray> _uvs; 109 | TArray> _tangents; 110 | TArray> _vertexColors; 111 | TArray _materials; 112 | TArray _textures; 113 | TArray _tnormals; 114 | TArray> _convexCollision; 115 | 116 | void processMesh(aiMesh* mesh, const aiNode* node, const aiScene* scene); 117 | void processNode(aiNode* node, const aiScene* scene); 118 | void processMaterial(aiMaterial* material, const aiScene* scene); 119 | UTexture2D* LoadTextureFromPath(const FString& Path); 120 | UTexture2D* LoadImageFromDisk(UObject* Outer, const FString& ImagePath); 121 | UTexture2D* CreateTexture(UObject* Outer, const TArray& PixelData, int32 InSizeX, int32 InSizeY, EPixelFormat InFormat, FName BaseName); 122 | 123 | void DecomposeMeshToHulls(TArray< TArray >& ConvexMeshes, const TArray& InVertices, const TArray& InIndices, float InAccuracy, int32 InMaxHullVerts); 124 | }; 125 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/PavilionPlugin/Public/UnrealEventPort.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | #pragma clang diagnostic push 8 | #pragma clang diagnostic ignored "-Wundef" 9 | #include 10 | #pragma clang diagnostic pop 11 | 12 | /** 13 | * 14 | */ 15 | class PAVILIONPLUGIN_API UnrealEventPort : public kj::EventPort 16 | { 17 | public: 18 | UnrealEventPort(); 19 | ~UnrealEventPort(); 20 | void setLoop(kj::EventLoop* loop) { 21 | // Store a pointer to the KJ event loop to call run() on when it needs to process events. The UnrealEventPort does 22 | // not take ownership of kjLoop. Make sure to call setLoop(nullptr) or destroy the UnrealEventPort prior to 23 | // deallocating kjLoop. 24 | this->kjLoop = loop; 25 | } 26 | // EventPort API 27 | virtual bool wait(); 28 | virtual bool poll(); 29 | virtual void setRunnable(bool runnable); 30 | void run(); 31 | private: 32 | bool isRunnable = false; 33 | kj::EventLoop* kjLoop = nullptr; 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/assimp/assimp.Build.cs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | // You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Copyright (c) 2018, Fan Jiang 6 | 7 | using System.IO; 8 | using System.Text.RegularExpressions; 9 | using UnrealBuildTool; 10 | 11 | public class assimp : ModuleRules 12 | { 13 | public assimp(ReadOnlyTargetRules Target) : base(Target) 14 | { 15 | Type = ModuleType.External; 16 | 17 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 18 | PublicIncludePaths.AddRange( 19 | new string[] { 20 | // ... add public include paths required here ... 21 | } 22 | ); 23 | 24 | var base_path = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../ThirdParty/Release/assimp")); 25 | var build_path = "lib"; 26 | var full_build_path = Path.Combine(base_path, build_path); 27 | 28 | if (!Directory.Exists(full_build_path)) { 29 | Log.TraceError("Invalid build path: " + full_build_path + " (Did you build the 3rdparty module already?)"); 30 | } 31 | 32 | // Look at all the files in the build path; we need to smartly locate 33 | // the static library based on the current platform. For dynamic libraries 34 | // this is more difficult, but for static libraries, it's just .lib or .a 35 | // string [] fileEntries = Directory.GetFiles(full_build_path); 36 | // var pattern = ".*\\."; 37 | // if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) { 38 | // pattern += "lib"; 39 | // } 40 | // else { 41 | // pattern += "a"; 42 | // } 43 | // Regex r = new Regex(pattern, RegexOptions.IgnoreCase); 44 | // string full_library_path = null; 45 | // foreach (var file in fileEntries) { 46 | // if (r.Match(file).Success) { 47 | // full_library_path = Path.Combine(full_build_path, file); 48 | // PublicAdditionalLibraries.Add(full_library_path); 49 | // } 50 | // } 51 | // if (full_library_path == null) { 52 | // Log.TraceError("Unable to locate any build libraries in: " + full_build_path); 53 | // } 54 | if (Target.Platform == UnrealTargetPlatform.Mac) 55 | { 56 | PublicDelayLoadDLLs.Add(Path.Combine(full_build_path, "libassimp.dylib")); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/capnproto/capnproto.Build.cs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | // You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Copyright (c) 2018, Fan Jiang 6 | 7 | using System.IO; 8 | using System.Text.RegularExpressions; 9 | using UnrealBuildTool; 10 | 11 | public class capnproto : ModuleRules 12 | { 13 | public capnproto(ReadOnlyTargetRules Target) : base(Target) 14 | { 15 | Type = ModuleType.External; 16 | 17 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 18 | PublicIncludePaths.AddRange( 19 | new string[] { 20 | // ... add public include paths required here ... 21 | } 22 | ); 23 | 24 | var base_path = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../ThirdParty/Release/capnproto")); 25 | var build_path = "lib"; 26 | var full_build_path = Path.Combine(base_path, build_path); 27 | 28 | if (!Directory.Exists(full_build_path)) { 29 | Log.TraceError("Invalid build path: " + full_build_path + " (Did you build the 3rdparty module already?)"); 30 | } 31 | 32 | // Look at all the files in the build path; we need to smartly locate 33 | // the static library based on the current platform. For dynamic libraries 34 | // this is more difficult, but for static libraries, it's just .lib or .a 35 | string [] fileEntries = Directory.GetFiles(full_build_path); 36 | var pattern = ".*\\."; 37 | if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) { 38 | pattern += "lib"; 39 | } 40 | else { 41 | pattern += "a"; 42 | } 43 | Regex r = new Regex(pattern, RegexOptions.IgnoreCase); 44 | string full_library_path = null; 45 | foreach (var file in fileEntries) { 46 | if (r.Match(file).Success) { 47 | full_library_path = Path.Combine(full_build_path, file); 48 | PublicAdditionalLibraries.Add(full_library_path); 49 | } 50 | } 51 | if (full_library_path == null) { 52 | Log.TraceError("Unable to locate any build libraries in: " + full_build_path); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/cros/cros.Build.cs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | // You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Copyright (c) 2018, Fan Jiang 6 | 7 | using System.IO; 8 | using System.Text.RegularExpressions; 9 | using UnrealBuildTool; 10 | 11 | public class cros : ModuleRules 12 | { 13 | public cros(ReadOnlyTargetRules Target) : base(Target) 14 | { 15 | Type = ModuleType.External; 16 | 17 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 18 | PublicIncludePaths.AddRange( 19 | new string[] { 20 | // ... add public include paths required here ... 21 | } 22 | ); 23 | 24 | var base_path = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../ThirdParty/Release/cros")); 25 | var build_path = "lib"; 26 | var full_build_path = Path.Combine(base_path, build_path); 27 | 28 | if (!Directory.Exists(full_build_path)) { 29 | Log.TraceError("Invalid build path: " + full_build_path + " (Did you build the 3rdparty module already?)"); 30 | } 31 | 32 | // Look at all the files in the build path; we need to smartly locate 33 | // the static library based on the current platform. For dynamic libraries 34 | // this is more difficult, but for static libraries, it's just .lib or .a 35 | string [] fileEntries = Directory.GetFiles(full_build_path); 36 | var pattern = ".*\\."; 37 | if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) { 38 | pattern += "lib"; 39 | } 40 | else { 41 | pattern += "a"; 42 | } 43 | Regex r = new Regex(pattern, RegexOptions.IgnoreCase); 44 | string full_library_path = null; 45 | foreach (var file in fileEntries) { 46 | if (r.Match(file).Success) { 47 | full_library_path = Path.Combine(full_build_path, file); 48 | PublicAdditionalLibraries.Add(full_library_path); 49 | } 50 | } 51 | if (full_library_path == null) { 52 | Log.TraceError("Unable to locate any build libraries in: " + full_build_path); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/ignition/ignition.Build.cs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | // You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Copyright (c) 2018, Fan Jiang 6 | 7 | using System.IO; 8 | using System.Text.RegularExpressions; 9 | using UnrealBuildTool; 10 | 11 | public class ignition : ModuleRules 12 | { 13 | public ignition(ReadOnlyTargetRules Target) : base(Target) 14 | { 15 | Type = ModuleType.External; 16 | 17 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 18 | PublicIncludePaths.AddRange( 19 | new string[] { 20 | // ... add public include paths required here ... 21 | } 22 | ); 23 | 24 | var base_path = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../ThirdParty/Release/ignition-math")); 25 | var build_path = "lib"; 26 | var full_build_path = Path.Combine(base_path, build_path); 27 | 28 | if (!Directory.Exists(full_build_path)) { 29 | Log.TraceError("Invalid build path: " + full_build_path + " (Did you build the 3rdparty module already?)"); 30 | } 31 | 32 | if (Target.Platform == UnrealTargetPlatform.Mac) 33 | { 34 | PublicDelayLoadDLLs.Add(Path.Combine(full_build_path, "libignition-math4.dylib")); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/sdformat/Private/Placeholder.cpp: -------------------------------------------------------------------------------- 1 | void placeholder_34235fdafsaref(){ 2 | return; 3 | } -------------------------------------------------------------------------------- /Plugins/PavilionPlugin/Source/ThirdParty/sdformat/sdformat.Build.cs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 | // You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Copyright (c) 2018, Fan Jiang 6 | 7 | using System.IO; 8 | using System.Text.RegularExpressions; 9 | using UnrealBuildTool; 10 | 11 | public class sdformat : ModuleRules 12 | { 13 | public sdformat(ReadOnlyTargetRules Target) : base(Target) 14 | { 15 | Type = ModuleType.External; 16 | 17 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 18 | PublicIncludePaths.AddRange( 19 | new string[] { 20 | // ... add public include paths required here ... 21 | } 22 | ); 23 | 24 | var base_path = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../../ThirdParty/Release/sdformat")); 25 | var build_path = "lib"; 26 | var full_build_path = Path.Combine(base_path, build_path); 27 | 28 | if (!Directory.Exists(full_build_path)) { 29 | Log.TraceError("Invalid build path: " + full_build_path + " (Did you build the 3rdparty module already?)"); 30 | } 31 | 32 | // Look at all the files in the build path; we need to smartly locate 33 | // the static library based on the current platform. For dynamic libraries 34 | // this is more difficult, but for static libraries, it's just .lib or .a 35 | // string [] fileEntries = Directory.GetFiles(full_build_path); 36 | // var pattern = ".*\\."; 37 | // if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) { 38 | // pattern += "lib"; 39 | // } 40 | // else { 41 | // pattern += "a"; 42 | // } 43 | // Regex r = new Regex(pattern, RegexOptions.IgnoreCase); 44 | // string full_library_path = null; 45 | // foreach (var file in fileEntries) { 46 | // if (r.Match(file).Success) { 47 | // full_library_path = Path.Combine(full_build_path, file); 48 | // PublicAdditionalLibraries.Add(full_library_path); 49 | // } 50 | // } 51 | // if (full_library_path == null) { 52 | // Log.TraceError("Unable to locate any build libraries in: " + full_build_path); 53 | // } 54 | if (Target.Platform == UnrealTargetPlatform.Mac) 55 | { 56 | PublicDelayLoadDLLs.Add(Path.Combine(full_build_path, "libsdformat.dylib")); 57 | } 58 | 59 | PrivateDependencyModuleNames.Add("ignition"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pavilion 2 | 3 | This repo is the main development repo for the Unreal-based robot simulator Pavilion. 4 | 5 | # Introduction 6 | 7 | This is a total recreation of Gazebo in Unreal Engine 4. This work is different with existing UE4-based simulators in that it employs a tightly-coupled approach with ROS and libsdformat. This eliminates the need for intermediate compatibility layers. 8 | 9 | Moreover, the model import process is done at runtime, which allows the simulator to be distributed without the Unreal Editor, a component not allowed to be redistributed by the UE4 License. 10 | 11 | # Features 12 | 13 | - RGB-D Camera, LIDAR Sensor Emulation 14 | - Direct import URDF and SDF models 15 | - Real-time interop with ROS 16 | - Real-time Autonomous Driving Demo 17 | 18 | # How to Build 19 | 20 | First, clone this repo. 21 | 22 | Then go to `Plugins/PavilionPlugin` and run `./BuildThirdParty.sh`. 23 | 24 | Finally open `Pavilion.uproject` with the Unreal Editor. 25 | 26 | Please note that to enable real-time optical flow output, you need to have a version of UE4 patched with [my patch](https://github.com/ProfFan/UnrealOpticalFlowDemo). 27 | 28 | # Supported Versions 29 | 30 | Unreal Engine version > 4.18 31 | 32 | # License 33 | 34 | MIT 35 | -------------------------------------------------------------------------------- /Source/Pavilion.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class PavilionTarget : TargetRules 7 | { 8 | public PavilionTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Game; 11 | ExtraModuleNames.Add("Pavilion"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Source/Pavilion/Pavilion.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pavilion : ModuleRules 6 | { 7 | public Pavilion(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "PhysXVehicles", "HeadMountedDisplay", "PavilionPlugin" }); 12 | 13 | PublicDefinitions.Add("HMD_MODULE_INCLUDED=1"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/Pavilion/Pavilion.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pavilion.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pavilion, "Pavilion" ); 7 | -------------------------------------------------------------------------------- /Source/Pavilion/Pavilion.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionGameMode.h" 4 | #include "PavilionPawn.h" 5 | #include "PavilionHud.h" 6 | 7 | APavilionGameMode::APavilionGameMode() 8 | { 9 | DefaultPawnClass = APavilionPawn::StaticClass(); 10 | HUDClass = APavilionHud::StaticClass(); 11 | } 12 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionGameMode.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "PavilionGameMode.generated.h" 8 | 9 | UCLASS(MinimalAPI) 10 | class APavilionGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APavilionGameMode(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionHud.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionHud.h" 4 | #include "PavilionPawn.h" 5 | #include "Engine/Canvas.h" 6 | #include "Engine/Font.h" 7 | #include "CanvasItem.h" 8 | #include "UObject/ConstructorHelpers.h" 9 | #include "Engine/Engine.h" 10 | 11 | // Needed for VR Headset 12 | #include "Engine.h" 13 | 14 | #define LOCTEXT_NAMESPACE "VehicleHUD" 15 | 16 | APavilionHud::APavilionHud() 17 | { 18 | static ConstructorHelpers::FObjectFinder Font(TEXT("/Engine/EngineFonts/RobotoDistanceField")); 19 | HUDFont = Font.Object; 20 | } 21 | 22 | void APavilionHud::DrawHUD() 23 | { 24 | Super::DrawHUD(); 25 | 26 | // Calculate ratio from 720p 27 | const float HUDXRatio = Canvas->SizeX / 1280.f; 28 | const float HUDYRatio = Canvas->SizeY / 720.f; 29 | 30 | bool bHMDDeviceActive = false; 31 | 32 | // We dont want the onscreen hud when using a HMD device 33 | #if HMD_MODULE_INCLUDED 34 | bHMDDeviceActive = GEngine->IsStereoscopic3D(); 35 | #endif // HMD_MODULE_INCLUDED 36 | if( bHMDDeviceActive == false ) 37 | { 38 | // Get our vehicle so we can check if we are in car. If we are we don't want onscreen HUD 39 | APavilionPawn* Vehicle = Cast(GetOwningPawn()); 40 | if ((Vehicle != nullptr) && (Vehicle->bInCarCameraActive == false)) 41 | { 42 | FVector2D ScaleVec(HUDYRatio * 1.4f, HUDYRatio * 1.4f); 43 | 44 | // Speed 45 | FCanvasTextItem SpeedTextItem(FVector2D(HUDXRatio * 805.f, HUDYRatio * 455), Vehicle->SpeedDisplayString, HUDFont, FLinearColor::White); 46 | SpeedTextItem.Scale = ScaleVec; 47 | Canvas->DrawItem(SpeedTextItem); 48 | 49 | // Gear 50 | FCanvasTextItem GearTextItem(FVector2D(HUDXRatio * 805.f, HUDYRatio * 500.f), Vehicle->GearDisplayString, HUDFont, Vehicle->bInReverseGear == false ? Vehicle->GearDisplayColor : Vehicle->GearDisplayReverseColor); 51 | GearTextItem.Scale = ScaleVec; 52 | Canvas->DrawItem(GearTextItem); 53 | } 54 | } 55 | } 56 | 57 | #undef LOCTEXT_NAMESPACE 58 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionHud.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/HUD.h" 7 | #include "PavilionHud.generated.h" 8 | 9 | UCLASS(config = Game) 10 | class APavilionHud : public AHUD 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APavilionHud(); 16 | 17 | /** Font used to render the vehicle info */ 18 | UPROPERTY() 19 | UFont* HUDFont; 20 | 21 | // Begin AHUD interface 22 | virtual void DrawHUD() override; 23 | // End AHUD interface 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionPawn.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionPawn.h" 4 | #include "PavilionWheelFront.h" 5 | #include "PavilionWheelRear.h" 6 | #include "PavilionHud.h" 7 | #include "Components/SkeletalMeshComponent.h" 8 | #include "GameFramework/SpringArmComponent.h" 9 | #include "Camera/CameraComponent.h" 10 | #include "Components/InputComponent.h" 11 | #include "Components/TextRenderComponent.h" 12 | #include "Components/AudioComponent.h" 13 | #include "Sound/SoundCue.h" 14 | #include "PhysicalMaterials/PhysicalMaterial.h" 15 | #include "WheeledVehicleMovementComponent4W.h" 16 | #include "Engine/SkeletalMesh.h" 17 | #include "Engine/Engine.h" 18 | #include "GameFramework/Controller.h" 19 | #include "UObject/ConstructorHelpers.h" 20 | 21 | // Needed for VR Headset 22 | #if HMD_MODULE_INCLUDED 23 | #include "IXRTrackingSystem.h" 24 | #include "HeadMountedDisplayFunctionLibrary.h" 25 | #endif // HMD_MODULE_INCLUDED 26 | 27 | const FName APavilionPawn::LookUpBinding("LookUp"); 28 | const FName APavilionPawn::LookRightBinding("LookRight"); 29 | const FName APavilionPawn::EngineAudioRPM("RPM"); 30 | 31 | #define LOCTEXT_NAMESPACE "VehiclePawn" 32 | 33 | APavilionPawn::APavilionPawn() 34 | { 35 | // Car mesh 36 | static ConstructorHelpers::FObjectFinder CarMesh(TEXT("/Game/VehicleAdv/Vehicle/Vehicle_SkelMesh.Vehicle_SkelMesh")); 37 | GetMesh()->SetSkeletalMesh(CarMesh.Object); 38 | 39 | static ConstructorHelpers::FClassFinder AnimBPClass(TEXT("/Game/VehicleAdv/Vehicle/VehicleAnimationBlueprint")); 40 | GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint); 41 | GetMesh()->SetAnimInstanceClass(AnimBPClass.Class); 42 | 43 | // Setup friction materials 44 | static ConstructorHelpers::FObjectFinder SlipperyMat(TEXT("/Game/VehicleAdv/PhysicsMaterials/Slippery.Slippery")); 45 | SlipperyMaterial = SlipperyMat.Object; 46 | 47 | static ConstructorHelpers::FObjectFinder NonSlipperyMat(TEXT("/Game/VehicleAdv/PhysicsMaterials/NonSlippery.NonSlippery")); 48 | NonSlipperyMaterial = NonSlipperyMat.Object; 49 | 50 | UWheeledVehicleMovementComponent4W* Vehicle4W = CastChecked(GetVehicleMovement()); 51 | 52 | check(Vehicle4W->WheelSetups.Num() == 4); 53 | 54 | // Wheels/Tyres 55 | // Setup the wheels 56 | Vehicle4W->WheelSetups[0].WheelClass = UPavilionWheelFront::StaticClass(); 57 | Vehicle4W->WheelSetups[0].BoneName = FName("PhysWheel_FL"); 58 | Vehicle4W->WheelSetups[0].AdditionalOffset = FVector(0.f, -8.f, 0.f); 59 | 60 | Vehicle4W->WheelSetups[1].WheelClass = UPavilionWheelFront::StaticClass(); 61 | Vehicle4W->WheelSetups[1].BoneName = FName("PhysWheel_FR"); 62 | Vehicle4W->WheelSetups[1].AdditionalOffset = FVector(0.f, 8.f, 0.f); 63 | 64 | Vehicle4W->WheelSetups[2].WheelClass = UPavilionWheelRear::StaticClass(); 65 | Vehicle4W->WheelSetups[2].BoneName = FName("PhysWheel_BL"); 66 | Vehicle4W->WheelSetups[2].AdditionalOffset = FVector(0.f, -8.f, 0.f); 67 | 68 | Vehicle4W->WheelSetups[3].WheelClass = UPavilionWheelRear::StaticClass(); 69 | Vehicle4W->WheelSetups[3].BoneName = FName("PhysWheel_BR"); 70 | Vehicle4W->WheelSetups[3].AdditionalOffset = FVector(0.f, 8.f, 0.f); 71 | 72 | // Adjust the tire loading 73 | Vehicle4W->MinNormalizedTireLoad = 0.0f; 74 | Vehicle4W->MinNormalizedTireLoadFiltered = 0.2f; 75 | Vehicle4W->MaxNormalizedTireLoad = 2.0f; 76 | Vehicle4W->MaxNormalizedTireLoadFiltered = 2.0f; 77 | 78 | // Engine 79 | // Torque setup 80 | Vehicle4W->MaxEngineRPM = 5700.0f; 81 | Vehicle4W->EngineSetup.TorqueCurve.GetRichCurve()->Reset(); 82 | Vehicle4W->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(0.0f, 400.0f); 83 | Vehicle4W->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(1890.0f, 500.0f); 84 | Vehicle4W->EngineSetup.TorqueCurve.GetRichCurve()->AddKey(5730.0f, 400.0f); 85 | 86 | // Adjust the steering 87 | Vehicle4W->SteeringCurve.GetRichCurve()->Reset(); 88 | Vehicle4W->SteeringCurve.GetRichCurve()->AddKey(0.0f, 1.0f); 89 | Vehicle4W->SteeringCurve.GetRichCurve()->AddKey(40.0f, 0.7f); 90 | Vehicle4W->SteeringCurve.GetRichCurve()->AddKey(120.0f, 0.6f); 91 | 92 | // Transmission 93 | // We want 4wd 94 | Vehicle4W->DifferentialSetup.DifferentialType = EVehicleDifferential4W::LimitedSlip_4W; 95 | 96 | // Drive the front wheels a little more than the rear 97 | Vehicle4W->DifferentialSetup.FrontRearSplit = 0.65; 98 | 99 | // Automatic gearbox 100 | Vehicle4W->TransmissionSetup.bUseGearAutoBox = true; 101 | Vehicle4W->TransmissionSetup.GearSwitchTime = 0.15f; 102 | Vehicle4W->TransmissionSetup.GearAutoBoxLatency = 1.0f; 103 | 104 | // Physics settings 105 | // Adjust the center of mass - the buggy is quite low 106 | UPrimitiveComponent* UpdatedPrimitive = Cast(Vehicle4W->UpdatedComponent); 107 | if (UpdatedPrimitive) 108 | { 109 | UpdatedPrimitive->BodyInstance.COMNudge = FVector(8.0f, 0.0f, 0.0f); 110 | } 111 | 112 | // Set the inertia scale. This controls how the mass of the vehicle is distributed. 113 | Vehicle4W->InertiaTensorScale = FVector(1.0f, 1.333f, 1.2f); 114 | 115 | // Create a spring arm component for our chase camera 116 | SpringArm = CreateDefaultSubobject(TEXT("SpringArm")); 117 | SpringArm->SetRelativeLocation(FVector(0.0f, 0.0f, 34.0f)); 118 | SpringArm->SetWorldRotation(FRotator(-20.0f, 0.0f, 0.0f)); 119 | SpringArm->SetupAttachment(RootComponent); 120 | SpringArm->TargetArmLength = 125.0f; 121 | SpringArm->bEnableCameraLag = false; 122 | SpringArm->bEnableCameraRotationLag = false; 123 | SpringArm->bInheritPitch = true; 124 | SpringArm->bInheritYaw = true; 125 | SpringArm->bInheritRoll = true; 126 | 127 | // Create the chase camera component 128 | Camera = CreateDefaultSubobject(TEXT("ChaseCamera")); 129 | Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName); 130 | Camera->SetRelativeLocation(FVector(-125.0, 0.0f, 0.0f)); 131 | Camera->SetRelativeRotation(FRotator(10.0f, 0.0f, 0.0f)); 132 | Camera->bUsePawnControlRotation = false; 133 | Camera->FieldOfView = 90.f; 134 | 135 | // Create In-Car camera component 136 | InternalCameraOrigin = FVector(-34.0f, -10.0f, 50.0f); 137 | InternalCameraBase = CreateDefaultSubobject(TEXT("InternalCameraBase")); 138 | InternalCameraBase->SetRelativeLocation(InternalCameraOrigin); 139 | InternalCameraBase->SetupAttachment(GetMesh()); 140 | 141 | InternalCamera = CreateDefaultSubobject(TEXT("InternalCamera")); 142 | InternalCamera->bUsePawnControlRotation = false; 143 | InternalCamera->FieldOfView = 90.f; 144 | InternalCamera->SetupAttachment(InternalCameraBase); 145 | 146 | // In car HUD 147 | // Create text render component for in car speed display 148 | InCarSpeed = CreateDefaultSubobject(TEXT("IncarSpeed")); 149 | InCarSpeed->SetRelativeScale3D(FVector(0.1f, 0.1f, 0.1f)); 150 | InCarSpeed->SetRelativeLocation(FVector(35.0f, -6.0f, 20.0f)); 151 | InCarSpeed->SetRelativeRotation(FRotator(0.0f, 180.0f, 0.0f)); 152 | InCarSpeed->SetupAttachment(GetMesh()); 153 | 154 | // Create text render component for in car gear display 155 | InCarGear = CreateDefaultSubobject(TEXT("IncarGear")); 156 | InCarGear->SetRelativeScale3D(FVector(0.1f, 0.1f, 0.1f)); 157 | InCarGear->SetRelativeLocation(FVector(35.0f, 5.0f, 20.0f)); 158 | InCarGear->SetRelativeRotation(FRotator(0.0f, 180.0f, 0.0f)); 159 | InCarGear->SetupAttachment(GetMesh()); 160 | 161 | // Setup the audio component and allocate it a sound cue 162 | static ConstructorHelpers::FObjectFinder SoundCue(TEXT("/Game/VehicleAdv/Sound/Engine_Loop_Cue.Engine_Loop_Cue")); 163 | EngineSoundComponent = CreateDefaultSubobject(TEXT("EngineSound")); 164 | EngineSoundComponent->SetSound(SoundCue.Object); 165 | EngineSoundComponent->SetupAttachment(GetMesh()); 166 | 167 | // Colors for the in-car gear display. One for normal one for reverse 168 | GearDisplayReverseColor = FColor(255, 0, 0, 255); 169 | GearDisplayColor = FColor(255, 255, 255, 255); 170 | 171 | bIsLowFriction = false; 172 | bInReverseGear = false; 173 | } 174 | 175 | void APavilionPawn::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) 176 | { 177 | Super::SetupPlayerInputComponent(PlayerInputComponent); 178 | 179 | // set up gameplay key bindings 180 | check(PlayerInputComponent); 181 | 182 | PlayerInputComponent->BindAxis("MoveForward", this, &APavilionPawn::MoveForward); 183 | PlayerInputComponent->BindAxis("MoveRight", this, &APavilionPawn::MoveRight); 184 | PlayerInputComponent->BindAxis(LookUpBinding); 185 | PlayerInputComponent->BindAxis(LookRightBinding); 186 | 187 | PlayerInputComponent->BindAction("Handbrake", IE_Pressed, this, &APavilionPawn::OnHandbrakePressed); 188 | PlayerInputComponent->BindAction("Handbrake", IE_Released, this, &APavilionPawn::OnHandbrakeReleased); 189 | PlayerInputComponent->BindAction("SwitchCamera", IE_Pressed, this, &APavilionPawn::OnToggleCamera); 190 | 191 | PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &APavilionPawn::OnResetVR); 192 | } 193 | 194 | void APavilionPawn::MoveForward(float Val) 195 | { 196 | GetVehicleMovementComponent()->SetThrottleInput(Val); 197 | 198 | } 199 | 200 | void APavilionPawn::MoveRight(float Val) 201 | { 202 | GetVehicleMovementComponent()->SetSteeringInput(Val); 203 | } 204 | 205 | void APavilionPawn::OnHandbrakePressed() 206 | { 207 | GetVehicleMovementComponent()->SetHandbrakeInput(true); 208 | } 209 | 210 | void APavilionPawn::OnHandbrakeReleased() 211 | { 212 | GetVehicleMovementComponent()->SetHandbrakeInput(false); 213 | } 214 | 215 | void APavilionPawn::OnToggleCamera() 216 | { 217 | EnableIncarView(!bInCarCameraActive); 218 | } 219 | 220 | void APavilionPawn::EnableIncarView(const bool bState) 221 | { 222 | if (bState != bInCarCameraActive) 223 | { 224 | bInCarCameraActive = bState; 225 | 226 | if (bState == true) 227 | { 228 | OnResetVR(); 229 | Camera->Deactivate(); 230 | InternalCamera->Activate(); 231 | } 232 | else 233 | { 234 | InternalCamera->Deactivate(); 235 | Camera->Activate(); 236 | } 237 | 238 | InCarSpeed->SetVisibility(bInCarCameraActive); 239 | InCarGear->SetVisibility(bInCarCameraActive); 240 | } 241 | } 242 | 243 | void APavilionPawn::Tick(float Delta) 244 | { 245 | Super::Tick(Delta); 246 | 247 | // Setup the flag to say we are in reverse gear 248 | bInReverseGear = GetVehicleMovement()->GetCurrentGear() < 0; 249 | 250 | // Update phsyics material 251 | UpdatePhysicsMaterial(); 252 | 253 | // Update the strings used in the hud (incar and onscreen) 254 | UpdateHUDStrings(); 255 | 256 | // Set the string in the incar hud 257 | SetupInCarHUD(); 258 | 259 | bool bHMDActive = false; 260 | #if HMD_MODULE_INCLUDED 261 | if ((GEngine->XRSystem.IsValid() == true ) && ( (GEngine->XRSystem->IsHeadTrackingAllowed() == true) || (GEngine->IsStereoscopic3D() == true))) 262 | { 263 | bHMDActive = true; 264 | } 265 | #endif // HMD_MODULE_INCLUDED 266 | if( bHMDActive == false ) 267 | { 268 | if ( (InputComponent) && (bInCarCameraActive == true )) 269 | { 270 | FRotator HeadRotation = InternalCamera->RelativeRotation; 271 | HeadRotation.Pitch += InputComponent->GetAxisValue(LookUpBinding); 272 | HeadRotation.Yaw += InputComponent->GetAxisValue(LookRightBinding); 273 | InternalCamera->RelativeRotation = HeadRotation; 274 | } 275 | } 276 | 277 | // Pass the engine RPM to the sound component 278 | float RPMToAudioScale = 2500.0f / GetVehicleMovement()->GetEngineMaxRotationSpeed(); 279 | EngineSoundComponent->SetFloatParameter(EngineAudioRPM, GetVehicleMovement()->GetEngineRotationSpeed()*RPMToAudioScale); 280 | } 281 | 282 | void APavilionPawn::BeginPlay() 283 | { 284 | Super::BeginPlay(); 285 | 286 | bool bWantInCar = false; 287 | // First disable both speed/gear displays 288 | bInCarCameraActive = false; 289 | InCarSpeed->SetVisibility(bInCarCameraActive); 290 | InCarGear->SetVisibility(bInCarCameraActive); 291 | 292 | // Enable in car view if HMD is attached 293 | #if HMD_MODULE_INCLUDED 294 | bWantInCar = UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled(); 295 | #endif // HMD_MODULE_INCLUDED 296 | 297 | EnableIncarView(bWantInCar); 298 | // Start an engine sound playing 299 | EngineSoundComponent->Play(); 300 | } 301 | 302 | void APavilionPawn::OnResetVR() 303 | { 304 | #if HMD_MODULE_INCLUDED 305 | if (GEngine->XRSystem.IsValid()) 306 | { 307 | GEngine->XRSystem->ResetOrientationAndPosition(); 308 | InternalCamera->SetRelativeLocation(InternalCameraOrigin); 309 | GetController()->SetControlRotation(FRotator()); 310 | } 311 | #endif // HMD_MODULE_INCLUDED 312 | } 313 | 314 | void APavilionPawn::UpdateHUDStrings() 315 | { 316 | float KPH = FMath::Abs(GetVehicleMovement()->GetForwardSpeed()) * 0.036f; 317 | int32 KPH_int = FMath::FloorToInt(KPH); 318 | int32 Gear = GetVehicleMovement()->GetCurrentGear(); 319 | 320 | // Using FText because this is display text that should be localizable 321 | SpeedDisplayString = FText::Format(LOCTEXT("SpeedFormat", "{0} km/h"), FText::AsNumber(KPH_int)); 322 | 323 | 324 | if (bInReverseGear == true) 325 | { 326 | GearDisplayString = FText(LOCTEXT("ReverseGear", "R")); 327 | } 328 | else 329 | { 330 | GearDisplayString = (Gear == 0) ? LOCTEXT("N", "N") : FText::AsNumber(Gear); 331 | } 332 | 333 | } 334 | 335 | void APavilionPawn::SetupInCarHUD() 336 | { 337 | APlayerController* PlayerController = Cast(GetController()); 338 | if ((PlayerController != nullptr) && (InCarSpeed != nullptr) && (InCarGear != nullptr)) 339 | { 340 | // Setup the text render component strings 341 | InCarSpeed->SetText(SpeedDisplayString); 342 | InCarGear->SetText(GearDisplayString); 343 | 344 | if (bInReverseGear == false) 345 | { 346 | InCarGear->SetTextRenderColor(GearDisplayColor); 347 | } 348 | else 349 | { 350 | InCarGear->SetTextRenderColor(GearDisplayReverseColor); 351 | } 352 | } 353 | } 354 | 355 | void APavilionPawn::UpdatePhysicsMaterial() 356 | { 357 | if (GetActorUpVector().Z < 0) 358 | { 359 | if (bIsLowFriction == true) 360 | { 361 | GetMesh()->SetPhysMaterialOverride(NonSlipperyMaterial); 362 | bIsLowFriction = false; 363 | } 364 | else 365 | { 366 | GetMesh()->SetPhysMaterialOverride(SlipperyMaterial); 367 | bIsLowFriction = true; 368 | } 369 | } 370 | } 371 | 372 | #undef LOCTEXT_NAMESPACE 373 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionPawn.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "WheeledVehicle.h" 7 | #include "PavilionPawn.generated.h" 8 | 9 | class UPhysicalMaterial; 10 | class UCameraComponent; 11 | class USpringArmComponent; 12 | class UTextRenderComponent; 13 | class UInputComponent; 14 | class UAudioComponent; 15 | 16 | UCLASS(config=Game) 17 | class APavilionPawn : public AWheeledVehicle 18 | { 19 | GENERATED_BODY() 20 | 21 | /** Spring arm that will offset the camera */ 22 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 23 | USpringArmComponent* SpringArm; 24 | 25 | /** Camera component that will be our viewpoint */ 26 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 27 | UCameraComponent* Camera; 28 | 29 | /** SCene component for the In-Car view origin */ 30 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 31 | class USceneComponent* InternalCameraBase; 32 | 33 | /** Camera component for the In-Car view */ 34 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 35 | UCameraComponent* InternalCamera; 36 | 37 | /** Text component for the In-Car speed */ 38 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 39 | UTextRenderComponent* InCarSpeed; 40 | 41 | /** Text component for the In-Car gear */ 42 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 43 | UTextRenderComponent* InCarGear; 44 | 45 | /** Audio component for the engine sound */ 46 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 47 | UAudioComponent* EngineSoundComponent; 48 | 49 | public: 50 | APavilionPawn(); 51 | 52 | /** The current speed as a string eg 10 km/h */ 53 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly) 54 | FText SpeedDisplayString; 55 | 56 | /** The current gear as a string (R,N, 1,2 etc) */ 57 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly) 58 | FText GearDisplayString; 59 | 60 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly) 61 | /** The color of the incar gear text in forward gears */ 62 | FColor GearDisplayColor; 63 | 64 | /** The color of the incar gear text when in reverse */ 65 | UPROPERTY(Category = Display, VisibleDefaultsOnly, BlueprintReadOnly) 66 | FColor GearDisplayReverseColor; 67 | 68 | /** Are we using incar camera */ 69 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly) 70 | bool bInCarCameraActive; 71 | 72 | /** Are we in reverse gear */ 73 | UPROPERTY(Category = Camera, VisibleDefaultsOnly, BlueprintReadOnly) 74 | bool bInReverseGear; 75 | 76 | /** Initial offset of incar camera */ 77 | FVector InternalCameraOrigin; 78 | 79 | // Begin Pawn interface 80 | virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override; 81 | // End Pawn interface 82 | 83 | // Begin Actor interface 84 | virtual void Tick(float Delta) override; 85 | protected: 86 | virtual void BeginPlay() override; 87 | 88 | public: 89 | // End Actor interface 90 | 91 | /** Handle pressing forwards */ 92 | void MoveForward(float Val); 93 | 94 | /** Setup the strings used on the hud */ 95 | void SetupInCarHUD(); 96 | 97 | /** Update the physics material used by the vehicle mesh */ 98 | void UpdatePhysicsMaterial(); 99 | 100 | /** Handle pressing right */ 101 | void MoveRight(float Val); 102 | /** Handle handbrake pressed */ 103 | void OnHandbrakePressed(); 104 | /** Handle handbrake released */ 105 | void OnHandbrakeReleased(); 106 | /** Switch between cameras */ 107 | void OnToggleCamera(); 108 | /** Handle reset VR device */ 109 | void OnResetVR(); 110 | 111 | static const FName LookUpBinding; 112 | static const FName LookRightBinding; 113 | static const FName EngineAudioRPM; 114 | 115 | private: 116 | /** 117 | * Activate In-Car camera. Enable camera and sets visibility of incar hud display 118 | * 119 | * @param bState true will enable in car view and set visibility of various 120 | */ 121 | void EnableIncarView( const bool bState ); 122 | 123 | /** Update the gear and speed strings */ 124 | void UpdateHUDStrings(); 125 | 126 | /* Are we on a 'slippery' surface */ 127 | bool bIsLowFriction; 128 | /** Slippery Material instance */ 129 | UPhysicalMaterial* SlipperyMaterial; 130 | /** Non Slippery Material instance */ 131 | UPhysicalMaterial* NonSlipperyMaterial; 132 | 133 | 134 | public: 135 | /** Returns SpringArm subobject **/ 136 | FORCEINLINE USpringArmComponent* GetSpringArm() const { return SpringArm; } 137 | /** Returns Camera subobject **/ 138 | FORCEINLINE UCameraComponent* GetCamera() const { return Camera; } 139 | /** Returns InternalCamera subobject **/ 140 | FORCEINLINE UCameraComponent* GetInternalCamera() const { return InternalCamera; } 141 | /** Returns InCarSpeed subobject **/ 142 | FORCEINLINE UTextRenderComponent* GetInCarSpeed() const { return InCarSpeed; } 143 | /** Returns InCarGear subobject **/ 144 | FORCEINLINE UTextRenderComponent* GetInCarGear() const { return InCarGear; } 145 | /** Returns EngineSoundComponent subobject **/ 146 | FORCEINLINE UAudioComponent* GetEngineSoundComponent() const { return EngineSoundComponent; } 147 | }; 148 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionWheelFront.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionWheelFront.h" 4 | #include "TireConfig.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | UPavilionWheelFront::UPavilionWheelFront() 8 | { 9 | ShapeRadius = 18.f; 10 | ShapeWidth = 15.0f; 11 | bAffectedByHandbrake = false; 12 | SteerAngle = 40.f; 13 | 14 | // Setup suspension forces 15 | SuspensionForceOffset = -4.0f; 16 | SuspensionMaxRaise = 8.0f; 17 | SuspensionMaxDrop = 12.0f; 18 | SuspensionNaturalFrequency = 9.0f; 19 | SuspensionDampingRatio = 1.05f; 20 | 21 | // Find the tire object and set the data for it 22 | static ConstructorHelpers::FObjectFinder TireData(TEXT("/Game/VehicleAdv/Vehicle/WheelData/Vehicle_FrontTireConfig.Vehicle_FrontTireConfig")); 23 | TireConfig = TireData.Object; 24 | } 25 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionWheelFront.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "VehicleWheel.h" 7 | #include "PavilionWheelFront.generated.h" 8 | 9 | UCLASS() 10 | class UPavilionWheelFront : public UVehicleWheel 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPavilionWheelFront(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionWheelRear.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PavilionWheelRear.h" 4 | #include "TireConfig.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | UPavilionWheelRear::UPavilionWheelRear() 8 | { 9 | ShapeRadius = 18.0f; 10 | ShapeWidth = 15.0f; 11 | bAffectedByHandbrake = true; 12 | SteerAngle = 0.f; 13 | 14 | // Setup suspension forces 15 | SuspensionForceOffset = -4.0f; 16 | SuspensionMaxRaise = 8.0f; 17 | SuspensionMaxDrop = 12.0f; 18 | SuspensionNaturalFrequency = 9.0f; 19 | SuspensionDampingRatio = 1.05f; 20 | 21 | // Find the tire object and set the data for it 22 | static ConstructorHelpers::FObjectFinder TireData(TEXT("/Game/VehicleAdv/Vehicle/WheelData/Vehicle_BackTireConfig.Vehicle_BackTireConfig")); 23 | TireConfig = TireData.Object; 24 | } 25 | -------------------------------------------------------------------------------- /Source/Pavilion/PavilionWheelRear.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "VehicleWheel.h" 7 | #include "PavilionWheelRear.generated.h" 8 | 9 | UCLASS() 10 | class UPavilionWheelRear : public UVehicleWheel 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPavilionWheelRear(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Source/PavilionEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class PavilionEditorTarget : TargetRules 7 | { 8 | public PavilionEditorTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | ExtraModuleNames.Add("Pavilion"); 12 | } 13 | } 14 | --------------------------------------------------------------------------------