Merge branch 'main' into jckand/FoundationAuto
This commit is contained in:
@@ -0,0 +1,666 @@
|
||||
{
|
||||
"Source": "Default_Level.prefab",
|
||||
"ContainerEntity": {
|
||||
"Id": "Entity_[1146574390643]",
|
||||
"Name": "Level",
|
||||
"Components": {
|
||||
"Component_[10641544592923449938]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 10641544592923449938
|
||||
},
|
||||
"Component_[12039882709170782873]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 12039882709170782873
|
||||
},
|
||||
"Component_[12265484671603697631]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 12265484671603697631
|
||||
},
|
||||
"Component_[14126657869720434043]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 14126657869720434043
|
||||
},
|
||||
"Component_[15230859088967841193]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 15230859088967841193,
|
||||
"Parent Entity": "",
|
||||
"Cached World Transform Parent": ""
|
||||
},
|
||||
"Component_[16239496886950819870]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 16239496886950819870
|
||||
},
|
||||
"Component_[5688118765544765547]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 5688118765544765547
|
||||
},
|
||||
"Component_[6545738857812235305]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 6545738857812235305
|
||||
},
|
||||
"Component_[7247035804068349658]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 7247035804068349658
|
||||
},
|
||||
"Component_[9307224322037797205]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9307224322037797205
|
||||
},
|
||||
"Component_[9562516168917670048]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 9562516168917670048
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[1155164325235]": {
|
||||
"Id": "Entity_[1155164325235]",
|
||||
"Name": "Sun",
|
||||
"Components": {
|
||||
"Component_[10440557478882592717]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 10440557478882592717
|
||||
},
|
||||
"Component_[13620450453324765907]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 13620450453324765907
|
||||
},
|
||||
"Component_[2134313378593666258]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 2134313378593666258
|
||||
},
|
||||
"Component_[234010807770404186]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 234010807770404186
|
||||
},
|
||||
"Component_[2970359110423865725]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 2970359110423865725
|
||||
},
|
||||
"Component_[3722854130373041803]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3722854130373041803
|
||||
},
|
||||
"Component_[5992533738676323195]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5992533738676323195
|
||||
},
|
||||
"Component_[7378860763541895402]": {
|
||||
"$type": "AZ::Render::EditorDirectionalLightComponent",
|
||||
"Id": 7378860763541895402,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Intensity": 1.0,
|
||||
"CameraEntityId": "",
|
||||
"ShadowFilterMethod": 1,
|
||||
"ShadowmapSize": "Size1024",
|
||||
"Pcf Method": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[7892834440890947578]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 7892834440890947578,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.0,
|
||||
0.0,
|
||||
13.487043380737305
|
||||
],
|
||||
"Rotate": [
|
||||
-76.13099670410156,
|
||||
-0.847000002861023,
|
||||
-15.8100004196167
|
||||
]
|
||||
},
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
9.442070960998536
|
||||
],
|
||||
"Rotation": [
|
||||
-0.6098860502243042,
|
||||
-0.09055805951356888,
|
||||
-0.10376212745904924,
|
||||
0.7804304361343384
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[8599729549570828259]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 8599729549570828259
|
||||
},
|
||||
"Component_[952797371922080273]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 952797371922080273
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1159459292531]": {
|
||||
"Id": "Entity_[1159459292531]",
|
||||
"Name": "Ground",
|
||||
"Components": {
|
||||
"Component_[11701138785793981042]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11701138785793981042
|
||||
},
|
||||
"Component_[12260880513256986252]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 12260880513256986252
|
||||
},
|
||||
"Component_[13711420870643673468]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 13711420870643673468
|
||||
},
|
||||
"Component_[138002849734991713]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 138002849734991713
|
||||
},
|
||||
"Component_[16578565737331764849]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 16578565737331764849,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[16919232076966545697]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 16919232076966545697
|
||||
},
|
||||
"Component_[5182430712893438093]": {
|
||||
"$type": "EditorMaterialComponent",
|
||||
"Id": 5182430712893438093,
|
||||
"materialSlots": [
|
||||
{
|
||||
"id": {
|
||||
"materialAssetId": {
|
||||
"guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
|
||||
"subId": 803645540
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"materialSlotsByLod": [
|
||||
[
|
||||
{
|
||||
"id": {
|
||||
"lodIndex": 0,
|
||||
"materialAssetId": {
|
||||
"guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
|
||||
"subId": 803645540
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Component_[5675108321710651991]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 5675108321710651991,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
|
||||
"subId": 277333723
|
||||
},
|
||||
"assetHint": "objects/groudplane/groundplane_521x521m.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[5681893399601237518]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 5681893399601237518
|
||||
},
|
||||
"Component_[592692962543397545]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 592692962543397545
|
||||
},
|
||||
"Component_[7090012899106946164]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7090012899106946164
|
||||
},
|
||||
"Component_[9410832619875640998]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 9410832619875640998
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1163754259827]": {
|
||||
"Id": "Entity_[1163754259827]",
|
||||
"Name": "Camera",
|
||||
"Components": {
|
||||
"Component_[11895140916889160460]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 11895140916889160460
|
||||
},
|
||||
"Component_[16880285896855930892]": {
|
||||
"$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
|
||||
"Id": 16880285896855930892,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Field of View": 55.0,
|
||||
"EditorEntityId": 8929576024571800510
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[17187464423780271193]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 17187464423780271193
|
||||
},
|
||||
"Component_[17495696818315413311]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 17495696818315413311
|
||||
},
|
||||
"Component_[18086214374043522055]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 18086214374043522055,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
-2.300000190734864,
|
||||
-3.9368600845336916,
|
||||
1.0
|
||||
],
|
||||
"Rotate": [
|
||||
-2.050307512283325,
|
||||
1.9552897214889529,
|
||||
-43.62335586547852
|
||||
]
|
||||
},
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
-11.904647827148438,
|
||||
13.392678260803223,
|
||||
-3.0449724197387697
|
||||
],
|
||||
"Rotation": [
|
||||
-0.02294669672846794,
|
||||
0.00919158011674881,
|
||||
-0.37172695994377139,
|
||||
0.9280129671096802
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[18387556550380114975]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 18387556550380114975
|
||||
},
|
||||
"Component_[2654521436129313160]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 2654521436129313160
|
||||
},
|
||||
"Component_[5265045084611556958]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5265045084611556958
|
||||
},
|
||||
"Component_[7169798125182238623]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 7169798125182238623
|
||||
},
|
||||
"Component_[8866210352157164042]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 8866210352157164042
|
||||
},
|
||||
"Component_[9129253381063760879]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 9129253381063760879
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1168049227123]": {
|
||||
"Id": "Entity_[1168049227123]",
|
||||
"Name": "Grid",
|
||||
"Components": {
|
||||
"Component_[11443347433215807130]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 11443347433215807130
|
||||
},
|
||||
"Component_[11779275529534764488]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11779275529534764488
|
||||
},
|
||||
"Component_[14249419413039427459]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14249419413039427459
|
||||
},
|
||||
"Component_[15448581635946161318]": {
|
||||
"$type": "AZ::Render::EditorGridComponent",
|
||||
"Id": 15448581635946161318,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"primarySpacing": 4.0,
|
||||
"primaryColor": [
|
||||
0.501960813999176,
|
||||
0.501960813999176,
|
||||
0.501960813999176
|
||||
],
|
||||
"secondarySpacing": 0.5,
|
||||
"secondaryColor": [
|
||||
0.250980406999588,
|
||||
0.250980406999588,
|
||||
0.250980406999588
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[1843303322527297409]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 1843303322527297409
|
||||
},
|
||||
"Component_[380249072065273654]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 380249072065273654,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[7476660583684339787]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 7476660583684339787
|
||||
},
|
||||
"Component_[7557626501215118375]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 7557626501215118375
|
||||
},
|
||||
"Component_[7984048488947365511]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 7984048488947365511
|
||||
},
|
||||
"Component_[8118181039276487398]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 8118181039276487398
|
||||
},
|
||||
"Component_[9189909764215270515]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9189909764215270515
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1172344194419]": {
|
||||
"Id": "Entity_[1172344194419]",
|
||||
"Name": "Shader Ball",
|
||||
"Components": {
|
||||
"Component_[10789351944715265527]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 10789351944715265527
|
||||
},
|
||||
"Component_[12037033284781049225]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 12037033284781049225
|
||||
},
|
||||
"Component_[13759153306105970079]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 13759153306105970079
|
||||
},
|
||||
"Component_[14135560884830586279]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14135560884830586279
|
||||
},
|
||||
"Component_[16247165675903986673]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 16247165675903986673
|
||||
},
|
||||
"Component_[18082433625958885247]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 18082433625958885247
|
||||
},
|
||||
"Component_[6472623349872972660]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6472623349872972660,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Transform Data": {
|
||||
"Rotate": [
|
||||
0.0,
|
||||
0.10000000149011612,
|
||||
180.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"Rotation": [
|
||||
0.0008726645028218627,
|
||||
0.0,
|
||||
0.9999996423721314,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[6495255223970673916]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 6495255223970673916,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
|
||||
"subId": 281415304
|
||||
},
|
||||
"assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[8056625192494070973]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 8056625192494070973
|
||||
},
|
||||
"Component_[8550141614185782969]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 8550141614185782969
|
||||
},
|
||||
"Component_[9439770997198325425]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 9439770997198325425
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1176639161715]": {
|
||||
"Id": "Entity_[1176639161715]",
|
||||
"Name": "Atom Default Environment",
|
||||
"Components": {
|
||||
"Component_[10757302973393310045]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 10757302973393310045,
|
||||
"Parent Entity": "Entity_[1146574390643]",
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1146574390643]"
|
||||
},
|
||||
"Component_[14505817420424255464]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14505817420424255464,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 10757302973393310045
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[14988041764659020032]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 14988041764659020032
|
||||
},
|
||||
"Component_[15808690248755038124]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 15808690248755038124
|
||||
},
|
||||
"Component_[15900837685796817138]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 15900837685796817138
|
||||
},
|
||||
"Component_[3298767348226484884]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3298767348226484884
|
||||
},
|
||||
"Component_[4076975109609220594]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 4076975109609220594
|
||||
},
|
||||
"Component_[5679760548946028854]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5679760548946028854
|
||||
},
|
||||
"Component_[5855590796136709437]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 5855590796136709437,
|
||||
"ChildEntityOrderEntryArray": [
|
||||
{
|
||||
"EntityId": "Entity_[1155164325235]"
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1180934129011]",
|
||||
"SortIndex": 1
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1172344194419]",
|
||||
"SortIndex": 2
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1168049227123]",
|
||||
"SortIndex": 3
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1163754259827]",
|
||||
"SortIndex": 4
|
||||
},
|
||||
{
|
||||
"EntityId": "Entity_[1159459292531]",
|
||||
"SortIndex": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[9277695270015777859]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 9277695270015777859
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[1180934129011]": {
|
||||
"Id": "Entity_[1180934129011]",
|
||||
"Name": "Global Sky",
|
||||
"Components": {
|
||||
"Component_[11231930600558681245]": {
|
||||
"$type": "AZ::Render::EditorHDRiSkyboxComponent",
|
||||
"Id": 11231930600558681245,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"CubemapAsset": {
|
||||
"assetId": {
|
||||
"guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
|
||||
"subId": 1000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[11980494120202836095]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 11980494120202836095
|
||||
},
|
||||
"Component_[1428633914413949476]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 1428633914413949476
|
||||
},
|
||||
"Component_[14936200426671614999]": {
|
||||
"$type": "AZ::Render::EditorImageBasedLightComponent",
|
||||
"Id": 14936200426671614999,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"diffuseImageAsset": {
|
||||
"assetId": {
|
||||
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
|
||||
"subId": 3000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
|
||||
},
|
||||
"specularImageAsset": {
|
||||
"assetId": {
|
||||
"guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
|
||||
"subId": 2000
|
||||
},
|
||||
"assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[14994774102579326069]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 14994774102579326069
|
||||
},
|
||||
"Component_[15417479889044493340]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 15417479889044493340
|
||||
},
|
||||
"Component_[15826613364991382688]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 15826613364991382688
|
||||
},
|
||||
"Component_[1665003113283562343]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 1665003113283562343
|
||||
},
|
||||
"Component_[3704934735944502280]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 3704934735944502280
|
||||
},
|
||||
"Component_[5698542331457326479]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 5698542331457326479
|
||||
},
|
||||
"Component_[6644513399057217122]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 6644513399057217122,
|
||||
"Parent Entity": "Entity_[1176639161715]",
|
||||
"Cached World Transform": {
|
||||
"Translation": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"Cached World Transform Parent": "Entity_[1176639161715]"
|
||||
},
|
||||
"Component_[931091830724002070]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 931091830724002070
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
# Extracted from Editor.xml
|
||||
set(GEM_DEPENDENCIES
|
||||
Gem::Maestro.Editor
|
||||
Gem::TextureAtlas
|
||||
Gem::TextureAtlas.Editor
|
||||
Gem::LmbrCentral.Editor
|
||||
Gem::LyShine.Editor
|
||||
Gem::HttpRequestor
|
||||
|
||||
@@ -1020,29 +1020,60 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
/// OnDemand reflection for AZStd::set
|
||||
|
||||
template<class t_Key, class t_Hasher, class t_EqualKey, class t_Allocator>
|
||||
class Iterator_VM<AZStd::unordered_set<t_Key, t_Hasher, t_EqualKey, t_Allocator>>
|
||||
{
|
||||
public:
|
||||
using ContainerType = AZStd::unordered_set<t_Key, t_Hasher, t_EqualKey, t_Allocator>;
|
||||
using IteratorType = typename ContainerType::iterator;
|
||||
Iterator_VM(ContainerType& container)
|
||||
: m_iterator(container.begin())
|
||||
, m_end(container.end())
|
||||
{}
|
||||
|
||||
const t_Key& GetKeyUnchecked() const
|
||||
{
|
||||
return *m_iterator;
|
||||
}
|
||||
|
||||
bool IsNotAtEnd() const
|
||||
{
|
||||
return m_iterator != m_end;
|
||||
}
|
||||
|
||||
t_Key& ModValueUnchecked()
|
||||
{
|
||||
return *m_iterator;
|
||||
}
|
||||
|
||||
void Next()
|
||||
{
|
||||
++m_iterator;
|
||||
}
|
||||
|
||||
private:
|
||||
IteratorType m_iterator;
|
||||
IteratorType m_end;
|
||||
};
|
||||
|
||||
/// OnDemand reflection for AZStd::unordered_set
|
||||
template<class Key, class Hasher, class EqualKey, class Allocator>
|
||||
struct OnDemandReflection< AZStd::unordered_set<Key, Hasher, EqualKey, Allocator> >
|
||||
{
|
||||
using ContainerType = AZStd::unordered_set<Key, Hasher, EqualKey, Allocator>;
|
||||
using KeyListType = AZStd::vector<Key, Allocator>;
|
||||
|
||||
static AZ::Outcome<void, void> Erase(ContainerType& thisMap, Key& key)
|
||||
using ValueIteratorType = Iterator_VM<ContainerType>;
|
||||
|
||||
static bool EraseCheck_VM(ContainerType& thisSet, Key& key)
|
||||
{
|
||||
const auto result = thisMap.erase(key);
|
||||
if (result)
|
||||
{
|
||||
return AZ::Success();
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure();
|
||||
}
|
||||
return thisSet.erase(key) != 0;
|
||||
}
|
||||
|
||||
static void Insert(ContainerType& thisSet, Key& key)
|
||||
static ContainerType& ErasePost_VM(ContainerType& thisSet, [[maybe_unused]] Key&)
|
||||
{
|
||||
thisSet.insert(key);
|
||||
return thisSet;
|
||||
}
|
||||
|
||||
static KeyListType GetKeys(ContainerType& thisSet)
|
||||
@@ -1055,6 +1086,17 @@ namespace AZ
|
||||
return keys;
|
||||
}
|
||||
|
||||
static ContainerType& Insert(ContainerType& thisSet, Key& key)
|
||||
{
|
||||
thisSet.insert(key);
|
||||
return thisSet;
|
||||
}
|
||||
|
||||
static ValueIteratorType Iterate_VM(ContainerType& thisContainer)
|
||||
{
|
||||
return ValueIteratorType(thisContainer);
|
||||
}
|
||||
|
||||
static void Swap(ContainerType& thisSet, ContainerType& otherSet)
|
||||
{
|
||||
thisSet.swap(otherSet);
|
||||
@@ -1064,33 +1106,68 @@ namespace AZ
|
||||
{
|
||||
if (BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
BranchOnResultInfo emptyBranchInfo;
|
||||
emptyBranchInfo.m_returnResultInBranches = true;
|
||||
emptyBranchInfo.m_trueToolTip = "The container is empty";
|
||||
emptyBranchInfo.m_falseToolTip = "The container is not empty";
|
||||
|
||||
auto ContainsTransparent = [](const ContainerType& containerType, typename ContainerType::key_type& key)->bool
|
||||
{
|
||||
return containerType.contains(key);
|
||||
};
|
||||
|
||||
ExplicitOverloadInfo explicitOverloadInfo;
|
||||
behaviorContext->Class<ContainerType>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::PrettyName, ScriptCanvasOnDemandReflection::OnDemandPrettyName<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::ToolTip, ScriptCanvasOnDemandReflection::OnDemandToolTip<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::Category, ScriptCanvasOnDemandReflection::OnDemandCategoryName<ContainerType>::Get(*behaviorContext))
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
|
||||
->Method("BucketCount", static_cast<typename ContainerType::size_type(ContainerType::*)() const>(&ContainerType::bucket_count))
|
||||
->Method("Erase", &Erase)
|
||||
->Method("Empty", [](ContainerType& thisSet)->bool { return thisSet.empty(); })
|
||||
->Method("Empty", static_cast<bool(ContainerType::*)() const>(&ContainerType::empty), { { { "Container", "The container to check if it is empty", nullptr, {} } } })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Is Empty", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::BranchOnResult, emptyBranchInfo)
|
||||
->Method("EraseCheck_VM", &EraseCheck_VM)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Method("Erase", &ErasePost_VM)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Erase", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::CheckedOperation, CheckedOperationInfo("EraseCheck_VM", {}, "Out", "Key Not Found", true))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "" }, { "ContainerGroup" }))
|
||||
->Method("contains", ContainsTransparent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Has Key", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Method("Insert", &Insert)
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Insert", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "", "" }, { "ContainerGroup" }))
|
||||
->Method(k_sizeName, [](ContainerType* thisPtr) { return aznumeric_cast<int>(thisPtr->size()); })
|
||||
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Length)
|
||||
->Method("GetKeys", &GetKeys)
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Method("GetSize", [](ContainerType& thisPtr) { return aznumeric_cast<int>(thisPtr.size()); })
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Size", "Containers"))
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Method("Reserve", static_cast<void(ContainerType::*)(typename ContainerType::size_type)>(&ContainerType::reserve))
|
||||
->Method("Swap", &Swap)
|
||||
->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; })
|
||||
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers"))
|
||||
->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" }))
|
||||
->Method(k_iteratorConstructorName, &Iterate_VM)
|
||||
;
|
||||
|
||||
behaviorContext->Class<ValueIteratorType>()
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
|
||||
->Method(k_iteratorGetKeyName, &ValueIteratorType::GetKeyUnchecked)
|
||||
->Method(k_iteratorModValueName, &ValueIteratorType::ModValueUnchecked)
|
||||
->Method(k_iteratorIsNotAtEndName, &ValueIteratorType::IsNotAtEnd)
|
||||
->Method(k_iteratorNextName, &ValueIteratorType::Next)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace AZ
|
||||
|
||||
if (HasResult() != overload->HasResult())
|
||||
{
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace AZ
|
||||
|
||||
if (!(methodResult->m_typeId == overloadResult->m_typeId && methodResult->m_traits == overloadResult->m_traits))
|
||||
{
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
|
||||
AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -575,7 +575,7 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("BehaviorContext", false, "safety check declared for method %s but it was not found in the class");
|
||||
AZ_Error("BehaviorContext", false, "Method: %s, declared safety check: %s, but it was not found in class: %s", method.m_name.c_str(), m_name.c_str(), checkedOperationInfo.m_safetyCheckName.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,17 @@ namespace BehaviorContextUtilitiesCPP
|
||||
using argument_type = const BehaviorParameter*;
|
||||
using result_type = size_t;
|
||||
result_type operator()(const argument_type& value) const
|
||||
{
|
||||
result_type result = AZStd::hash<Uuid>()(value->m_typeId);
|
||||
AZStd::hash_combine(result, CleanTraits(value->m_traits));
|
||||
return result;
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
result_type result = AZStd::hash<Uuid>()(value->m_typeId);
|
||||
AZStd::hash_combine(result, CleanTraits(value->m_traits));
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,7 +52,11 @@ namespace BehaviorContextUtilitiesCPP
|
||||
{
|
||||
bool operator()(const BehaviorParameter* left, const BehaviorParameter* right) const
|
||||
{
|
||||
return left->m_typeId == right->m_typeId && CleanTraits(left->m_traits) == CleanTraits(right->m_traits);
|
||||
return (left == nullptr && right == nullptr)
|
||||
|| (left != nullptr
|
||||
&& right != nullptr
|
||||
&& left->m_typeId == right->m_typeId
|
||||
&& CleanTraits(left->m_traits) == CleanTraits(right->m_traits));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -137,7 +148,7 @@ namespace AZ
|
||||
for (size_t argIndex = 0, argSentinel = overload.GetNumArguments(); argIndex < argSentinel; ++argIndex)
|
||||
{
|
||||
auto overloadedArgIter = variance.m_input.find(argIndex);
|
||||
if (overloadedArgIter != variance.m_input.end())
|
||||
if (overloadedArgIter != variance.m_input.end() && overloadedArgIter->second[overloadIndex])
|
||||
{
|
||||
// if this doesn't work try the type name
|
||||
overloadName += ReplaceCppArtifacts(overloadedArgIter->second[overloadIndex]->m_name);
|
||||
@@ -185,16 +196,24 @@ namespace AZ
|
||||
{
|
||||
auto argument = overloads[overloadIndex].first->GetArgument(0);
|
||||
|
||||
const bool isThisPointer
|
||||
= (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
|
||||
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
|
||||
if (argument)
|
||||
{
|
||||
const bool isThisPointer
|
||||
= (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
|
||||
|| AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
|
||||
|
||||
oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
|
||||
oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
|
||||
}
|
||||
|
||||
types.insert(argument);
|
||||
stripedArgs.emplace_back(argument);
|
||||
}
|
||||
|
||||
if (types.size() == overloads.size())
|
||||
{
|
||||
variance.m_unambiguousInput.insert(0);
|
||||
}
|
||||
|
||||
if (types.size() > 1 && (onThis == VariantOnThis::Yes || !oneArgIsThisPointer))
|
||||
{
|
||||
variance.m_input.insert(AZStd::make_pair(0, stripedArgs));
|
||||
@@ -210,11 +229,15 @@ namespace AZ
|
||||
for (size_t overloadIndex = 0, overloadSentinel = overloads.size(); overloadIndex < overloadSentinel; ++overloadIndex)
|
||||
{
|
||||
auto argument = overloads[overloadIndex].first->GetArgument(argIndex);
|
||||
|
||||
types.insert(argument);
|
||||
stripedArgs.emplace_back(argument);
|
||||
}
|
||||
|
||||
if (types.size() == overloads.size())
|
||||
{
|
||||
variance.m_unambiguousInput.insert(0);
|
||||
}
|
||||
|
||||
if (types.size() > 1)
|
||||
{
|
||||
variance.m_input.insert(AZStd::make_pair(argIndex, stripedArgs));
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace AZ
|
||||
struct OverloadVariance
|
||||
{
|
||||
AZStd::unordered_map<size_t, AZStd::vector<const BehaviorParameter*>> m_input;
|
||||
// the indices of inputs that make selection of overload unambiguous
|
||||
AZStd::unordered_set<size_t> m_unambiguousInput;
|
||||
AZStd::vector<const BehaviorParameter*> m_output;
|
||||
};
|
||||
|
||||
|
||||
@@ -2048,10 +2048,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Script", false, "Index %d is not a function!", functionIndex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2078,7 +2074,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Script", lua_isnil(m_nativeContext, -1), "Name %s exists but is not a function!", functionName);
|
||||
lua_pop(m_nativeContext, 1);
|
||||
}
|
||||
|
||||
@@ -5888,7 +5883,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else
|
||||
{
|
||||
lua_pop(m_impl->m_lua, 1);
|
||||
AZ_Warning("Script", false, "%s is not a function!", functionName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -5906,7 +5900,6 @@ LUA_API const Node* lua_getDummyNode()
|
||||
else
|
||||
{
|
||||
lua_pop(m_impl->m_lua, 1);
|
||||
AZ_Warning("Script", false, "CacheIndex %d is not a function!", cachedIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AzCore/RTTI/TypeInfo.h"
|
||||
#include <AzCore/Math/UuidSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/Json/CastingHelpers.h>
|
||||
@@ -61,6 +62,13 @@ namespace AZ
|
||||
|
||||
if (classData->m_azRtti && classData->m_azRtti->GetGenericTypeId() != typeId)
|
||||
{
|
||||
if (((classData->m_azRtti->GetTypeTraits() & (AZ::TypeTraits::is_signed | AZ::TypeTraits::is_unsigned)) != AZ::TypeTraits{0}) &&
|
||||
context.GetSerializeContext()->GetUnderlyingTypeId(typeId) == classData->m_typeId)
|
||||
{
|
||||
// This value is from an enum, where a field has been reflected using ClassBuilder::Field, but the enum
|
||||
// type itself has not been reflected using EnumBuilder. Treat it as an enum.
|
||||
return LoadEnum(object, *classData, value, context);
|
||||
}
|
||||
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
|
||||
if (serializer)
|
||||
{
|
||||
@@ -77,21 +85,18 @@ namespace AZ
|
||||
{
|
||||
return LoadEnum(object, *classData, value, context);
|
||||
}
|
||||
else if (classData->m_container)
|
||||
if (classData->m_container)
|
||||
{
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
"The Json Serializer uses custom serializers to load containers. If this message is encountered "
|
||||
"then a serializer for the target containers is missing, isn't registered or doesn't exist.");
|
||||
}
|
||||
else if (value.IsObject())
|
||||
if (value.IsObject())
|
||||
{
|
||||
return LoadClass(object, *classData, value, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
|
||||
}
|
||||
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
|
||||
AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
|
||||
}
|
||||
|
||||
JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId,
|
||||
@@ -233,8 +238,16 @@ namespace AZ
|
||||
AZ::TypeId underlyingTypeId = AZ::TypeId::CreateNull();
|
||||
if (!attributeReader.Read<AZ::TypeId>(underlyingTypeId))
|
||||
{
|
||||
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
"Unable to find underlying type of enum in class data.");
|
||||
// for non-reflected enums, the passed-in classData already represents the enum's underlying type
|
||||
if (context.GetSerializeContext()->GetUnderlyingTypeId(classData.m_typeId) == classData.m_typeId)
|
||||
{
|
||||
underlyingTypeId = classData.m_typeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
"Unable to find underlying type of enum in class data.");
|
||||
}
|
||||
}
|
||||
|
||||
const SerializeContext::ClassData* underlyingClassData = context.GetSerializeContext()->FindClassData(underlyingTypeId);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace JsonSerializationTests
|
||||
{
|
||||
using JsonSerializationTestCases = ::testing::Types<
|
||||
// Structures
|
||||
SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper,
|
||||
SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper, NonReflectedEnumWrapper,
|
||||
// Pointers
|
||||
SimpleNullPointer, SimpleAssignedPointer, ComplexAssignedPointer, ComplexNullInheritedPointer,
|
||||
ComplexAssignedDifferentInheritedPointer, ComplexAssignedSameInheritedPointer,
|
||||
|
||||
@@ -373,6 +373,57 @@ namespace JsonSerializationTests
|
||||
return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
|
||||
}
|
||||
|
||||
// NonReflectedEnumWrapper
|
||||
bool NonReflectedEnumWrapper::Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const
|
||||
{
|
||||
return !fullReflection || (m_enumClass == rhs.m_enumClass && m_rawEnum== rhs.m_rawEnum);
|
||||
}
|
||||
|
||||
void NonReflectedEnumWrapper::Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context, bool fullReflection)
|
||||
{
|
||||
if (fullReflection)
|
||||
{
|
||||
// Note that the enums are not reflected using context->Enum<>
|
||||
|
||||
context->Class<NonReflectedEnumWrapper>()
|
||||
->Field("enumClass", &NonReflectedEnumWrapper::m_enumClass)
|
||||
->Field("rawEnum", &NonReflectedEnumWrapper::m_rawEnum);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceWithSomeDefaults<NonReflectedEnumWrapper> NonReflectedEnumWrapper::GetInstanceWithSomeDefaults()
|
||||
{
|
||||
auto instance = AZStd::make_unique<NonReflectedEnumWrapper>();
|
||||
instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
|
||||
|
||||
const char* strippedDefaults = R"(
|
||||
{
|
||||
"enumClass": 2
|
||||
})";
|
||||
const char* keptDefaults = R"(
|
||||
{
|
||||
"enumClass": 2,
|
||||
"rawEnum": 0
|
||||
})";
|
||||
|
||||
return MakeInstanceWithSomeDefaults(AZStd::move(instance),
|
||||
strippedDefaults, keptDefaults);
|
||||
}
|
||||
|
||||
InstanceWithoutDefaults<NonReflectedEnumWrapper> NonReflectedEnumWrapper::GetInstanceWithoutDefaults()
|
||||
{
|
||||
auto instance = AZStd::make_unique<NonReflectedEnumWrapper>();
|
||||
instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
|
||||
instance->m_rawEnum = NonReflectedEnumWrapper::SimpleRawEnum::RawOption1;
|
||||
|
||||
const char* json = R"(
|
||||
{
|
||||
"enumClass": 2,
|
||||
"rawEnum": 1
|
||||
})";
|
||||
return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
|
||||
}
|
||||
|
||||
// TemplatedClass<int>
|
||||
|
||||
bool TemplatedClass<int>::Equals(const TemplatedClass<int>& rhs, bool fullReflection) const
|
||||
|
||||
@@ -134,6 +134,35 @@ namespace JsonSerializationTests
|
||||
SimpleRawEnum m_rawEnum{};
|
||||
};
|
||||
|
||||
struct NonReflectedEnumWrapper
|
||||
{
|
||||
enum class SimpleEnumClass
|
||||
{
|
||||
Option1 = 1,
|
||||
Option2,
|
||||
};
|
||||
enum SimpleRawEnum
|
||||
{
|
||||
RawOption1 = 1,
|
||||
RawOption2,
|
||||
};
|
||||
AZ_CLASS_ALLOCATOR(NonReflectedEnumWrapper, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(NonReflectedEnumWrapper, "{A80D5B6B-2FD1-46E9-A7A9-44C5E2650526}");
|
||||
|
||||
static constexpr bool SupportsPartialDefaults = true;
|
||||
|
||||
NonReflectedEnumWrapper() = default;
|
||||
virtual ~NonReflectedEnumWrapper() = default;
|
||||
|
||||
bool Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const;
|
||||
static void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context, bool fullReflection);
|
||||
static InstanceWithSomeDefaults<NonReflectedEnumWrapper> GetInstanceWithSomeDefaults();
|
||||
static InstanceWithoutDefaults<NonReflectedEnumWrapper> GetInstanceWithoutDefaults();
|
||||
|
||||
SimpleEnumClass m_enumClass{};
|
||||
SimpleRawEnum m_rawEnum{};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct TemplatedClass
|
||||
{
|
||||
@@ -158,5 +187,7 @@ namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleEnumClass, "{AF6F1964-5B20-4689-BF23-F36B9C9AAE6A}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleRawEnum, "{EB24207F-B48F-4D8B-940D-3CD06A371739}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleEnumClass, "{E80E4A41-B29E-4B7C-B630-3B599172C837}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleRawEnum, "{C42AF28D-4F84-4540-972A-5B6EEFAB13FF}");
|
||||
AZ_TYPE_INFO_TEMPLATE(JsonSerializationTests::TemplatedClass, "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", AZ_TYPE_INFO_TYPENAME);
|
||||
}
|
||||
|
||||
@@ -99,51 +99,18 @@ namespace AzFramework::ProjectManager
|
||||
AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
|
||||
}
|
||||
{
|
||||
const char projectsScript[] = "projects.py";
|
||||
AZStd::string filename = "o3de";
|
||||
AZ::IO::FixedMaxPath executablePath = AZ::Utils::GetExecutableDirectory();
|
||||
executablePath /= filename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION;
|
||||
|
||||
AZ_Warning("ProjectManager", false, "No project provided - launching project selector.");
|
||||
|
||||
if (engineRootPath.empty())
|
||||
if (!AZ::IO::SystemFile::Exists(executablePath.c_str()))
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Couldn't find engine root");
|
||||
AZ_Error("ProjectManager", false, "%s not found", executablePath.c_str());
|
||||
return false;
|
||||
}
|
||||
auto projectManagerPath = engineRootPath / "scripts" / "project_manager";
|
||||
|
||||
if (!AZ::IO::SystemFile::Exists((projectManagerPath / projectsScript).c_str()))
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "%s not found at %s!", projectsScript, projectManagerPath.c_str());
|
||||
return false;
|
||||
}
|
||||
AZ::IO::FixedMaxPathString executablePath;
|
||||
AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath.data(), executablePath.capacity());
|
||||
if (result.m_pathStored != AZ::Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Could not determine executable path!");
|
||||
return false;
|
||||
}
|
||||
AZ::IO::FixedMaxPath parentPath(executablePath.c_str());
|
||||
auto exeFolder = parentPath.ParentPath();
|
||||
AZStd::fixed_string<8> debugOption;
|
||||
auto lastSep = exeFolder.Native().find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
if (lastSep != AZStd::string_view::npos)
|
||||
{
|
||||
exeFolder = exeFolder.Native().substr(lastSep + 1);
|
||||
}
|
||||
if (exeFolder == "debug")
|
||||
{
|
||||
// We need to use the debug version of the python interpreter to load up our debug version of our libraries which work with the debug version of QT living in this folder
|
||||
debugOption = "debug ";
|
||||
}
|
||||
AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python";
|
||||
pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL;
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(),
|
||||
debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId());
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
processLaunchInfo.m_commandlineParameters = cmdPath;
|
||||
processLaunchInfo.m_showWindow = false;
|
||||
processLaunchInfo.m_commandlineParameters = executablePath.String();
|
||||
launchSuccess = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
}
|
||||
if (ownsSystemAllocator)
|
||||
|
||||
@@ -65,5 +65,12 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
ly_add_googletest(
|
||||
NAME AZ::AzNetworking.Tests
|
||||
)
|
||||
|
||||
ly_add_googletest(
|
||||
NAME AZ::AzNetworking.Tests.Sandbox
|
||||
TARGET AZ::AzNetworking.Tests
|
||||
TEST_SUITE sandbox
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
|
||||
TEST_F(TcpTransportTests, DISABLED_TestSingleClient)
|
||||
#else
|
||||
TEST_F(TcpTransportTests, TestSingleClient)
|
||||
TEST_F(TcpTransportTests, SUITE_sandbox_TestSingleClient)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
|
||||
{
|
||||
TestTcpServer testServer;
|
||||
@@ -157,7 +157,7 @@ namespace UnitTest
|
||||
#if AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
|
||||
TEST_F(TcpTransportTests, DISABLED_TestMultipleClients)
|
||||
#else
|
||||
TEST_F(TcpTransportTests, TestMultipleClients)
|
||||
TEST_F(TcpTransportTests, SUITE_sandbox_TestMultipleClients)
|
||||
#endif // AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
|
||||
{
|
||||
constexpr uint32_t NumTestClients = 50;
|
||||
|
||||
+50
-10
@@ -14,9 +14,11 @@
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h>
|
||||
#include <AzToolsFramework/Prefab/EditorPrefabComponent.h>
|
||||
@@ -222,21 +224,52 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
|
||||
|
||||
m_rootInstance->SetTemplateSourcePath(relativePath);
|
||||
|
||||
bool newLevelFromTemplate = false;
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
// This has not been loaded yet, this is the case of being saved with a different name.
|
||||
// Create it
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({m_rootInstance->m_containerEntity.get()});
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
bool sourceInfoFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
|
||||
sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName,
|
||||
assetInfo, watchFolder);
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
if (sourceInfoFound)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
|
||||
|
||||
// Get the default prefab and copy the Dom over to the new template being saved
|
||||
Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
|
||||
Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
|
||||
|
||||
Prefab::PrefabDom levelDefaultDom;
|
||||
levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
|
||||
|
||||
Prefab::PrefabDomPath sourcePath("/Source");
|
||||
sourcePath.Set(levelDefaultDom, relativePath.c_str());
|
||||
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(levelDefaultDom));
|
||||
newLevelFromTemplate = true;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
else
|
||||
{
|
||||
// Create an empty level since we couldn't find the default template
|
||||
m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
|
||||
|
||||
AzToolsFramework::Prefab::PrefabDom dom;
|
||||
bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
|
||||
if (!success)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
|
||||
return false;
|
||||
}
|
||||
templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
|
||||
}
|
||||
|
||||
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
|
||||
{
|
||||
AZ_Error("Prefab", false, "Couldn't add new template id '%i' when saving file '%.*s'", templateId, AZ_STRING_ARG(filename));
|
||||
@@ -253,6 +286,13 @@ namespace AzToolsFramework
|
||||
m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
|
||||
}
|
||||
|
||||
// If we have a new level from a template, we need to make sure to propagate the changes here otherwise
|
||||
// the entities from the new template won't show up
|
||||
if (newLevelFromTemplate)
|
||||
{
|
||||
m_prefabSystemComponent->PropagateTemplateChanges(templateId);
|
||||
}
|
||||
|
||||
AZStd::string out;
|
||||
if (m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out))
|
||||
{
|
||||
|
||||
+2
@@ -216,5 +216,7 @@ namespace AzToolsFramework
|
||||
Prefab::PrefabLoaderInterface* m_loaderInterface;
|
||||
AzFramework::EntityContextId m_entityContextId;
|
||||
AZ::SerializeContext m_serializeContext;
|
||||
|
||||
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
|
||||
};
|
||||
}
|
||||
|
||||
+7
-2
@@ -83,7 +83,7 @@ namespace AzToolsFramework
|
||||
protected:
|
||||
QWidget* GetFirstInTabOrder() override;
|
||||
QWidget* GetLastInTabOrder() override;
|
||||
void UpdateTabOrder() override;
|
||||
void UpdateTabOrder() override;
|
||||
|
||||
void onChildComboBoxValueChange(int comboBoxIndex) override;
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace AzToolsFramework
|
||||
|
||||
void addElementImpl(const AZStd::pair<T, AZStd::string>& genericValue);
|
||||
|
||||
QLabel* m_warningLabel = nullptr;
|
||||
QLabel* m_warningLabel = nullptr;
|
||||
DHQComboBox* m_pComboBox;
|
||||
AZStd::vector<AZStd::pair<T, AZStd::string>> m_values;
|
||||
AZ::AttributeFunction <void(const T&)>* m_postChangeNotifyCB{};
|
||||
@@ -131,6 +131,11 @@ namespace AzToolsFramework
|
||||
template<typename T>
|
||||
AzToolsFramework::PropertyHandlerBase* RegisterGenericComboBoxHandler()
|
||||
{
|
||||
if (!AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto propertyHandler = aznew GenericComboBoxHandler<T>();
|
||||
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, propertyHandler);
|
||||
return propertyHandler;
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ function Process(context)
|
||||
local shadowMap = context:GetShaderByTag("Shadowmap")
|
||||
local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS")
|
||||
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
|
||||
local shadowMapWitPS = context:GetShaderByTag("Shadowmap_WithPS")
|
||||
local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
|
||||
local forwardPass = context:GetShaderByTag("ForwardPass")
|
||||
|
||||
local shadingAffectsDepth = parallaxEnabled and parallaxPdoEnabled;
|
||||
@@ -34,6 +34,6 @@ function Process(context)
|
||||
forwardPassEDS:SetEnabled(not shadingAffectsDepth)
|
||||
|
||||
depthPassWithPS:SetEnabled(shadingAffectsDepth)
|
||||
shadowMapWitPS:SetEnabled(shadingAffectsDepth)
|
||||
shadowMapWithPS:SetEnabled(shadingAffectsDepth)
|
||||
forwardPass:SetEnabled(shadingAffectsDepth)
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ function Process(context)
|
||||
local lowEndForwardEDS = context:GetShaderByTag("LowEndForward_EDS")
|
||||
|
||||
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
|
||||
local shadowMapWitPS = context:GetShaderByTag("Shadowmap_WithPS")
|
||||
local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
|
||||
local forwardPass = context:GetShaderByTag("ForwardPass")
|
||||
local lowEndForward = context:GetShaderByTag("LowEndForward")
|
||||
|
||||
@@ -43,7 +43,7 @@ function Process(context)
|
||||
lowEndForwardEDS:SetEnabled(false)
|
||||
|
||||
depthPassWithPS:SetEnabled(true)
|
||||
shadowMapWitPS:SetEnabled(true)
|
||||
shadowMapWithPS:SetEnabled(true)
|
||||
forwardPass:SetEnabled(true)
|
||||
lowEndForward:SetEnabled(true)
|
||||
else
|
||||
@@ -53,7 +53,7 @@ function Process(context)
|
||||
lowEndForwardEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
|
||||
|
||||
depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
|
||||
shadowMapWitPS:SetEnabled(opacityMode == OpacityMode_Cutout)
|
||||
shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
|
||||
forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout)
|
||||
lowEndForward:SetEnabled(opacityMode == OpacityMode_Cutout)
|
||||
end
|
||||
|
||||
+11
-1
@@ -203,7 +203,7 @@ namespace AZ
|
||||
if (m_shadowingLightHandle.IsValid())
|
||||
{
|
||||
uint32_t shadowFilterMethod = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_shadowFilterMethod;
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(AZ::Name{"o_directional_shadow_filtering_method"}, AZ::RPI::ShaderOptionValue{shadowFilterMethod});
|
||||
RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_directionalShadowFilteringMethodName, AZ::RPI::ShaderOptionValue{shadowFilterMethod});
|
||||
|
||||
const uint32_t cascadeCount = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_cascadeCount;
|
||||
ShadowProperty& property = m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex());
|
||||
@@ -656,6 +656,7 @@ namespace AZ
|
||||
CacheRenderPipelineIdsForPersistentView();
|
||||
SetConfigurationToPasses();
|
||||
SetCameraViewNameToPass();
|
||||
UpdateViewsOfCascadeSegments();
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::CacheCascadedShadowmapsPass() {
|
||||
@@ -1344,6 +1345,15 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void DirectionalLightFeatureProcessor::UpdateViewsOfCascadeSegments()
|
||||
{
|
||||
if (m_shadowingLightHandle.IsValid())
|
||||
{
|
||||
const uint16_t cascadeCount = GetCascadeCount(m_shadowingLightHandle);
|
||||
UpdateViewsOfCascadeSegments(m_shadowingLightHandle, cascadeCount);
|
||||
}
|
||||
}
|
||||
|
||||
Aabb DirectionalLightFeatureProcessor::CalculateShadowViewAabb(
|
||||
LightHandle handle,
|
||||
const RPI::View* cameraView,
|
||||
|
||||
@@ -296,6 +296,8 @@ namespace AZ
|
||||
//! This updates the shadowmap view.
|
||||
void UpdateShadowmapViews(LightHandle handle);
|
||||
|
||||
void UpdateViewsOfCascadeSegments();
|
||||
|
||||
//! This calculate shadow view AABB.
|
||||
Aabb CalculateShadowViewAabb(
|
||||
LightHandle handle,
|
||||
@@ -372,6 +374,7 @@ namespace AZ
|
||||
uint32_t m_shadowmapIndexTableBufferNameIndex = 0;
|
||||
|
||||
Name m_lightTypeName = Name("directional");
|
||||
Name m_directionalShadowFilteringMethodName = Name("o_directional_shadow_filtering_method");
|
||||
static constexpr const char* FeatureProcessorName = "DirectionalLightFeatureProcessor";
|
||||
};
|
||||
} // namespace Render
|
||||
|
||||
@@ -890,7 +890,7 @@ namespace EMotionFX
|
||||
#if AZ_TRAIT_EMOTIONFX_MAIN_WINDOW_DETACHED
|
||||
emotionFXWindowOptions.detachedWindow = true;
|
||||
#endif
|
||||
emotionFXWindowOptions.optionalMenuText = "Animation Editor (PREVIEW)";
|
||||
emotionFXWindowOptions.optionalMenuText = "Animation Editor";
|
||||
EditorRequests::Bus::Broadcast(&EditorRequests::RegisterViewPane, EMStudio::MainWindow::GetEMotionFXPaneName(), LyViewPane::CategoryTools, emotionFXWindowOptions, windowCreationFunc);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Gem::LyShine.Static
|
||||
Legacy::CryCommon
|
||||
Gem::LmbrCentral
|
||||
Gem::TextureAtlas
|
||||
Gem::TextureAtlas.Editor
|
||||
Gem::AtomToolsFramework.Static
|
||||
Gem::AtomToolsFramework.Editor
|
||||
${additional_dependencies}
|
||||
@@ -118,10 +118,10 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AZ::AssetBuilderSDK
|
||||
Gem::LyShine.Editor.Static
|
||||
Gem::LmbrCentral
|
||||
Gem::TextureAtlas
|
||||
Gem::TextureAtlas.Editor
|
||||
RUNTIME_DEPENDENCIES
|
||||
Gem::LmbrCentral.Editor
|
||||
Gem::TextureAtlas
|
||||
Gem::TextureAtlas.Editor
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -176,7 +176,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
Legacy::CryCommon
|
||||
AZ::AssetBuilderSDK
|
||||
Gem::LmbrCentral
|
||||
Gem::TextureAtlas
|
||||
Gem::TextureAtlas.Editor
|
||||
Gem::LyShine.Editor.Static
|
||||
)
|
||||
ly_add_googletest(
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "RenderGraph.h"
|
||||
|
||||
#include <AtomLyIntegration/AtomFont/FFont.h>
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -1076,7 +1077,7 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
|
||||
{
|
||||
m_filepath = texturePathname;
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, m_filepath);
|
||||
m_texture = nullptr;
|
||||
m_texture.reset();
|
||||
m_size = AZ::Vector2(0.0f, 0.0f);
|
||||
m_vAlign = vAlign;
|
||||
m_yOffset = yOffset;
|
||||
@@ -1094,24 +1095,11 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
|
||||
else
|
||||
{
|
||||
// Load the texture
|
||||
uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
|
||||
ITexture* texture = gEnv->pRenderer->EF_LoadTexture(texturePathname.c_str(), loadTextureFlags);
|
||||
|
||||
if (!texture || !texture->IsTextureLoaded())
|
||||
m_texture = CDraw2d::LoadTexture(m_filepath);
|
||||
if (m_texture)
|
||||
{
|
||||
gEnv->pSystem->Warning(
|
||||
VALIDATOR_MODULE_SHINE,
|
||||
VALIDATOR_WARNING,
|
||||
VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
|
||||
texturePathname.c_str(),
|
||||
"No texture file found for image: %s. "
|
||||
"NOTE: File must be in current project or a gem.",
|
||||
texturePathname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_texture = texture;
|
||||
m_size = AZ::Vector2(static_cast<float>(m_texture->GetWidth()), static_cast<float>(m_texture->GetHeight()));
|
||||
AZ::RHI::Size size = m_texture->GetDescriptor().m_size;
|
||||
m_size = AZ::Vector2(size.m_width, size.m_height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,17 +1115,6 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
UiTextComponent::InlineImage::~InlineImage()
|
||||
{
|
||||
// In order to avoid the texture being deleted while there are still commands on the render
|
||||
// thread command queue that use it, we queue a command to delete the texture onto the
|
||||
// command queue.
|
||||
|
||||
if (m_texture && !m_atlas)
|
||||
{
|
||||
SResourceAsync* pInfo = new SResourceAsync();
|
||||
pInfo->eClassName = eRCN_Texture;
|
||||
pInfo->pResource = m_texture;
|
||||
gEnv->pRenderer->ReleaseResourceAsync(pInfo);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1148,13 +1125,6 @@ bool UiTextComponent::InlineImage::OnAtlasLoaded(const TextureAtlasNamespace::Te
|
||||
m_coordinates = atlas->GetAtlasCoordinates(m_filepath);
|
||||
if (m_coordinates.GetWidth() > 0)
|
||||
{
|
||||
if (m_texture)
|
||||
{
|
||||
SResourceAsync* pInfo = new SResourceAsync();
|
||||
pInfo->eClassName = eRCN_Texture;
|
||||
pInfo->pResource = m_texture;
|
||||
gEnv->pRenderer->ReleaseResourceAsync(pInfo);
|
||||
}
|
||||
m_atlas = atlas;
|
||||
m_texture = m_atlas->GetTexture();
|
||||
return true;
|
||||
@@ -1177,25 +1147,7 @@ bool UiTextComponent::InlineImage::OnAtlasUnloaded(const TextureAtlasNamespace::
|
||||
else
|
||||
{
|
||||
// Load the texture
|
||||
uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
|
||||
ITexture* texture = gEnv->pRenderer->EF_LoadTexture(m_filepath.c_str(), loadTextureFlags);
|
||||
|
||||
if (!texture || !texture->IsTextureLoaded())
|
||||
{
|
||||
gEnv->pSystem->Warning(
|
||||
VALIDATOR_MODULE_SHINE,
|
||||
VALIDATOR_WARNING,
|
||||
VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
|
||||
m_filepath.c_str(),
|
||||
"No texture file found for image: %s. "
|
||||
"NOTE: File must be in current project or a gem.",
|
||||
m_filepath.c_str());
|
||||
m_texture = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_texture = texture;
|
||||
}
|
||||
m_texture = CDraw2d::LoadTexture(m_filepath);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1869,7 +1821,7 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
|
||||
UiTransformInterface::RectPointsArray rectPoints;
|
||||
GetTextBoundingBoxPrivate(GetDrawBatchLines(), m_selectionStart, m_selectionEnd, rectPoints);
|
||||
|
||||
ITexture* whiteTexture = gEnv->pRenderer->GetWhiteTexture();
|
||||
auto systemImage = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White);
|
||||
bool isClampTextureMode = true;
|
||||
|
||||
uint32 packedColor = (m_textSelectionColor.GetA8() << 24) | (m_textSelectionColor.GetR8() << 16) | (m_textSelectionColor.GetG8() << 8) | m_textSelectionColor.GetB8();
|
||||
@@ -1878,7 +1830,12 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
|
||||
{
|
||||
IRenderer::DynUiPrimitive* primitive = renderGraph->GetDynamicQuadPrimitive(rect.pt, packedColor);
|
||||
primitive->m_next = nullptr;
|
||||
renderGraph->AddPrimitive(primitive, whiteTexture, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
|
||||
LyShine::RenderGraph* lyRenderGraph = dynamic_cast<LyShine::RenderGraph*>(renderGraph);
|
||||
if (lyRenderGraph)
|
||||
{
|
||||
lyRenderGraph->AddPrimitiveAtom(primitive, systemImage, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1887,21 +1844,25 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
|
||||
{
|
||||
for (auto batch : m_renderCache.m_imageBatches)
|
||||
{
|
||||
ITexture* texture = batch->m_texture;
|
||||
AZ::Data::Instance<AZ::RPI::Image> texture = batch->m_texture;
|
||||
|
||||
// If the fade value has changed we need to update the alpha values in the vertex colors but we do
|
||||
// not want to touch or recompute the RGB values
|
||||
if (batch->m_cachedPrimitive.m_vertices[0].color.a != finalAlphaByte)
|
||||
{
|
||||
for (int i=0; i < 4; ++i)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
batch->m_cachedPrimitive.m_vertices[i].color.a = finalAlphaByte;
|
||||
}
|
||||
}
|
||||
|
||||
bool isClampTextureMode = true;
|
||||
renderGraph->AddPrimitive(&batch->m_cachedPrimitive, texture,
|
||||
isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
LyShine::RenderGraph* lyRenderGraph = dynamic_cast<LyShine::RenderGraph*>(renderGraph);
|
||||
if (lyRenderGraph)
|
||||
{
|
||||
lyRenderGraph->AddPrimitiveAtom(&batch->m_cachedPrimitive, texture,
|
||||
isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,14 @@
|
||||
#include <LyShine/Bus/UiLayoutCellDefaultBus.h>
|
||||
#include <LyShine/Bus/UiElementBus.h>
|
||||
#include <LyShine/Bus/UiCanvasBus.h>
|
||||
#include <LyShine/Bus/UiAnimateEntityBus.h>
|
||||
#include <LyShine/UiAssetTypes.h>
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <LyShine/Bus/UiAnimateEntityBus.h>
|
||||
|
||||
#include <LyShine/UiAssetTypes.h>
|
||||
#include <Atom/RPI.Reflect/Image/Image.h>
|
||||
|
||||
// Only needed for internal unit-testing
|
||||
#include <LyShine.h>
|
||||
@@ -91,7 +92,7 @@ public: //types
|
||||
bool OnAtlasLoaded(const TextureAtlasNamespace::TextureAtlas* atlas);
|
||||
bool OnAtlasUnloaded(const TextureAtlasNamespace::TextureAtlas* atlas);
|
||||
|
||||
ITexture* m_texture;
|
||||
AZ::Data::Instance<AZ::RPI::Image> m_texture;
|
||||
AZ::Vector2 m_size;
|
||||
VAlign m_vAlign;
|
||||
float m_yOffset;
|
||||
@@ -616,8 +617,8 @@ private: // types
|
||||
|
||||
struct RenderCacheImageBatch
|
||||
{
|
||||
ITexture* m_texture;
|
||||
IRenderer::DynUiPrimitive m_cachedPrimitive;
|
||||
AZ::Data::Instance<AZ::RPI::Image> m_texture;
|
||||
IRenderer::DynUiPrimitive m_cachedPrimitive;
|
||||
};
|
||||
|
||||
struct RenderCacheData
|
||||
|
||||
@@ -1450,13 +1450,17 @@ void UiTextInputComponent::CheckStartTextInput()
|
||||
EBUS_EVENT_ID_RESULT(textString, m_textEntity, UiTextBus, GetText);
|
||||
options.m_initialText = Utf8SubString(textString, m_textCursorPos, m_textSelectionStartPos);
|
||||
|
||||
AZ::EntityId canvasEntityId;
|
||||
EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId);
|
||||
|
||||
// Calculate height available for virtual keyboard. In game mode, canvas size is the same as viewport size
|
||||
AZ::Vector2 canvasSize;
|
||||
EBUS_EVENT_ID_RESULT(canvasSize, canvasEntityId, UiCanvasBus, GetCanvasSize);
|
||||
UiTransformInterface::RectPoints rectPoints;
|
||||
EBUS_EVENT_ID(GetEntityId(), UiTransformBus, GetViewportSpacePoints, rectPoints);
|
||||
const AZ::Vector2 bottomRight = rectPoints.GetAxisAlignedBottomRight();
|
||||
options.m_normalizedMinY = bottomRight.GetY() / static_cast<float>(gEnv->pRenderer->GetHeight());
|
||||
options.m_normalizedMinY = (canvasSize.GetY() > 0.0f) ? bottomRight.GetY() / canvasSize.GetY() : 0.0f;
|
||||
|
||||
AZ::EntityId canvasEntityId;
|
||||
EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId);
|
||||
EBUS_EVENT_ID_RESULT(options.m_localUserId, canvasEntityId, UiCanvasBus, GetLocalUserIdInputFilter);
|
||||
|
||||
AzFramework::InputTextEntryRequestBus::Broadcast(&AzFramework::InputTextEntryRequests::TextEntryStart, options);
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>>& outSlotIdMap)
|
||||
bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
|
||||
{
|
||||
auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector<const ScriptCanvas::Slot*>& newSlots)->ScriptCanvas::SlotId
|
||||
{
|
||||
@@ -529,14 +529,14 @@ namespace ScriptCanvasEditor
|
||||
return {};
|
||||
};
|
||||
|
||||
oldNode->CustomizeReplacementNode(newNode, outSlotIdMap);
|
||||
|
||||
if (!newNode)
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Replacement node can not be null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
oldNode->CustomizeReplacementNode(newNode, nodeUpdateSlotReport.m_oldSlotsToNewSlots);
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> slotNameMap = oldNode->GetReplacementSlotsMap();
|
||||
|
||||
const auto newSlots = newNode->GetAllSlots();
|
||||
@@ -544,16 +544,19 @@ namespace ScriptCanvasEditor
|
||||
bool usingDefaults = true;
|
||||
size_t defaultMatchesFound = 0;
|
||||
|
||||
auto& oldSlotsToNewSlots = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
|
||||
|
||||
for (auto oldSlot : oldSlots)
|
||||
{
|
||||
const ScriptCanvas::SlotId oldSlotId = oldSlot->GetId();
|
||||
const AZStd::string oldSlotName = oldSlot->GetName();
|
||||
auto slotIdsIter = outSlotIdMap.find(oldSlotId);
|
||||
|
||||
auto slotIdsIter = oldSlotsToNewSlots.find(oldSlotId);
|
||||
auto slotNamesIter = slotNameMap.find(oldSlotName);
|
||||
// For old node slot remapping, we should get:
|
||||
// 1. if old slot name is not static, we should find the mapping in user provided slot id map
|
||||
// 2. if old slot name is static, we should find the mapping in codegen generated map (case 1 can override case 2)
|
||||
if (slotIdsIter != outSlotIdMap.end())
|
||||
if (slotIdsIter != oldSlotsToNewSlots.end())
|
||||
{
|
||||
for (auto newSlotId : slotIdsIter->second)
|
||||
{
|
||||
@@ -581,9 +584,10 @@ namespace ScriptCanvasEditor
|
||||
if (!newSlotName.empty())
|
||||
{
|
||||
auto newSlot = newNode->GetSlotByName(newSlotName);
|
||||
|
||||
if (!newSlot)
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node(%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
|
||||
AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node (%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
|
||||
return false;
|
||||
}
|
||||
else if (newSlot && oldSlot->GetType() != newSlot->GetType())
|
||||
@@ -591,10 +595,11 @@ namespace ScriptCanvasEditor
|
||||
AZ_Warning("ScriptCanvas", false, "Failed to map deprecated Node (%s) Slot (%s) to replacement Node (%s) Slot (%s).", oldNode->GetNodeName().c_str(), oldSlot->GetName().c_str(), newNode->GetNodeName().c_str(), newSlot->GetName().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
newSlotIds.push_back(newSlot->GetId());
|
||||
}
|
||||
}
|
||||
outSlotIdMap.emplace(oldSlot->GetId(), newSlotIds);
|
||||
oldSlotsToNewSlots.emplace(oldSlot->GetId(), newSlotIds);
|
||||
}
|
||||
else if (slotNameMap.empty())
|
||||
{
|
||||
@@ -605,7 +610,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
++defaultMatchesFound;
|
||||
AZStd::vector<ScriptCanvas::SlotId> slotIds{ newSlotId };
|
||||
outSlotIdMap.emplace(oldSlot->GetId(), slotIds);
|
||||
oldSlotsToNewSlots.emplace(oldSlot->GetId(), slotIds);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -615,7 +620,7 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
if (usingDefaults && defaultMatchesFound != oldSlots.size())
|
||||
if (usingDefaults && oldSlotsToNewSlots.size() != oldSlots.size())
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) not all old slots were present in the new node.", oldNode->GetNodeName().c_str());
|
||||
}
|
||||
@@ -690,8 +695,10 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Outcome<ScriptCanvas::Node*> Graph::ReplaceNodeByConfig(ScriptCanvas::Node* oldNode, const ScriptCanvas::NodeConfiguration& nodeConfig,
|
||||
ScriptCanvas::ReplacementConnectionMap& remapConnections)
|
||||
AZ::Outcome<ScriptCanvas::Node*> Graph::ReplaceNodeByConfig
|
||||
( ScriptCanvas::Node* oldNode
|
||||
, const ScriptCanvas::NodeConfiguration& nodeConfig
|
||||
, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
|
||||
{
|
||||
auto nodeEntity = oldNode->GetEntity();
|
||||
if (!nodeEntity)
|
||||
@@ -731,8 +738,8 @@ namespace ScriptCanvasEditor
|
||||
AddNode(newNode->GetEntityId());
|
||||
ScriptCanvas::NodeUtils::InitializeNode(newNode, nodeConfig);
|
||||
|
||||
AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>> slotIdMap;
|
||||
rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, slotIdMap);
|
||||
rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, nodeUpdateSlotReport);
|
||||
auto& slotIdMap = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
|
||||
|
||||
if (rollbackRequired)
|
||||
{
|
||||
@@ -748,25 +755,15 @@ namespace ScriptCanvasEditor
|
||||
else
|
||||
{
|
||||
nodeEntity->Activate();
|
||||
|
||||
newNode->SignalReconfigurationBegin();
|
||||
|
||||
newNode->SetNodeDisabledFlag(oldNode->GetNodeDisabledFlag());
|
||||
|
||||
for (auto slotIdIter : slotIdMap)
|
||||
{
|
||||
ScriptCanvas::Slot* oldSlot = oldNode->GetSlot(slotIdIter.first);
|
||||
const ScriptCanvas::Endpoint oldEndpoint{ nodeEntity->GetId(), oldSlot->GetId() };
|
||||
if (slotIdIter.second.size() == 0)
|
||||
{
|
||||
// If remap id is empty, then we should just cache the old slot connection for delete
|
||||
if (oldSlot->IsInput())
|
||||
{
|
||||
ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -808,35 +805,11 @@ namespace ScriptCanvasEditor
|
||||
|
||||
ScriptCanvas::VersioningUtils::CopyOldValueToDataSlot(newSlot, oldSlot->GetVariableReference(), oldSlot->FindDatum());
|
||||
}
|
||||
|
||||
// if old slot is visible, we need to check its connections for remapping
|
||||
if (oldSlot->IsVisible())
|
||||
{
|
||||
ScriptCanvas::Endpoint newEndpoint;
|
||||
if (newSlot)
|
||||
{
|
||||
newEndpoint = { nodeEntity->GetId(), newSlot->GetId() };
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "Invalid slot! Unable to create new connection for Node (%s).", newNode->GetNodeName().c_str());
|
||||
}
|
||||
|
||||
if (oldSlot->IsInput())
|
||||
{
|
||||
ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete oldNode;
|
||||
|
||||
newNode->SignalReconfigurationEnd();
|
||||
|
||||
return AZ::Success(newNode);
|
||||
}
|
||||
}
|
||||
@@ -3634,8 +3607,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > scriptCanvasToGraphCanvasMapping;
|
||||
|
||||
bool graphNeedsDirtying = false;
|
||||
|
||||
bool graphNeedsDirtying = !GetVersion().IsLatest();
|
||||
{
|
||||
QScopedValueRollback<bool> ignoreRequests(m_ignoreSaveRequests, true);
|
||||
|
||||
@@ -3659,7 +3631,8 @@ namespace ScriptCanvasEditor
|
||||
AZStd::unordered_set<AZ::EntityId> deletedNodes;
|
||||
AZStd::unordered_set<AZ::EntityId> assetSanitizationSet;
|
||||
AZStd::unordered_set<ScriptCanvas::Node*> sanityCheckRequiredNodes;
|
||||
ScriptCanvas::ReplacementConnectionMap remapConnections;
|
||||
|
||||
ScriptCanvas::GraphUpdateSlotReport graphUpdateSlotReport;
|
||||
|
||||
for (const AZ::EntityId& scriptCanvasNodeId : nodeList)
|
||||
{
|
||||
@@ -3674,12 +3647,15 @@ namespace ScriptCanvasEditor
|
||||
ScriptCanvas::NodeConfiguration nodeConfig = scriptCanvasNode->GetReplacementNodeConfiguration();
|
||||
if (nodeConfig.IsValid())
|
||||
{
|
||||
auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, remapConnections);
|
||||
ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
|
||||
auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, nodeUpdateSlotReport);
|
||||
|
||||
if (nodeOutcome.IsSuccess())
|
||||
{
|
||||
graphNeedsDirtying = true;
|
||||
scriptCanvasNode = nodeOutcome.GetValue();
|
||||
m_updateStrings.insert(AZStd::string::format("Replaced node (%s)", scriptCanvasNode->GetNodeName().c_str()));
|
||||
ScriptCanvas::MergeUpdateSlotReport(scriptCanvasNodeId, graphUpdateSlotReport, nodeUpdateSlotReport);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3688,7 +3664,6 @@ namespace ScriptCanvasEditor
|
||||
scriptCanvasToGraphCanvasMapping[scriptCanvasNodeId] = graphCanvasNodeId;
|
||||
|
||||
auto saveDataIter2 = m_graphCanvasSaveData.find(scriptCanvasNodeId);
|
||||
|
||||
if (saveDataIter2 != m_graphCanvasSaveData.end())
|
||||
{
|
||||
GraphCanvas::EntitySaveDataRequestBus::Event(graphCanvasNodeId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter2->second));
|
||||
@@ -3699,7 +3674,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, position, false);
|
||||
|
||||
// If the node is deprecated, we want to stomp whatever style it had saved and apply the deperecated style
|
||||
// If the node is deprecated, we want to stomp whatever style it had saved and apply the deprecated style
|
||||
if (scriptCanvasNode->IsDeprecated())
|
||||
{
|
||||
GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, "DeprecatedNodeTitlePalette");
|
||||
@@ -3719,27 +3694,13 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
// Remap connections step should be done before editor processing connections for graph
|
||||
//
|
||||
// Delete underlying data conenections.
|
||||
for (auto remapConnection : remapConnections)
|
||||
if (!graphUpdateSlotReport.IsEmpty())
|
||||
{
|
||||
RemoveConnection(remapConnection.first);
|
||||
// currently, it is expected that there are no deleted old slots, those need manual correction
|
||||
AZ_Error("ScriptCanvas", graphUpdateSlotReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required");
|
||||
UpdateConnectionStatus(*this, graphUpdateSlotReport);
|
||||
}
|
||||
|
||||
// Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
|
||||
for (auto remapConnection : remapConnections)
|
||||
{
|
||||
for (auto newEndpointPair : remapConnection.second)
|
||||
{
|
||||
if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
|
||||
{
|
||||
ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
////
|
||||
|
||||
AZStd::unordered_set<AZ::EntityId> graphCanvasNodesToDelete;
|
||||
|
||||
for (auto scriptCanvasNode : outOfDateNodes)
|
||||
|
||||
@@ -424,24 +424,11 @@ namespace ScriptCanvasEditor
|
||||
EditorGraphUpgradeMachine* sm = GetStateMachine<EditorGraphUpgradeMachine>();
|
||||
auto* graph = sm->m_graph;
|
||||
|
||||
// Delete underlying data connections.
|
||||
for (auto remapConnection : sm->m_replacementConnections)
|
||||
if (!sm->m_updateReport.IsEmpty())
|
||||
{
|
||||
graph->RemoveConnection(remapConnection.first);
|
||||
}
|
||||
|
||||
// Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
|
||||
for (auto remapConnection : sm->m_replacementConnections)
|
||||
{
|
||||
for (auto newEndpointPair : remapConnection.second)
|
||||
{
|
||||
if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
|
||||
{
|
||||
graph->ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
|
||||
|
||||
Log("Replaced Connection: %s\n", Helpers::ConnectionToText(graph, newEndpointPair.first, newEndpointPair.second).c_str());
|
||||
}
|
||||
}
|
||||
// currently, it is expected that there are no deleted old slots, those need manual correction
|
||||
AZ_Error("ScriptCanvas", sm->m_updateReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required");
|
||||
UpdateConnectionStatus(*graph, sm->m_updateReport);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,16 +442,18 @@ namespace ScriptCanvasEditor
|
||||
ScriptCanvas::NodeConfiguration nodeConfig = node->GetReplacementNodeConfiguration();
|
||||
if (nodeConfig.IsValid())
|
||||
{
|
||||
auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, sm->m_replacementConnections);
|
||||
ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
|
||||
auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, nodeUpdateSlotReport);
|
||||
if (nodeOutcome.IsSuccess())
|
||||
{
|
||||
ScriptCanvas::MergeUpdateSlotReport(node->GetEntityId(), sm->m_updateReport, nodeUpdateSlotReport);
|
||||
|
||||
sm->m_allNodes.erase(node);
|
||||
sm->m_outOfDateNodes.erase(node);
|
||||
sm->m_sanityCheckRequiredNodes.erase(node);
|
||||
|
||||
sm->m_graphNeedsDirtying = true;
|
||||
auto replacedNode = nodeOutcome.GetValue();
|
||||
|
||||
auto replacedNode = nodeOutcome.GetValue();
|
||||
sm->m_allNodes.insert(replacedNode);
|
||||
|
||||
if (replacedNode->IsOutOfDate(graph->GetVersion()))
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
struct NodeConfiguration;
|
||||
struct NodeUpdateSlotReport;
|
||||
}
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
@@ -361,8 +362,8 @@ namespace ScriptCanvasEditor
|
||||
void HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId);
|
||||
|
||||
//// Version Update code
|
||||
AZ::Outcome<ScriptCanvas::Node*> ReplaceNodeByConfig(ScriptCanvas::Node*, const ScriptCanvas::NodeConfiguration&, ScriptCanvas::ReplacementConnectionMap&);
|
||||
bool SanityCheckNodeReplacement(ScriptCanvas::Node*, ScriptCanvas::Node*, AZStd::unordered_map<ScriptCanvas::SlotId, AZStd::vector<ScriptCanvas::SlotId>>&);
|
||||
AZ::Outcome<ScriptCanvas::Node*> ReplaceNodeByConfig(ScriptCanvas::Node*, const ScriptCanvas::NodeConfiguration&, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport);
|
||||
bool SanityCheckNodeReplacement(ScriptCanvas::Node*, ScriptCanvas::Node*, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport);
|
||||
|
||||
bool m_allowVersionUpdate = false;
|
||||
AZStd::unordered_set< AZ::EntityId > m_queuedConvertingNodes;
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
AZStd::unordered_set<AZ::EntityId> m_deletedNodes;
|
||||
AZStd::unordered_set<AZ::EntityId> m_assetSanitizationSet;
|
||||
ScriptCanvas::ReplacementConnectionMap m_replacementConnections;
|
||||
ScriptCanvas::GraphUpdateSlotReport m_updateReport;
|
||||
|
||||
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > m_scriptCanvasToGraphCanvasMapping;
|
||||
|
||||
|
||||
+5
@@ -123,6 +123,11 @@ namespace ScriptCanvasEditor
|
||||
template<typename T>
|
||||
AzToolsFramework::PropertyHandlerBase* RegisterGenericLineEditHandler(const EditCtrl::PropertyToStringCB<T>& propertyToStringCB, const EditCtrl::StringToPropertyCB<T>& stringToPropertyCB)
|
||||
{
|
||||
if (!AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto propertyHandler(aznew GenericLineEditHandler<T>(propertyToStringCB, stringToPropertyCB));
|
||||
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, propertyHandler);
|
||||
return propertyHandler;
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ public: \
|
||||
void ConfigureSlots() override; \
|
||||
bool RequiresDynamicSlotOrdering() const override; \
|
||||
bool IsDeprecated() const override; \
|
||||
{% if deprecationUuid is defined %} NodeConfiguration GetReplacementNodeConfiguration() const override; \
|
||||
{% if deprecationUuid is defined %} ScriptCanvas::NodeConfiguration GetReplacementNodeConfiguration() const override; \
|
||||
{% endif %}
|
||||
using Node::FindDatum; \
|
||||
{% if Class.attrib['GraphEntryPoint'] is defined %} bool IsEntryPoint() const override { return {%if Class.attrib['GraphEntryPoint'] == "True" %}true{%else%}false{%endif%}; } \
|
||||
@@ -168,4 +168,4 @@ struct {{ className | replace(' ','') }}Property
|
||||
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
@@ -22,6 +22,7 @@
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
class Slot;
|
||||
struct NodeUpdateSlotReport;
|
||||
|
||||
class Connection
|
||||
: public AZ::Component
|
||||
@@ -64,6 +65,8 @@ namespace ScriptCanvas
|
||||
// GraphNotificationBus
|
||||
void OnNodeRemoved(const ID& nodeId) override;
|
||||
|
||||
void UpdateConnectionStatus(NodeUpdateSlotReport& report);
|
||||
|
||||
protected:
|
||||
//-------------------------------------------------------------------------
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
|
||||
+15
-12
@@ -33,7 +33,7 @@ namespace ScriptCanvas
|
||||
{
|
||||
if (m_availableIndexes.empty())
|
||||
{
|
||||
return -1;
|
||||
return std::numeric_limits<AZ::u32>::max();
|
||||
}
|
||||
|
||||
return (*m_availableIndexes.begin());
|
||||
@@ -151,19 +151,22 @@ namespace ScriptCanvas
|
||||
|
||||
for (const AZ::BehaviorParameter* behaviorParameter : paramTypes.second)
|
||||
{
|
||||
ScriptCanvas::Data::Type dataType = ScriptCanvas::Data::FromAZType(behaviorParameter->m_typeId);
|
||||
if (ScriptCanvas::Data::IsValueType(dataType))
|
||||
if (behaviorParameter)
|
||||
{
|
||||
isValueType = true;
|
||||
}
|
||||
else if (ScriptCanvas::Data::IsContainerType(dataType))
|
||||
{
|
||||
isContainerType = true;
|
||||
}
|
||||
ScriptCanvas::Data::Type dataType = ScriptCanvas::Data::FromAZType(behaviorParameter->m_typeId);
|
||||
if (ScriptCanvas::Data::IsValueType(dataType))
|
||||
{
|
||||
isValueType = true;
|
||||
}
|
||||
else if (ScriptCanvas::Data::IsContainerType(dataType))
|
||||
{
|
||||
isContainerType = true;
|
||||
}
|
||||
|
||||
if (isValueType && isContainerType)
|
||||
{
|
||||
break;
|
||||
if (isValueType && isContainerType)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -616,6 +616,34 @@ namespace ScriptCanvas
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Graph::RemoveAllConnections()
|
||||
{
|
||||
for (auto connectionEntity : m_graphData.m_connections)
|
||||
{
|
||||
if (auto connection = connectionEntity ? AZ::EntityUtils::FindFirstDerivedComponent<Connection>(connectionEntity) : nullptr)
|
||||
{
|
||||
if (connection->GetSourceEndpoint().IsValid())
|
||||
{
|
||||
EndpointNotificationBus::Event(connection->GetSourceEndpoint(), &EndpointNotifications::OnEndpointDisconnected, connection->GetTargetEndpoint());
|
||||
}
|
||||
if (connection->GetTargetEndpoint().IsValid())
|
||||
{
|
||||
EndpointNotificationBus::Event(connection->GetTargetEndpoint(), &EndpointNotifications::OnEndpointDisconnected, connection->GetSourceEndpoint());
|
||||
}
|
||||
}
|
||||
|
||||
GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnConnectionRemoved, connectionEntity->GetId());
|
||||
}
|
||||
|
||||
for (auto& connectionRef : m_graphData.m_connections)
|
||||
{
|
||||
delete connectionRef;
|
||||
}
|
||||
|
||||
m_graphData.m_connections.clear();
|
||||
}
|
||||
|
||||
bool Graph::RemoveConnection(const AZ::EntityId& connectionId)
|
||||
{
|
||||
if (connectionId.IsValid())
|
||||
@@ -752,7 +780,6 @@ namespace ScriptCanvas
|
||||
auto* connectionEntity = aznew AZ::Entity("Connection");
|
||||
connectionEntity->CreateComponent<Connection>(sourceEndpoint, targetEndpoint);
|
||||
|
||||
|
||||
AZ::Entity* nodeEntity{};
|
||||
AZ::ComponentApplicationBus::BroadcastResult(nodeEntity, &AZ::ComponentApplicationRequests::FindEntity, sourceEndpoint.GetNodeId());
|
||||
auto node = nodeEntity ? AZ::EntityUtils::FindFirstDerivedComponent<Node>(nodeEntity) : nullptr;
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace ScriptCanvas
|
||||
Slot* FindSlot(const Endpoint& endpoint) const override;
|
||||
|
||||
bool AddConnection(const AZ::EntityId&) override;
|
||||
void RemoveAllConnections();
|
||||
bool RemoveConnection(const AZ::EntityId& connectionId) override;
|
||||
AZStd::vector<AZ::EntityId> GetConnections() const override;
|
||||
AZStd::vector<Endpoint> GetConnectedEndpoints(const Endpoint& firstEndpoint) const override;
|
||||
|
||||
@@ -53,7 +53,9 @@ namespace ScriptCanvas
|
||||
template<typename DatumType>
|
||||
void AddDefaultInputAndOutputTypeSlot(DatumType&& defaultValue);
|
||||
void AddInputTypeAndOutputTypeSlot(const Data::Type& type);
|
||||
|
||||
|
||||
bool IsDeprecated() const override { return true; }
|
||||
|
||||
void OnActivate() override;
|
||||
void OnInputChanged(const Datum& input, const SlotId& id) override;
|
||||
void MarkDefaultableInput() override {}
|
||||
|
||||
@@ -347,6 +347,11 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void Slot::ClearDynamicGroup()
|
||||
{
|
||||
m_dynamicGroup = AZ::Crc32{};
|
||||
}
|
||||
|
||||
void Slot::ConvertToLatentExecutionOut()
|
||||
{
|
||||
if (IsExecution() && IsOutput())
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace ScriptCanvas
|
||||
|
||||
void AddContract(const ContractDescriptor& contractDesc);
|
||||
|
||||
void ClearDynamicGroup();
|
||||
|
||||
template<typename T>
|
||||
T* FindContract()
|
||||
{
|
||||
|
||||
@@ -1036,12 +1036,12 @@ namespace ScriptCanvas
|
||||
if (azrtti_istypeof<ScriptCanvas::Nodes::NodeableNodeOverloaded*>(&node))
|
||||
{
|
||||
// todo Add node to these errors
|
||||
AddError(nullptr, ValidationConstPtr(aznew NotYetImplemented(node.GetEntityId(), AZStd::string::format("NodeableNodeOverloaded doesn't have enough data connected to select a valid overload: %s", node.GetDebugName().data()))));
|
||||
AddError(nullptr, ValidationConstPtr(aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("%s: %s", ParseErrors::NodeableNodeOverloadAmbiguous, node.GetDebugName().data()))));
|
||||
}
|
||||
else
|
||||
{
|
||||
// todo Add node to these errors
|
||||
AddError(nullptr, ValidationConstPtr(aznew NotYetImplemented(node.GetEntityId(), AZStd::string::format("NodeableNode did not construct its internal node: %s", node.GetDebugName().data()))));
|
||||
AddError(nullptr, ValidationConstPtr(aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("%s: %s", ParseErrors::NodeableNodeDidNotConstructInternalNodeable, node.GetDebugName().data()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2535,7 +2535,7 @@ namespace ScriptCanvas
|
||||
|
||||
if (IsInfiniteVariableWriteHandlingLoop(*this, variableHandling, variableHandling->m_function, true))
|
||||
{
|
||||
AddError(variableHandling->m_function, aznew NotYetImplemented(AZ::EntityId(), ScriptCanvas::ParseErrors::InfiniteLoopWritingToVariable));
|
||||
AddError(variableHandling->m_function, aznew Internal::ParseError(AZ::EntityId(), ScriptCanvas::ParseErrors::InfiniteLoopWritingToVariable));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3312,7 +3312,7 @@ namespace ScriptCanvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), childOutSlotsOutcome.TakeError()));
|
||||
AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), childOutSlotsOutcome.TakeError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3615,9 +3615,11 @@ namespace ScriptCanvas
|
||||
|
||||
void AbstractCodeModel::ParseExecutionMultipleOutSyntaxSugar(ExecutionTreePtr execution, const EndpointsResolved& executionOutNodes, const AZStd::vector<const Slot*>& outSlots)
|
||||
{
|
||||
const auto executionNodeId = execution->GetId().m_node ? execution->GetId().m_node->GetEntityId() : AZ::EntityId();
|
||||
|
||||
if (executionOutNodes.size() != outSlots.size())
|
||||
{
|
||||
AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarMismatchOutSize);
|
||||
AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarMismatchOutSize);
|
||||
}
|
||||
|
||||
if (execution->GetSymbol() != Symbol::Sequence)
|
||||
@@ -3630,13 +3632,13 @@ namespace ScriptCanvas
|
||||
|
||||
if (!child)
|
||||
{
|
||||
AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNullChildFound);
|
||||
AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNullChildFound);
|
||||
return;
|
||||
}
|
||||
|
||||
if (child->m_execution)
|
||||
{
|
||||
AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound);
|
||||
AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3660,7 +3662,7 @@ namespace ScriptCanvas
|
||||
|
||||
if (execution->GetChildrenCount() != executionOutNodes.size())
|
||||
{
|
||||
AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced);
|
||||
AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -4187,7 +4189,7 @@ namespace ScriptCanvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError(nullptr, aznew NotYetImplemented(execution->GetNodeId(), dataSlotsOutcome.TakeError()));
|
||||
AddError(nullptr, aznew Internal::ParseError(execution->GetNodeId(), dataSlotsOutcome.TakeError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4494,13 +4496,13 @@ namespace ScriptCanvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), returnSlotsOutcome.TakeError()));
|
||||
AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), returnSlotsOutcome.TakeError()));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), outputSlotsOutcome.TakeError()));
|
||||
AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), outputSlotsOutcome.TakeError()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,6 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> ArithmeticExpression::GetReplacementSlotsMap() const
|
||||
{
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> slotsMap;
|
||||
slotsMap.emplace(k_evaluateName, AZStd::vector<AZStd::string>{ "In" });
|
||||
slotsMap.emplace(k_outName, AZStd::vector<AZStd::string>{ "Out" });
|
||||
slotsMap.emplace(k_resultName, AZStd::vector<AZStd::string>{ "Result" });
|
||||
return slotsMap;
|
||||
}
|
||||
|
||||
void ArithmeticExpression::OnInit()
|
||||
{
|
||||
{
|
||||
|
||||
@@ -72,7 +72,6 @@ namespace ScriptCanvas
|
||||
|
||||
bool IsDeprecated() const override { return true; }
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> GetReplacementSlotsMap() const override;
|
||||
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -94,8 +94,6 @@ namespace ScriptCanvas
|
||||
|
||||
void ForEach::OnInit()
|
||||
{
|
||||
ResetLoop();
|
||||
|
||||
if (!m_sourceSlot.IsValid())
|
||||
{
|
||||
DynamicDataSlotConfiguration slotConfiguration;
|
||||
@@ -130,33 +128,6 @@ namespace ScriptCanvas
|
||||
EndpointNotificationBus::Handler::BusConnect({ GetEntityId(), m_sourceSlot });
|
||||
}
|
||||
|
||||
void ForEach::OnInputSignal(const SlotId& slotId)
|
||||
{
|
||||
auto inSlotId = ForEachProperty::GetInSlotId(this);
|
||||
if (slotId == inSlotId || slotId == SlotId{})
|
||||
{
|
||||
if (slotId == inSlotId)
|
||||
{
|
||||
if (!InitializeLoop())
|
||||
{
|
||||
// Loop initialization failed
|
||||
SignalOutput(ForEachProperty::GetFinishedSlotId(this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_breakCalled)
|
||||
{
|
||||
Iterate();
|
||||
}
|
||||
}
|
||||
else if (slotId == ForEachProperty::GetBreakSlotId(this))
|
||||
{
|
||||
m_breakCalled = true;
|
||||
SignalOutput(ForEachProperty::GetFinishedSlotId(this));
|
||||
}
|
||||
}
|
||||
|
||||
UpdateResult ForEach::OnUpdateNode()
|
||||
{
|
||||
if (auto continueSlot = GetSlotByNameAndType("Continue", CombinedSlotType::ExecutionIn))
|
||||
@@ -167,161 +138,6 @@ namespace ScriptCanvas
|
||||
return UpdateResult::DirtyGraph;
|
||||
}
|
||||
|
||||
bool ForEach::InitializeLoop()
|
||||
{
|
||||
ResetLoop();
|
||||
|
||||
const Datum* input = FindDatum(m_sourceSlot);
|
||||
|
||||
if (input && !input->Empty())
|
||||
{
|
||||
if (!Data::IsContainerType(input->GetType()))
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Iteration not supported on this type: %s", Data::GetName(m_sourceContainer.GetType()).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make a copy of the source datum
|
||||
m_sourceContainer = *input;
|
||||
|
||||
// Get the size of the container
|
||||
auto sizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_sourceContainer, "Size");
|
||||
|
||||
if (!sizeOutcome)
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of container: %s", sizeOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Datum sizeResult = sizeOutcome.TakeValue();
|
||||
const size_t* sizePtr = sizeResult.GetAs<size_t>();
|
||||
m_size = sizePtr ? *sizePtr : 0;
|
||||
|
||||
if (Data::IsSetContainerType(m_sourceContainer.GetType()) || Data::IsMapContainerType(m_sourceContainer.GetType()))
|
||||
{
|
||||
// If it's a map or set, get the vector of keys
|
||||
auto keysVectorOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_sourceContainer, "GetKeys");
|
||||
|
||||
if (!keysVectorOutcome)
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get vector of keys: %s", keysVectorOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_keysVector = keysVectorOutcome.TakeValue();
|
||||
|
||||
// Check size of vector of keys for safety
|
||||
auto keysSizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_keysVector, "Size");
|
||||
|
||||
if (!keysSizeOutcome)
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of vector of keys: %s", keysSizeOutcome.GetError().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
Datum keysSizeResult = keysSizeOutcome.TakeValue();
|
||||
const size_t* keysSizePtr = keysSizeResult.GetAs<size_t>();
|
||||
size_t keysSize = keysSizePtr ? *keysSizePtr : 0;
|
||||
|
||||
if (m_size != keysSize)
|
||||
{
|
||||
// This shouldn't happen
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Container size and vector of keys size mismatch.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ForEach::Iterate()
|
||||
{
|
||||
if (m_sourceContainer.Empty() || m_index >= m_size)
|
||||
{
|
||||
SignalOutput(ForEachProperty::GetFinishedSlotId(this));
|
||||
return;
|
||||
}
|
||||
|
||||
Datum& container = Data::IsVectorContainerType(m_sourceContainer.GetType()) ? m_sourceContainer : m_keysVector;
|
||||
|
||||
auto keyAtOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(container, "At", m_index);
|
||||
|
||||
if (!keyAtOutcome)
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get key in container: %s", keyAtOutcome.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
Datum keyAtResult = keyAtOutcome.TakeValue();
|
||||
|
||||
if (!SetPropertySlotData(keyAtResult, k_keySlotIndex))
|
||||
{
|
||||
// Unable to set property slot
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Unable to set one of the property slots on this node.");
|
||||
SignalOutput(ForEachProperty::GetFinishedSlotId(this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Data::IsMapContainerType(m_sourceContainer.GetType()))
|
||||
{
|
||||
// If the container is a map, we want to get the value for the current key
|
||||
auto valueAtOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(m_sourceContainer, "At", keyAtResult);
|
||||
|
||||
if (!valueAtOutcome)
|
||||
{
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get value for key in container: %s", valueAtOutcome.GetError().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
Datum valueAtResult = valueAtOutcome.TakeValue();
|
||||
|
||||
if (!SetPropertySlotData(valueAtResult, k_valueSlotIndex))
|
||||
{
|
||||
// Unable to set property slot
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Unable to set one of the property slots on this node.");
|
||||
SignalOutput(ForEachProperty::GetFinishedSlotId(this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
++m_index;
|
||||
|
||||
SignalOutput(ForEachProperty::GetEachSlotId(this));
|
||||
}
|
||||
|
||||
bool ForEach::SetPropertySlotData(Datum& atResult, size_t propertyIndex)
|
||||
{
|
||||
if (atResult.Empty())
|
||||
{
|
||||
// Something went wrong with the Behavior Context call
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Behavior Context call failed; unable to retrieve element from container.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_propertySlots.size() <= propertyIndex)
|
||||
{
|
||||
// Missing a property slot
|
||||
SCRIPTCANVAS_REPORT_ERROR((*this), "Node in invalid state; missing a property slot.");
|
||||
return false;
|
||||
}
|
||||
|
||||
PushOutput(atResult, *GetSlot(m_propertySlots[propertyIndex].m_propertySlotId));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ForEach::ResetLoop()
|
||||
{
|
||||
// Reset node state
|
||||
m_index = 0;
|
||||
m_size = 0;
|
||||
m_breakCalled = false;
|
||||
m_sourceContainer = Datum();
|
||||
m_keysVector = Datum();
|
||||
}
|
||||
|
||||
void ForEach::OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType)
|
||||
{
|
||||
if (dynamicGroup == GetContainerGroupId() && dataType.IsValid())
|
||||
|
||||
@@ -56,44 +56,29 @@ namespace ScriptCanvas
|
||||
|
||||
bool IsBreakSlot(const SlotId&) const;
|
||||
|
||||
bool IsOutOfDate(const VersionData& graphVersion) const override;
|
||||
|
||||
|
||||
bool IsOutOfDate(const VersionData& graphVersion) const override;
|
||||
|
||||
UpdateResult OnUpdateNode() override;
|
||||
|
||||
protected:
|
||||
ExecutionNameMap GetExecutionNameMap() const override;
|
||||
|
||||
void OnInit() override;
|
||||
void OnInputSignal(const SlotId&) override;
|
||||
|
||||
bool InitializeLoop();
|
||||
void Iterate();
|
||||
bool SetPropertySlotData(Datum& atResult, size_t propertyIndex);
|
||||
void ResetLoop();
|
||||
|
||||
void OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType) override;
|
||||
|
||||
void ClearPropertySlots();
|
||||
void AddPropertySlotsFromType(const Data::Type& dataType);
|
||||
|
||||
static AZ::Crc32 GetContainerGroupId() { return AZ_CRC("ContainerGroup", 0xb81ed451); }
|
||||
|
||||
SlotId m_sourceSlot;
|
||||
AZ::TypeId m_previousTypeId;
|
||||
AZStd::vector<Data::PropertyMetadata> m_propertySlots;
|
||||
|
||||
private:
|
||||
static const size_t k_keySlotIndex;
|
||||
static const size_t k_valueSlotIndex;
|
||||
|
||||
size_t m_index;
|
||||
size_t m_size;
|
||||
static AZ::Crc32 GetContainerGroupId() { return AZ_CRC("ContainerGroup", 0xb81ed451); }
|
||||
|
||||
bool m_breakCalled;
|
||||
void AddPropertySlotsFromType(const Data::Type& dataType);
|
||||
|
||||
Datum m_sourceContainer;
|
||||
Datum m_keysVector;
|
||||
void ClearPropertySlots();
|
||||
|
||||
ExecutionNameMap GetExecutionNameMap() const override;
|
||||
|
||||
void OnInit() override;
|
||||
|
||||
void OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType) override;
|
||||
|
||||
SlotId m_sourceSlot;
|
||||
AZ::TypeId m_previousTypeId;
|
||||
AZStd::vector<Data::PropertyMetadata> m_propertySlots;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,11 @@ namespace ScriptCanvas
|
||||
return m_asset.GetId();
|
||||
}
|
||||
|
||||
const AZStd::string& FunctionCallNode::GetAssetHint() const
|
||||
{
|
||||
return m_asset.GetHint();
|
||||
}
|
||||
|
||||
AZ::Outcome<DependencyReport, void> FunctionCallNode::GetDependencies() const
|
||||
{
|
||||
DependencyReport report;
|
||||
|
||||
@@ -70,6 +70,8 @@ namespace ScriptCanvas
|
||||
|
||||
AZ::Data::AssetId GetAssetId() const;
|
||||
|
||||
const AZStd::string& GetAssetHint() const;
|
||||
|
||||
const AZStd::string& GetName() const;
|
||||
|
||||
void Initialize(AZ::Data::AssetId assetId, const ScriptCanvas::Grammar::FunctionSourceId& sourceId);
|
||||
|
||||
+32
-1
@@ -19,6 +19,32 @@
|
||||
|
||||
#include <ScriptCanvas/Debugger/ValidationEvents/DataValidation/InvalidPropertyEvent.h>
|
||||
|
||||
namespace FunctionDefinitionNodeCpp
|
||||
{
|
||||
void VersionUpdateRemoveDefaultDisplayGroup(ScriptCanvas::Nodes::Core::FunctionDefinitionNode& node)
|
||||
{
|
||||
using namespace ScriptCanvas;
|
||||
using namespace ScriptCanvas::Nodes::Core;
|
||||
|
||||
AZ::SerializeContext* serializeContext{};
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
if (serializeContext)
|
||||
{
|
||||
const auto& classData = serializeContext->FindClassData(azrtti_typeid<FunctionDefinitionNode>());
|
||||
if (classData && classData->m_version < FunctionDefinitionNode::NodeVersion::RemoveDefaultDisplayGroup)
|
||||
{
|
||||
for (auto& slot : node.ModAllSlots())
|
||||
{
|
||||
if (slot->GetType() == CombinedSlotType::DataIn || slot->GetType() == CombinedSlotType::DataOut)
|
||||
{
|
||||
slot->ClearDynamicGroup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
namespace Nodes
|
||||
@@ -113,6 +139,12 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionDefinitionNode::OnInit()
|
||||
{
|
||||
Nodeling::OnInit();
|
||||
FunctionDefinitionNodeCpp::VersionUpdateRemoveDefaultDisplayGroup(*this);
|
||||
}
|
||||
|
||||
void FunctionDefinitionNode::SetupSlots()
|
||||
{
|
||||
auto groupedSlots = GetSlotsWithDisplayGroup(GetSlotDisplayGroup());
|
||||
@@ -208,7 +240,6 @@ namespace ScriptCanvas
|
||||
slotConfiguration.SetConnectionType(connectionType);
|
||||
|
||||
slotConfiguration.m_displayGroup = GetDataDisplayGroup();
|
||||
slotConfiguration.m_dynamicGroup = GetDataDynamicTypeGroup();
|
||||
slotConfiguration.m_dynamicDataType = DynamicDataType::Any;
|
||||
slotConfiguration.m_isUserAdded = true;
|
||||
|
||||
|
||||
@@ -29,14 +29,13 @@ namespace ScriptCanvas
|
||||
class FunctionDefinitionNode
|
||||
: public Internal::Nodeling
|
||||
{
|
||||
private:
|
||||
public:
|
||||
enum NodeVersion
|
||||
{
|
||||
Initial = 1
|
||||
Initial = 1,
|
||||
RemoveDefaultDisplayGroup,
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
SCRIPTCANVAS_NODE(FunctionDefinitionNode);
|
||||
|
||||
FunctionDefinitionNode() = default;
|
||||
@@ -78,14 +77,15 @@ namespace ScriptCanvas
|
||||
|
||||
static constexpr AZ::Crc32 GetAddNodelingInputDataSlot() { return AZ_CRC_CE("AddNodelingInputDataSlot"); }
|
||||
static constexpr AZ::Crc32 GetAddNodelingOutputDataSlot() { return AZ_CRC_CE("AddNodelingOutputDataSlot"); }
|
||||
static constexpr AZ::Crc32 GetDataDynamicTypeGroup() { return AZ_CRC_CE("DataGroup"); }
|
||||
|
||||
|
||||
AZStd::string GetDataDisplayGroup() const { return "DataDisplayGroup"; }
|
||||
|
||||
SlotId HandleExtension(AZ::Crc32 extensionId) override;
|
||||
|
||||
void ConfigureVisualExtensions() override;
|
||||
|
||||
void OnInit() override;
|
||||
|
||||
void OnSetup() override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -208,7 +208,6 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Method::InitializeMethod(const MethodConfiguration& config)
|
||||
{
|
||||
m_namespaces = config.m_namespaces ? *config.m_namespaces : m_namespaces;
|
||||
@@ -239,7 +238,11 @@ namespace ScriptCanvas
|
||||
for (size_t argIndex(0), sentinel(config.m_method.GetNumArguments()); argIndex != sentinel; ++argIndex)
|
||||
{
|
||||
SlotId addedSlot = AddMethodInputSlot(config, argIndex);
|
||||
MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex);
|
||||
|
||||
if (addedSlot.IsValid())
|
||||
{
|
||||
MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,8 @@ namespace ScriptCanvas
|
||||
|
||||
const Slot* GetIfBranchSlot(bool branch) const;
|
||||
|
||||
AZ_INLINE const AZStd::string& GetLookupName() const { return m_lookupName; }
|
||||
|
||||
AZ_INLINE AZStd::recursive_mutex& GetMutex() { return m_mutex; }
|
||||
|
||||
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* executionChildSlot) const override;
|
||||
@@ -160,6 +162,8 @@ namespace ScriptCanvas
|
||||
|
||||
bool SanityCheckBranchOnResultMethod(const AZ::BehaviorMethod& branchOnResultMethod) const;
|
||||
|
||||
AZ_INLINE void SetClassNamePretty(AZStd::string_view classNamePretty) { m_classNamePretty = classNamePretty; }
|
||||
|
||||
void SetMethodUnchecked(const AZ::BehaviorMethod* method, const AZ::BehaviorClass* behaviorClass);
|
||||
|
||||
AZ_INLINE void SetWarnOnMissingFunction(bool enabled) { m_warnOnMissingFunction = enabled; }
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace ScriptCanvas
|
||||
{
|
||||
if (!m_updatingDisplay)
|
||||
{
|
||||
RefreshActiveIndexes();
|
||||
RefreshActiveIndexes(true, true);
|
||||
UpdateSlotDisplay();
|
||||
}
|
||||
}
|
||||
@@ -135,10 +135,8 @@ namespace ScriptCanvas
|
||||
return Data::Type::Invalid();
|
||||
}
|
||||
|
||||
AZ::Outcome<AZStd::string, void> MethodOverloaded::GetFunctionCallName(const Slot* slot) const
|
||||
AZ::Outcome<AZStd::string, void> MethodOverloaded::GetFunctionCallName([[maybe_unused]] const Slot* slot) const
|
||||
{
|
||||
AZ_UNUSED(slot);
|
||||
|
||||
AZStd::string overloadName;
|
||||
|
||||
int activeIndex = GetActiveIndex();
|
||||
@@ -188,7 +186,7 @@ namespace ScriptCanvas
|
||||
|
||||
// this prevents repeated updates based on changes to slots
|
||||
Method::InitializeMethod(config);
|
||||
|
||||
SetClassNamePretty("");
|
||||
RefreshActiveIndexes();
|
||||
|
||||
ConfigureContracts();
|
||||
@@ -197,7 +195,12 @@ namespace ScriptCanvas
|
||||
SlotId MethodOverloaded::AddMethodInputSlot(const MethodConfiguration& config, size_t argumentIndex)
|
||||
{
|
||||
const AZ::BehaviorParameter* argumentPtr = config.m_method.GetArgument(argumentIndex);
|
||||
AZ_Assert(argumentPtr, "Method: %s had a null argument at index: %d", config.m_lookupName->data(), argumentIndex);
|
||||
|
||||
if (!argumentPtr)
|
||||
{
|
||||
return SlotId{};
|
||||
}
|
||||
|
||||
const auto& argument = *argumentPtr;
|
||||
auto nameAndToolTip = MethodHelper::GetArgumentNameAndToolTip(config, argumentIndex);
|
||||
|
||||
@@ -507,7 +510,7 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void MethodOverloaded::RefreshActiveIndexes(bool checkForConnections)
|
||||
void MethodOverloaded::RefreshActiveIndexes(bool checkForConnections, bool adjustSlots)
|
||||
{
|
||||
DataIndexMapping concreteInputTypes;
|
||||
DataIndexMapping concreteOutputTypes;
|
||||
@@ -519,6 +522,35 @@ namespace ScriptCanvas
|
||||
if (m_overloadSelection.m_availableIndexes.size() == 1)
|
||||
{
|
||||
auto methodOverload = m_overloadConfiguration.m_overloads[(*m_overloadSelection.m_availableIndexes.begin())];
|
||||
|
||||
if (adjustSlots)
|
||||
{
|
||||
const size_t numArguments = methodOverload.first->GetNumArguments();
|
||||
const size_t numInputSlots = m_orderedInputSlotIds.size();
|
||||
|
||||
if (numArguments > numInputSlots)
|
||||
{
|
||||
MethodConfiguration config(*methodOverload.first, GetMethodType());
|
||||
AZStd::string_view lookupName = GetLookupName();
|
||||
config.m_lookupName = &lookupName;
|
||||
|
||||
for (size_t index = numInputSlots; index != numArguments; ++index)
|
||||
{
|
||||
AddMethodInputSlot(config, index);
|
||||
}
|
||||
}
|
||||
else if (numArguments < numInputSlots)
|
||||
{
|
||||
const size_t removeCount = numInputSlots - numArguments;
|
||||
// remove extra slots, assuming remaining ones are of valid type (if not valid name)
|
||||
for (size_t count = 0; count != removeCount; ++count)
|
||||
{
|
||||
RemoveSlot(m_orderedInputSlotIds.back());
|
||||
m_orderedInputSlotIds.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetMethodUnchecked(methodOverload.first, methodOverload.second);
|
||||
}
|
||||
}
|
||||
@@ -681,9 +713,6 @@ namespace ScriptCanvas
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace ScriptCanvas
|
||||
void SetupMethodData(const AZ::BehaviorMethod* lookupMethod, const AZ::BehaviorClass* lookupClass);
|
||||
void ConfigureContracts();
|
||||
|
||||
void RefreshActiveIndexes(bool checkForConnections = true);
|
||||
void RefreshActiveIndexes(bool checkForConnections = true, bool adjustSlots = false);
|
||||
void FindDataIndexMappings(DataIndexMapping& inputMapping, DataIndexMapping& outputMapping, bool checkForConnections) const;
|
||||
|
||||
void UpdateSlotDisplay();
|
||||
|
||||
@@ -393,14 +393,6 @@ namespace ScriptCanvas
|
||||
AZ_UNUSED(sourceType);
|
||||
}
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> OperatorBase::GetReplacementSlotsMap() const
|
||||
{
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> slotsMap;
|
||||
slotsMap.emplace("In", AZStd::vector<AZStd::string>{ "In" });
|
||||
slotsMap.emplace("Out", AZStd::vector<AZStd::string>{ "Out" });
|
||||
return slotsMap;
|
||||
}
|
||||
|
||||
void OperatorBase::CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const
|
||||
{
|
||||
auto newDataInSlots = replacementNode->GetSlotsByType(ScriptCanvas::CombinedSlotType::DataIn);
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace ScriptCanvas
|
||||
AZStd::vector< SourceSlotConfiguration > m_sourceSlotConfigurations;
|
||||
};
|
||||
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> GetReplacementSlotsMap() const override;
|
||||
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map<SlotId, AZStd::vector<SlotId>>& outSlotIdMap) const override;
|
||||
|
||||
using TypeList = AZStd::vector<AZ::TypeId>;
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@
|
||||
Base="ScriptCanvas::Node"
|
||||
Version="2"
|
||||
GeneratePropertyFriend="True"
|
||||
DeprecationUUID="32A4BEDC-C207-4472-61DE-9A716402620A"
|
||||
DeprecationUUID="{32A4BEDC-C207-4472-61DE-9A716402620A}"
|
||||
Deprecated="This node has been deprecated in favor of the nodeable form"
|
||||
Description="Provides a time value.">
|
||||
<In Name="Start" Description="Starts the timer."/>
|
||||
@@ -25,4 +25,4 @@
|
||||
IsInput="False"
|
||||
IsOutput="True" />
|
||||
</Class>
|
||||
</ScriptCanvas>
|
||||
</ScriptCanvas>
|
||||
@@ -62,6 +62,8 @@ namespace ScriptCanvas
|
||||
constexpr const char* NoChildrenAfterRoot = "No children after parsing function root";
|
||||
constexpr const char* NoChildrenInExtraction = "No children found in property extraction node";
|
||||
constexpr const char* NoDataPresent = "Could not construct from graph, no graph data was present";
|
||||
constexpr const char* NodeableNodeOverloadAmbiguous = "NodeableNodeOverloaded doesn't have enough data connected to select a valid overload";
|
||||
constexpr const char* NodeableNodeDidNotConstructInternalNodeable = "NodeableNode did not construct its internal Nodeable";
|
||||
constexpr const char* NoInputToForEach = "No Input To For Each Loop";
|
||||
constexpr const char* NoOutForExecution = "No out slot for execution root";
|
||||
constexpr const char* NoOutSlotInFunctionDefinitionStart = "No 'Out' slot in start of function definition";
|
||||
|
||||
@@ -12,9 +12,26 @@
|
||||
#include "VersioningUtils.h"
|
||||
|
||||
#include <ScriptCanvas/Core/Graph.h>
|
||||
#include <ScriptCanvas/Core/Connection.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
AZStd::vector<Endpoint> GraphUpdateSlotReport::Convert(const Endpoint& oldEndpoint) const
|
||||
{
|
||||
auto iter = m_oldSlotsToNewSlots.find(oldEndpoint);
|
||||
return iter != m_oldSlotsToNewSlots.end() ? iter->second : AZStd::vector<Endpoint>{ oldEndpoint };
|
||||
}
|
||||
|
||||
bool GraphUpdateSlotReport::IsEmpty() const
|
||||
{
|
||||
return m_deletedOldSlots.empty() && m_oldSlotsToNewSlots.empty();
|
||||
}
|
||||
|
||||
bool NodeUpdateSlotReport::IsEmpty() const
|
||||
{
|
||||
return m_deletedOldSlots.empty() && m_oldSlotsToNewSlots.empty();
|
||||
}
|
||||
|
||||
void VersioningUtils::CopyOldValueToDataSlot(Slot* newSlot, const VariableId& oldVariableReference, const Datum* oldDatum)
|
||||
{
|
||||
if (oldVariableReference.IsValid())
|
||||
@@ -36,6 +53,99 @@ namespace ScriptCanvas
|
||||
}
|
||||
}
|
||||
|
||||
void MergeUpdateSlotReport(const AZ::EntityId& scriptCanvasNodeId, GraphUpdateSlotReport& report, const NodeUpdateSlotReport& source)
|
||||
{
|
||||
report.m_deletedOldSlots.reserve(source.m_deletedOldSlots.size());
|
||||
|
||||
for (auto& slotId : source.m_deletedOldSlots)
|
||||
{
|
||||
report.m_deletedOldSlots.insert({ scriptCanvasNodeId, slotId });
|
||||
}
|
||||
|
||||
report.m_oldSlotsToNewSlots.reserve(source.m_oldSlotsToNewSlots.size());
|
||||
|
||||
for (auto& oldToNewIter : source.m_oldSlotsToNewSlots)
|
||||
{
|
||||
AZStd::vector<Endpoint> newEndpoints;
|
||||
newEndpoints.reserve(oldToNewIter.second.size());
|
||||
|
||||
for (auto& targetSlotId : oldToNewIter.second)
|
||||
{
|
||||
newEndpoints.push_back({ scriptCanvasNodeId, targetSlotId });
|
||||
}
|
||||
|
||||
report.m_oldSlotsToNewSlots[{ scriptCanvasNodeId, oldToNewIter.first}] = AZStd::move(newEndpoints);
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::vector<AZStd::pair<Endpoint, Endpoint>> CollectEndpoints(const AZStd::vector<AZ::Entity*>& connections, bool logEntityNames)
|
||||
{
|
||||
AZStd::vector<AZStd::string> names;
|
||||
AZStd::vector<AZStd::pair<Endpoint, Endpoint>> endpoints;
|
||||
|
||||
for (auto& connectionEntity : connections)
|
||||
{
|
||||
if (logEntityNames)
|
||||
{
|
||||
names.push_back(connectionEntity->GetName());
|
||||
}
|
||||
|
||||
if (auto connection = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Connection>(connectionEntity->GetId()))
|
||||
{
|
||||
endpoints.push_back(AZStd::make_pair(connection->GetSourceEndpoint(), connection->GetTargetEndpoint()));
|
||||
}
|
||||
}
|
||||
|
||||
if (logEntityNames)
|
||||
{
|
||||
AZStd::sort(names.begin(), names.end());
|
||||
|
||||
AZStd::string result = "\nConnection Name list:\n";
|
||||
for (auto& name : names)
|
||||
{
|
||||
result += "\n";
|
||||
result += name;
|
||||
}
|
||||
|
||||
AZ_TracePrintf("ScriptCanvas", result.c_str());
|
||||
}
|
||||
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
void UpdateConnectionStatus(Graph& graph, const GraphUpdateSlotReport& report)
|
||||
{
|
||||
GraphData* graphData = graph.GetGraphData();
|
||||
if (!graphData)
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "Graph was missing graph data to update");
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::unordered_set<SlotId> oldConnectedSlots;
|
||||
AZ_TracePrintf("ScriptCanvas", "Connections list before: ");
|
||||
auto endpoints = CollectEndpoints(graphData->m_connections, true);
|
||||
graph.RemoveAllConnections();
|
||||
|
||||
for (auto& iter : endpoints)
|
||||
{
|
||||
const AZStd::vector<Endpoint>& sources = report.Convert(iter.first);
|
||||
const AZStd::vector<Endpoint>& targets = report.Convert(iter.second);
|
||||
|
||||
for (const auto& source : sources)
|
||||
{
|
||||
for (const auto& target : targets)
|
||||
{
|
||||
graph.ConnectByEndpoint(source, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
graphData->BuildEndpointMap();
|
||||
AZ_TracePrintf("ScriptCanvas", "Connections list after: ");
|
||||
CollectEndpoints(graphData->m_connections, true);
|
||||
}
|
||||
|
||||
void VersioningUtils::CreateRemapConnectionsForSourceEndpoint(const Graph& graph, const Endpoint& oldSourceEndpoint, const Endpoint& newSourceEndpoint,
|
||||
ReplacementConnectionMap& connectionMap)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <ScriptCanvas/Core/Endpoint.h>
|
||||
#include <ScriptCanvas/Variable/VariableCore.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -25,13 +27,36 @@ namespace AZ
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
class Datum;
|
||||
class Endpoint;
|
||||
class Graph;
|
||||
class Slot;
|
||||
|
||||
using ReplacementEndpointPairs = AZStd::unordered_set<AZStd::pair<ScriptCanvas::Endpoint, ScriptCanvas::Endpoint>>;
|
||||
using ReplacementEndpointPairs = AZStd::unordered_set<AZStd::pair<Endpoint, Endpoint>>;
|
||||
using ReplacementConnectionMap = AZStd::unordered_map<AZ::EntityId, ReplacementEndpointPairs>;
|
||||
|
||||
struct NodeUpdateSlotReport
|
||||
{
|
||||
AZStd::unordered_set<SlotId> m_deletedOldSlots;
|
||||
AZStd::unordered_map<SlotId, AZStd::vector<SlotId>> m_oldSlotsToNewSlots;
|
||||
|
||||
bool IsEmpty() const;
|
||||
};
|
||||
|
||||
struct GraphUpdateSlotReport
|
||||
{
|
||||
AZStd::unordered_set<Endpoint> m_deletedOldSlots;
|
||||
AZStd::unordered_map<Endpoint, AZStd::vector<Endpoint>> m_oldSlotsToNewSlots;
|
||||
|
||||
AZStd::vector<Endpoint> Convert(const Endpoint& oldEndpoint) const;
|
||||
|
||||
bool IsEmpty() const;
|
||||
};
|
||||
|
||||
void MergeUpdateSlotReport(const AZ::EntityId& scriptCanvasNodeId, GraphUpdateSlotReport& report, const NodeUpdateSlotReport& source);
|
||||
|
||||
AZStd::vector<AZStd::pair<Endpoint, Endpoint>> CollectEndpoints(const AZStd::vector<AZ::Entity*>& connections, bool logEntityNames = false);
|
||||
|
||||
void UpdateConnectionStatus(Graph& graph, const GraphUpdateSlotReport& report);
|
||||
|
||||
class VersioningUtils
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
PreferredClassName="Input Handler"
|
||||
Uuid="{0B0AC61B-4BBA-42BF-BDCD-DAF2D3CA41A8}"
|
||||
Base="ScriptCanvas::Node"
|
||||
Icon="Icons/ScriptCanvas/Bus.png"
|
||||
Icon="Editor/Icons/ScriptCanvas/Bus.png"
|
||||
EditAttributes="AZ::Edit::Attributes::Category@Gameplay/Input"
|
||||
DeprecationUUID="{0A2EB488-5A6A-E166-BB62-23FF81499E33}"
|
||||
Deprecated="This node has been deprecated in favor of the nodeable form"
|
||||
GraphEntryPoint="True"
|
||||
GeneratePropertyFriend="True"
|
||||
Description="Handle processed input events found in input binding assets">
|
||||
@@ -25,4 +27,4 @@
|
||||
IsInput="False"
|
||||
IsOutput="True" />
|
||||
</Class>
|
||||
</ScriptCanvas>
|
||||
</ScriptCanvas>
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
|
||||
ly_add_target(
|
||||
NAME TextureAtlas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
|
||||
NAME TextureAtlas.Static STATIC
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
textureatlas_files.cmake
|
||||
@@ -21,4 +21,46 @@ ly_add_target(
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
AZ::AzFramework
|
||||
PUBLIC
|
||||
Gem::Atom_RPI.Public
|
||||
AZ::AtomCore
|
||||
)
|
||||
|
||||
ly_add_target(
|
||||
NAME TextureAtlas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
textureatlas_module_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
Include
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
Gem::TextureAtlas.Static
|
||||
)
|
||||
|
||||
if(PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_target(
|
||||
NAME TextureAtlas.Editor GEM_MODULE
|
||||
NAMESPACE Gem
|
||||
FILES_CMAKE
|
||||
textureatlas_module_files.cmake
|
||||
textureatlas_builder_files.cmake
|
||||
COMPILE_DEFINITIONS
|
||||
PRIVATE
|
||||
TEXTUREATLAS_EDITOR
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
Include
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
Legacy::CryCommon
|
||||
AZ::AzCore
|
||||
AZ::AzFramework
|
||||
AZ::AssetBuilderSDK
|
||||
Gem::TextureAtlas.Static
|
||||
Gem::ImageProcessingAtom.Headers
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
class ITexture;
|
||||
#include <Atom/RPI.Reflect/Image/Image.h>
|
||||
#include <AtomCore/Instance/Instance.h>
|
||||
|
||||
namespace TextureAtlasNamespace
|
||||
{
|
||||
@@ -77,9 +78,9 @@ namespace TextureAtlasNamespace
|
||||
//! Retrieve a coordinate set from the Atlas by its handle
|
||||
virtual AtlasCoordinates GetAtlasCoordinates(const AZStd::string& handle) const = 0;
|
||||
//! Links this atlas to an image pointer
|
||||
virtual void SetTexture(ITexture* image) = 0;
|
||||
virtual void SetTexture(AZ::Data::Instance<AZ::RPI::Image> image) = 0;
|
||||
//! Returns the image linked to this atlas
|
||||
virtual ITexture* GetTexture() const = 0;
|
||||
virtual AZ::Data::Instance<AZ::RPI::Image> GetTexture() const = 0;
|
||||
//! Returns the width of the atlas
|
||||
virtual int GetWidth() const = 0;
|
||||
//! Returns the height of the atlas
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ImageProcessing_precompiled.h"
|
||||
#include "AtlasBuilderComponent.h"
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ImageProcessing_precompiled.h"
|
||||
#include "AtlasBuilderWorker.h"
|
||||
|
||||
#include <AzCore/Math/MathIntrinsics.h>
|
||||
@@ -19,22 +18,17 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/std/string/regex.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzFramework/IO/LocalFileIO.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
|
||||
#include <ImageProcessing/ImageObject.h>
|
||||
#include <Processing/ImageConvert.h>
|
||||
#include <Processing/ImageConvertJob.h>
|
||||
#include <ImageLoader/ImageLoaders.h>
|
||||
#include <Processing/ImageObjectImpl.h>
|
||||
#include <Processing/PixelFormatInfo.h>
|
||||
|
||||
#include <BuilderSettings/PresetSettings.h>
|
||||
#include <BuilderSettings/TextureSettings.h>
|
||||
#include <BuilderSettings/BuilderSettingManager.h>
|
||||
#include <Atom/ImageProcessing/ImageObject.h>
|
||||
#include <Atom/ImageProcessing/ImageProcessingBus.h>
|
||||
#include <Atom/ImageProcessing/PixelFormats.h>
|
||||
#include <Atom/RPI.Reflect/Image/StreamingImageAsset.h>
|
||||
|
||||
#include <qimage.h>
|
||||
#include <QString>
|
||||
@@ -44,13 +38,13 @@
|
||||
namespace TextureAtlasBuilder
|
||||
{
|
||||
//! Counts leading zeros
|
||||
uint32 CountLeadingZeros32(uint32 x)
|
||||
uint32_t CountLeadingZeros32(uint32_t x)
|
||||
{
|
||||
return x == 0 ? 32 : az_clz_u32(x);
|
||||
}
|
||||
|
||||
//! Integer log2
|
||||
uint32 IntegerLog2(uint32 x)
|
||||
uint32_t IntegerLog2(uint32_t x)
|
||||
{
|
||||
return 31 - CountLeadingZeros32(x);
|
||||
}
|
||||
@@ -113,13 +107,24 @@ namespace TextureAtlasBuilder
|
||||
{
|
||||
bool resolved = false;
|
||||
|
||||
// Get full path by appending the relative path to the watch directory
|
||||
AZStd::string fullPath = watchDirectory;
|
||||
fullPath.append("/");
|
||||
fullPath.append(relativePath);
|
||||
if (relativePath[0] == '@')
|
||||
{
|
||||
// Get full path by resolving the alias at the front of the path
|
||||
char resolvedPath[AZ_MAX_PATH_LEN];
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath(relativePath.c_str(), resolvedPath, AZ_MAX_PATH_LEN);
|
||||
resolvedFullPathOut = resolvedPath;
|
||||
resolved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get full path by appending the relative path to the watch directory
|
||||
AZStd::string fullPath = watchDirectory;
|
||||
fullPath.append("/");
|
||||
fullPath.append(relativePath);
|
||||
|
||||
// Resolve to canonical path (remove "./" and "../")
|
||||
resolved = GetCanonicalPathFromFullPath(fullPath, resolvedFullPathOut);
|
||||
// Resolve to canonical path (remove "./" and "../")
|
||||
resolved = GetCanonicalPathFromFullPath(fullPath, resolvedFullPathOut);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
@@ -140,23 +145,6 @@ namespace TextureAtlasBuilder
|
||||
return result;
|
||||
}
|
||||
|
||||
const ImageProcessing::PresetSettings* GetImageProcessPresetSettings(const AZStd::string& presetName, const AZStd::string& platformIdentifier)
|
||||
{
|
||||
// Get the specified presetId
|
||||
AZ::Uuid presetId = ImageProcessing::BuilderSettingManager::Instance()->GetPresetIdFromName(presetName);
|
||||
if (presetId.IsNull())
|
||||
{
|
||||
AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the preset settings for the platform this job is building for
|
||||
const ImageProcessing::PresetSettings* presetSettings = ImageProcessing::BuilderSettingManager::Instance()->GetPreset(
|
||||
presetId, platformIdentifier);
|
||||
|
||||
return presetSettings;
|
||||
}
|
||||
|
||||
// Reflect the input parameters
|
||||
void AtlasBuilderInput::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
@@ -474,7 +462,7 @@ namespace TextureAtlasBuilder
|
||||
{
|
||||
AZStd::string ext;
|
||||
AzFramework::StringFunc::Path::GetExtension(candidates[i].c_str(), ext, false);
|
||||
if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds")
|
||||
if (ext != "dds")
|
||||
{
|
||||
bool duplicate = false;
|
||||
for (size_t j = 0; j < paths.size() && !duplicate; ++j)
|
||||
@@ -589,7 +577,7 @@ namespace TextureAtlasBuilder
|
||||
{
|
||||
AddFolderContents(paths, child, valid);
|
||||
}
|
||||
else if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds")
|
||||
else if (ext != "dds")
|
||||
{
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, child);
|
||||
bool duplicate = false;
|
||||
@@ -652,7 +640,11 @@ namespace TextureAtlasBuilder
|
||||
// We process the same file for all platforms
|
||||
for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms)
|
||||
{
|
||||
if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(info.m_identifier))
|
||||
bool doesSupportPlatform = false;
|
||||
ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(doesSupportPlatform,
|
||||
&ImageProcessingAtom::ImageBuilderRequests::DoesSupportPlatform,
|
||||
info.m_identifier);
|
||||
if (doesSupportPlatform)
|
||||
{
|
||||
AssetBuilderSDK::JobDescriptor descriptor = GetJobDescriptor(request.m_sourceFile, input);
|
||||
descriptor.SetPlatformIdentifier(info.m_identifier.c_str());
|
||||
@@ -707,12 +699,8 @@ namespace TextureAtlasBuilder
|
||||
// Before we begin, let's make sure we are not meant to abort.
|
||||
AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId);
|
||||
|
||||
AZStd::vector<AZStd::string> productFilepaths;
|
||||
|
||||
const AZStd::string path = request.m_fullPath;
|
||||
|
||||
bool imageProcessingSuccessful = false;
|
||||
|
||||
// read in settings/filepaths
|
||||
AtlasBuilderInput input;
|
||||
input.m_forceSquare = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forceSquare"))->second.c_str());
|
||||
@@ -752,43 +740,37 @@ namespace TextureAtlasBuilder
|
||||
// Default to the TextureAtlas preset which is currently set to use compression for all platforms except for iOS.
|
||||
// Currently the only fully supported compression for iOS is PVRTC which requires the texture to be square and a power of 2.
|
||||
// Due to this limitation, we default to using no compression for iOS until ASTC is fully supported
|
||||
const AZStd::string defaultPresetName = "TextureAtlas";
|
||||
const AZStd::string defaultPresetName = "UserInterface_Compressed";
|
||||
input.m_presetName = defaultPresetName;
|
||||
}
|
||||
|
||||
// Get a preset to use for the output image
|
||||
const ImageProcessing::PresetSettings* preset = GetImageProcessPresetSettings(input.m_presetName, request.m_platformInfo.m_identifier);
|
||||
if (preset)
|
||||
bool isFormatSquarePow2 = false;
|
||||
ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(isFormatSquarePow2,
|
||||
&ImageProcessingAtom::ImageBuilderRequests::IsPresetFormatSquarePow2,
|
||||
input.m_presetName, request.m_platformInfo.m_identifier);
|
||||
|
||||
if (isFormatSquarePow2)
|
||||
{
|
||||
// Check the preset's pixel format requirements
|
||||
const ImageProcessing::PixelFormatInfo* pixelFormatInfo = ImageProcessing::CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat);
|
||||
if (pixelFormatInfo && pixelFormatInfo->bSquarePow2)
|
||||
{
|
||||
// Override the user config settings to force square and power of 2.
|
||||
// Otherwise the image conversion process will stretch the image to satisfy these requirements
|
||||
input.m_forceSquare = true;
|
||||
input.m_forcePowerOf2 = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("AtlasBuilder", false, "Could not find a preset setting for the output image.");
|
||||
return;
|
||||
// Override the user config settings to force square and power of 2.
|
||||
// Otherwise the image conversion process will stretch the image to satisfy these requirements
|
||||
input.m_forceSquare = true;
|
||||
input.m_forcePowerOf2 = true;
|
||||
}
|
||||
|
||||
// Read in images
|
||||
AZStd::vector<ImageProcessing::IImageObjectPtr> images;
|
||||
AZStd::vector<ImageProcessingAtom::IImageObjectPtr> images;
|
||||
AZ::u64 totalArea = 0;
|
||||
int maxArea = input.m_maxDimension * input.m_maxDimension;
|
||||
bool sizeFailure = false;
|
||||
for (int i = 0; i < input.m_filePaths.size() && !jobCancelListener.IsCancelled(); ++i)
|
||||
{
|
||||
ImageProcessing::IImageObject* inputImage = ImageProcessing::LoadImageFromFile(input.m_filePaths[i]);
|
||||
ImageProcessingAtom::IImageObjectPtr inputImage;
|
||||
ImageProcessingAtom::ImageProcessingRequestBus::BroadcastResult(inputImage, &ImageProcessingAtom::ImageProcessingRequests::LoadImage, input.m_filePaths[i]);
|
||||
|
||||
// Check if we were able to load the image
|
||||
if (inputImage)
|
||||
{
|
||||
ImageProcessing::IImageObjectPtr image = ImageProcessing::IImageObjectPtr(inputImage);
|
||||
images.push_back(image);
|
||||
images.push_back(inputImage);
|
||||
totalArea += inputImage->GetWidth(0) * inputImage->GetHeight(0);
|
||||
}
|
||||
else
|
||||
@@ -837,8 +819,13 @@ namespace TextureAtlasBuilder
|
||||
// Add white texture if we need to
|
||||
if (input.m_includeWhiteTexture)
|
||||
{
|
||||
ImageProcessing::IImageObjectPtr texture(ImageProcessing::IImageObject::CreateImage(
|
||||
cellSize, cellSize, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8));
|
||||
ImageProcessingAtom::IImageObjectPtr texture;
|
||||
ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(texture,
|
||||
&ImageProcessingAtom::ImageBuilderRequests::CreateImage,
|
||||
aznumeric_cast<AZ::u32>(cellSize),
|
||||
aznumeric_cast<AZ::u32>(cellSize),
|
||||
1,
|
||||
ImageProcessingAtom::EPixelFormat::ePixelFormat_R8G8B8A8);
|
||||
|
||||
// Make the texture white
|
||||
texture->ClearColor(1, 1, 1, 1);
|
||||
@@ -897,8 +884,8 @@ namespace TextureAtlasBuilder
|
||||
}
|
||||
if (input.m_forcePowerOf2)
|
||||
{
|
||||
resultWidth = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32>(resultWidth - 1))));
|
||||
resultHeight = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32>(resultHeight - 1))));
|
||||
resultWidth = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32_t>(resultWidth - 1))));
|
||||
resultHeight = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32_t>(resultHeight - 1))));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -918,8 +905,13 @@ namespace TextureAtlasBuilder
|
||||
}
|
||||
|
||||
// Process texture sheet
|
||||
ImageProcessing::IImageObjectPtr outImage(ImageProcessing::IImageObject::CreateImage(
|
||||
resultWidth, resultHeight, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8));
|
||||
ImageProcessingAtom::IImageObjectPtr outImage;
|
||||
ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(outImage,
|
||||
&ImageProcessingAtom::ImageBuilderRequests::CreateImage,
|
||||
aznumeric_cast<AZ::u32>(resultWidth),
|
||||
aznumeric_cast<AZ::u32>(resultHeight),
|
||||
1,
|
||||
ImageProcessingAtom::EPixelFormat::ePixelFormat_R8G8B8A8);
|
||||
|
||||
// Clear the sheet
|
||||
outImage->ClearColor(input.m_unusedColor.GetR(), input.m_unusedColor.GetG(), input.m_unusedColor.GetB(), input.m_unusedColor.GetA());
|
||||
@@ -1010,54 +1002,21 @@ namespace TextureAtlasBuilder
|
||||
// Output texture sheet
|
||||
AZStd::string imageFileName, imageOutputPath;
|
||||
AzFramework::StringFunc::Path::GetFileName(request.m_sourceFile.c_str(), imageFileName);
|
||||
imageFileName += ".dds";
|
||||
imageFileName += ".texatlas";
|
||||
AzFramework::StringFunc::Path::Join(
|
||||
request.m_tempDirPath.c_str(), imageFileName.c_str(), imageOutputPath, true, true);
|
||||
|
||||
// Let the ImageProcessor do the rest of the work.
|
||||
ImageProcessing::TextureSettings textureSettings;
|
||||
textureSettings.m_preset = preset->m_uuid;
|
||||
AZStd::vector<AssetBuilderSDK::JobProduct> outProducts;
|
||||
ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(outProducts,
|
||||
&ImageProcessingAtom::ImageBuilderRequests::ConvertImageObject,
|
||||
outImage,
|
||||
input.m_presetName,
|
||||
request.m_platformInfo.m_identifier,
|
||||
imageOutputPath,
|
||||
request.m_sourceFileUUID,
|
||||
request.m_sourceFile);
|
||||
|
||||
// Mipmaps for the texture atlas would require more work than the Image Processor does. This is because if we
|
||||
// let the Image Processor make mipmaps, it might bleed the textures in the atlas together.
|
||||
textureSettings.m_enableMipmap = false;
|
||||
|
||||
// Check if the ImageBuilder wants to enable streaming
|
||||
bool isStreaming = ImageProcessing::BuilderSettingManager::Instance()
|
||||
->GetBuilderSetting(request.m_platformInfo.m_identifier)
|
||||
->m_enableStreaming;
|
||||
|
||||
bool canOverridePreset = false;
|
||||
ImageProcessing::ImageConvertProcess* process =
|
||||
new ImageProcessing::ImageConvertProcess(outImage,
|
||||
textureSettings,
|
||||
*preset,
|
||||
false,
|
||||
isStreaming,
|
||||
canOverridePreset,
|
||||
imageOutputPath,
|
||||
request.m_platformInfo.m_identifier);
|
||||
|
||||
if (process != nullptr)
|
||||
{
|
||||
// the process can be stopped if the job is cancelled or the worker is shutting down
|
||||
while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled())
|
||||
{
|
||||
process->UpdateProcess();
|
||||
}
|
||||
|
||||
// get process result
|
||||
imageProcessingSuccessful = process->IsSucceed();
|
||||
process->GetAppendOutputFilePaths(productFilepaths);
|
||||
|
||||
delete process;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageProcessingSuccessful = false;
|
||||
}
|
||||
|
||||
if (imageProcessingSuccessful)
|
||||
if (!outProducts.empty())
|
||||
{
|
||||
TextureAtlasNamespace::TextureAtlasRequestBus::Broadcast(
|
||||
&TextureAtlasNamespace::TextureAtlasRequests::SaveAtlasToFile, outputPath, output, resultWidth, resultHeight);
|
||||
@@ -1067,27 +1026,23 @@ namespace TextureAtlasBuilder
|
||||
|
||||
// The Image Processing Gem can produce multiple output files under certain
|
||||
// circumstances, but the texture atlas is not expected to produce such output
|
||||
if (productFilepaths.size() > 1)
|
||||
if (outProducts.size() > 1)
|
||||
{
|
||||
AZ_Error("AtlasBuilder", false, "Image processing resulted in multiple output files. Texture atlas is expected to produce one output.");
|
||||
response.m_outputProducts.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (productFilepaths.size() > 0)
|
||||
{
|
||||
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(productFilepaths[0]));
|
||||
response.m_outputProducts.back().m_productAssetType = azrtti_typeid<TextureAtlasNamespace::TextureAtlasAsset>();
|
||||
response.m_outputProducts.back().m_productSubID = 1;
|
||||
response.m_outputProducts.push_back(outProducts[0]);
|
||||
|
||||
// The texatlasidx file is a data file that indicates where the original parts are inside the atlas,
|
||||
// and this would usually imply that it refers to its dds file in some way or needs it to function.
|
||||
// The texatlasidx file should be the one that depends on the DDS because it's possible to use the DDS
|
||||
// without the texatlasid, but not the other way around
|
||||
AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID);
|
||||
response.m_outputProducts[static_cast<int>(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0));
|
||||
response.m_outputProducts[static_cast<int>(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies
|
||||
|
||||
// The texatlasidx file is a data file that indicates where the original parts are inside the atlas,
|
||||
// and this would usually imply that it refers to its dds file in some way or needs it to function.
|
||||
// The texatlasidx file should be the one that depends on the DDS because its possible to use the DDS
|
||||
// without the texatlasid, but not the other way around
|
||||
AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID);
|
||||
response.m_outputProducts[static_cast<int>(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0));
|
||||
response.m_outputProducts[static_cast<int>(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies
|
||||
}
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
}
|
||||
}
|
||||
@@ -1315,7 +1270,7 @@ namespace TextureAtlasBuilder
|
||||
if (powerOfTwo)
|
||||
{
|
||||
// Starting dimension needs to be rounded up to the nearest power of two
|
||||
dimension = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32>(dimension - 1))));
|
||||
dimension = aznumeric_cast<int>(pow(2, 1 + IntegerLog2(static_cast<uint32_t>(dimension - 1))));
|
||||
}
|
||||
|
||||
AZStd::vector<AtlasCoordinates> track;
|
||||
@@ -1363,7 +1318,7 @@ namespace TextureAtlasBuilder
|
||||
if (powerOfTwo)
|
||||
{
|
||||
// Starting dimension needs to be rounded up to the nearest power of two
|
||||
minWidth = aznumeric_cast<AZ::u32>(pow(2, 1 + IntegerLog2(static_cast<uint32>(minWidth - 1))));
|
||||
minWidth = aznumeric_cast<AZ::u32>(pow(2, 1 + IntegerLog2(static_cast<uint32_t>(minWidth - 1))));
|
||||
}
|
||||
|
||||
// Round min width up to the nearest compression unit
|
||||
@@ -1400,7 +1355,7 @@ namespace TextureAtlasBuilder
|
||||
// Find the height of the solution
|
||||
for (int i = 0; i < track.size(); ++i)
|
||||
{
|
||||
uint32 bottom = static_cast<uint32>(AZStd::max(0, track[i].GetBottom()));
|
||||
uint32_t bottom = static_cast<uint32_t>(AZStd::max(0, track[i].GetBottom()));
|
||||
if (height < bottom)
|
||||
{
|
||||
height = bottom;
|
||||
@@ -1411,7 +1366,7 @@ namespace TextureAtlasBuilder
|
||||
if (powerOfTwo)
|
||||
{
|
||||
// Starting dimensions need to be rounded up to the nearest power of two
|
||||
height = aznumeric_cast<AZ::u32>(pow(2, 1 + IntegerLog2(static_cast<uint32>(height - 1))));
|
||||
height = aznumeric_cast<AZ::u32>(pow(2, 1 + IntegerLog2(static_cast<uint32_t>(height - 1))));
|
||||
}
|
||||
|
||||
AZ::u32 resultArea = height * width;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AssetBuilderSDK/AssetBuilderSDK.h>
|
||||
#include <AssetBuilderSDK/AssetBuilderBusses.h>
|
||||
#include <qimage.h>
|
||||
@@ -110,7 +111,7 @@ namespace TextureAtlasBuilder
|
||||
enum class Product
|
||||
{
|
||||
TexatlasidxProduct = 0,
|
||||
DdsProduct = 1
|
||||
StreamingImageProduct = 1
|
||||
};
|
||||
|
||||
//! An asset builder for texture atlases
|
||||
|
||||
@@ -120,14 +120,14 @@ namespace TextureAtlasNamespace
|
||||
}
|
||||
|
||||
// Links this atlas to an image pointer
|
||||
void TextureAtlasImpl::SetTexture(ITexture* image)
|
||||
void TextureAtlasImpl::SetTexture(AZ::Data::Instance<AZ::RPI::Image> image)
|
||||
{
|
||||
// We don't need to delete the old value because the pointer is handled elsewhere
|
||||
m_image = image;
|
||||
}
|
||||
|
||||
// Returns the image linked to this atlas
|
||||
ITexture* TextureAtlasImpl::GetTexture() const
|
||||
AZ::Data::Instance<AZ::RPI::Image> TextureAtlasImpl::GetTexture() const
|
||||
{
|
||||
return m_image;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
#include "TextureAtlas/TextureAtlas.h"
|
||||
#include "TextureAtlas/TextureAtlasBus.h"
|
||||
|
||||
#include <ITexture.h>
|
||||
#include <Atom/RPI.Reflect/Image/Image.h>
|
||||
#include <AtomCore/Instance/Instance.h>
|
||||
|
||||
namespace TextureAtlasNamespace
|
||||
{
|
||||
@@ -61,10 +62,10 @@ namespace TextureAtlasNamespace
|
||||
AtlasCoordinates GetAtlasCoordinates(const AZStd::string& handle) const override;
|
||||
|
||||
//! Links this atlas to an image pointer
|
||||
void SetTexture(ITexture* image) override;
|
||||
void SetTexture(AZ::Data::Instance<AZ::RPI::Image> image) override;
|
||||
|
||||
//! Returns the image linked to this atlas
|
||||
ITexture* GetTexture() const override;
|
||||
AZ::Data::Instance<AZ::RPI::Image> GetTexture() const override;
|
||||
|
||||
//! Replaces the mappings of this Texture Atlas Object, with the source's mappings
|
||||
void OverwriteMappings(TextureAtlasImpl* source);
|
||||
@@ -80,7 +81,7 @@ namespace TextureAtlasNamespace
|
||||
|
||||
private:
|
||||
AZStd::unordered_map<AZStd::string, AtlasCoordinates, hash_case_insensitive, equal_to_case_insensitive> m_data;
|
||||
ITexture* m_image;
|
||||
AZ::Data::Instance<AZ::RPI::Image> m_image;
|
||||
int m_width;
|
||||
int m_height;
|
||||
};
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
#include "TextureAtlasSystemComponent.h"
|
||||
|
||||
#ifdef TEXTUREATLAS_EDITOR
|
||||
#include "Editor/AtlasBuilderComponent.h"
|
||||
#endif
|
||||
|
||||
#include <IGem.h>
|
||||
|
||||
namespace TextureAtlasNamespace
|
||||
@@ -33,6 +37,9 @@ namespace TextureAtlasNamespace
|
||||
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
|
||||
m_descriptors.insert(m_descriptors.end(), {
|
||||
TextureAtlasSystemComponent::CreateDescriptor(),
|
||||
#ifdef TEXTUREATLAS_EDITOR
|
||||
TextureAtlasBuilder::AtlasBuilderComponent::CreateDescriptor(), //builder component for texture atlas
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,25 @@
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <IRenderer.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImage.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
AZ::Data::Instance<AZ::RPI::Image> LoadAtlasImage(const AZStd::string& imagePath)
|
||||
{
|
||||
// The file may not be in the AssetCatalog at this point if it is still processing or doesn't exist on disk.
|
||||
// Use GenerateAssetIdTEMP instead of GetAssetIdByPath so that it will return a valid AssetId anyways
|
||||
AZ::Data::AssetId streamingImageAssetId;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
|
||||
streamingImageAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GenerateAssetIdTEMP,
|
||||
imagePath.c_str());
|
||||
|
||||
streamingImageAssetId.m_subId = AZ::RPI::StreamingImageAsset::GetImageAssetSubId();
|
||||
auto streamingImageAsset = AZ::Data::AssetManager::Instance().FindOrCreateAsset<AZ::RPI::StreamingImageAsset>(streamingImageAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
AZ::Data::Instance<AZ::RPI::Image> image = AZ::RPI::StreamingImage::FindOrCreate(streamingImageAsset);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
namespace TextureAtlasNamespace
|
||||
{
|
||||
@@ -95,27 +113,15 @@ namespace TextureAtlasNamespace
|
||||
// We reload the image here to prevent stuttering in the editor
|
||||
if (iterator->second.m_atlas && iterator->second.m_atlas->GetTexture())
|
||||
{
|
||||
SResourceAsync* pInfo = new SResourceAsync();
|
||||
pInfo->eClassName = eRCN_Texture;
|
||||
pInfo->pResource = iterator->second.m_atlas->GetTexture();
|
||||
// ToDo: Update to work with Atom? LYN-3680
|
||||
// ???->ReleaseResourceAsync(pInfo);
|
||||
iterator->second.m_atlas->GetTexture().reset();
|
||||
}
|
||||
// Reload Texture
|
||||
AZStd::string imagePath = iterator->second.m_path.substr(0, iterator->second.m_path.find_last_of('.'));
|
||||
imagePath.append(".dds");
|
||||
|
||||
// ToDo: Update to work with Atom? LYN-3680
|
||||
// uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
|
||||
ITexture* texture = nullptr;
|
||||
|
||||
if (!texture || !texture->IsTextureLoaded())
|
||||
AZStd::string imagePath = iterator->second.m_path;
|
||||
AZ::Data::Instance<AZ::RPI::Image> texture = LoadAtlasImage(imagePath);
|
||||
if (!texture)
|
||||
{
|
||||
gEnv->pSystem->Warning(VALIDATOR_MODULE_UNKNOWN,
|
||||
VALIDATOR_WARNING,
|
||||
VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
|
||||
imagePath.c_str(),
|
||||
"No texture file found for texture atlas: %s. "
|
||||
AZ_Error("TextureAtlasSystemComponent",
|
||||
false,
|
||||
"Failed to find or create an image instance for texture atlas '%s'"
|
||||
"NOTE: File must be in current project or a gem.",
|
||||
imagePath.c_str());
|
||||
TextureAtlas* temp = iterator->second.m_atlas;
|
||||
@@ -123,6 +129,7 @@ namespace TextureAtlasNamespace
|
||||
TextureAtlasNotificationBus::Broadcast(&TextureAtlasNotifications::OnAtlasUnloaded, temp);
|
||||
return;
|
||||
}
|
||||
|
||||
iterator->second.m_atlas->SetTexture(texture);
|
||||
TextureAtlasNotificationBus::Broadcast(&TextureAtlasNotifications::OnAtlasReloaded, iterator->second.m_atlas);
|
||||
break;
|
||||
@@ -186,30 +193,23 @@ namespace TextureAtlasNamespace
|
||||
delete[] buffer;
|
||||
if (loadedAtlas)
|
||||
{
|
||||
// Get the image path based on the atlas path
|
||||
// Convert to image path based on the atlas path
|
||||
AZStd::string imagePath = path;
|
||||
AzFramework::StringFunc::Path::ReplaceExtension(imagePath, "dds");
|
||||
|
||||
// Load the image in
|
||||
// ToDo: Update to work with Atom? LYN-3680
|
||||
// uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
|
||||
ITexture* texture = nullptr;
|
||||
|
||||
if (!texture || !texture->IsTextureLoaded())
|
||||
AzFramework::StringFunc::Path::ReplaceExtension(imagePath, "texatlas");
|
||||
AZ::Data::Instance<AZ::RPI::Image> texture = LoadAtlasImage(imagePath);
|
||||
if (!texture)
|
||||
{
|
||||
gEnv->pSystem->Warning(VALIDATOR_MODULE_UNKNOWN,
|
||||
VALIDATOR_WARNING,
|
||||
VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
|
||||
imagePath.c_str(),
|
||||
"No texture file found for texture atlas: %s. "
|
||||
AZ_Error("TextureAtlasSystemComponent",
|
||||
false,
|
||||
"Failed to find or create an image instance for texture atlas '%s'"
|
||||
"NOTE: File must be in current project or a gem.",
|
||||
imagePath.c_str());
|
||||
path.c_str());
|
||||
|
||||
delete loadedAtlas;
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture->SetFilter(FILTER_LINEAR);
|
||||
// Add the atlas to the list
|
||||
AtlasInfo info(loadedAtlas, assetPath);
|
||||
++info.m_refs;
|
||||
@@ -241,11 +241,7 @@ namespace TextureAtlasNamespace
|
||||
// Tell the renderer to release the texture.
|
||||
if (temp.m_atlas && temp.m_atlas->GetTexture())
|
||||
{
|
||||
SResourceAsync* pInfo = new SResourceAsync();
|
||||
pInfo->eClassName = eRCN_Texture;
|
||||
pInfo->pResource = temp.m_atlas->GetTexture();
|
||||
// ToDo: Update to work with Atom? LYN-3680
|
||||
// ???->ReleaseResourceAsync(pInfo);
|
||||
temp.m_atlas->GetTexture().reset();
|
||||
}
|
||||
// Delete the atlas
|
||||
SAFE_DELETE(temp.m_atlas);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Source/Editor/AtlasBuilderComponent.h
|
||||
Source/Editor/AtlasBuilderComponent.cpp
|
||||
Source/Editor/AtlasBuilderWorker.h
|
||||
Source/Editor/AtlasBuilderWorker.cpp
|
||||
)
|
||||
@@ -15,7 +15,6 @@ set(FILES
|
||||
Include/TextureAtlas/TextureAtlasBus.h
|
||||
Include/TextureAtlas/TextureAtlasNotificationBus.h
|
||||
Include/TextureAtlas/TextureAtlas.h
|
||||
Source/TextureAtlasModule.cpp
|
||||
Source/TextureAtlasSystemComponent.cpp
|
||||
Source/TextureAtlasSystemComponent.h
|
||||
Source/TextureAtlasImpl.h
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Source/TextureAtlasModule.cpp
|
||||
)
|
||||
@@ -370,6 +370,7 @@ endfunction()
|
||||
#! ly_add_googletest: Adds a new RUN_TEST using for the specified target using the supplied command or fallback to running
|
||||
# googletest tests through AzTestRunner
|
||||
# \arg:NAME Name to for the test run target
|
||||
# \arg:TARGET Name of the target module that is being run for tests. If not provided, will default to 'NAME'
|
||||
# \arg:TEST_REQUIRES(optional) List of system resources that are required to run this test.
|
||||
# Only available option is "gpu"
|
||||
# \arg:TEST_SUITE(optional) - "smoke" or "periodic" or "sandbox" - prevents the test from running normally
|
||||
@@ -384,14 +385,20 @@ function(ly_add_googletest)
|
||||
message(FATAL_ERROR "Platform does not support test targets")
|
||||
endif()
|
||||
|
||||
set(one_value_args NAME TEST_SUITE)
|
||||
set(one_value_args NAME TARGET TEST_SUITE)
|
||||
set(multi_value_args TEST_COMMAND COMPONENT)
|
||||
cmake_parse_arguments(ly_add_googletest "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||
|
||||
if (ly_add_googletest_TARGET)
|
||||
set(target_name ${ly_add_googletest_TARGET})
|
||||
else()
|
||||
set(target_name ${ly_add_googletest_NAME})
|
||||
endif()
|
||||
|
||||
|
||||
# AzTestRunner modules only supports google test libraries, regardless of whether or not
|
||||
# google test suites are supported
|
||||
set_property(GLOBAL APPEND PROPERTY LY_AZTESTRUNNER_TEST_MODULES "${ly_add_googletest_NAME}")
|
||||
set_property(GLOBAL APPEND PROPERTY LY_AZTESTRUNNER_TEST_MODULES "${target_name}")
|
||||
|
||||
if(NOT PAL_TRAIT_TEST_GOOGLE_TEST_SUPPORTED)
|
||||
return()
|
||||
@@ -400,7 +407,7 @@ function(ly_add_googletest)
|
||||
|
||||
if (ly_add_googletest_TEST_SUITE AND NOT ly_add_googletest_TEST_SUITE STREQUAL "main")
|
||||
# if a suite is specified, we filter to only accept things which match that suite (in c++)
|
||||
set(non_ide_params "-gtest_filter=*SUITE_${ly_add_googletest_TEST_SUITE}*")
|
||||
set(non_ide_params "--gtest_filter=*SUITE_${ly_add_googletest_TEST_SUITE}*")
|
||||
else()
|
||||
# otherwise, if its the main suite we only runs things that dont have any of the other suites.
|
||||
# Note: it doesn't do AND, only 'or' - so specifying SUITE_main:REQUIRES_gpu
|
||||
@@ -412,11 +419,11 @@ function(ly_add_googletest)
|
||||
|
||||
if(NOT ly_add_googletest_TEST_COMMAND)
|
||||
# Use the NAME parameter as the build target
|
||||
set(build_target ${ly_add_googletest_NAME})
|
||||
set(build_target ${target_name})
|
||||
ly_strip_target_namespace(TARGET ${build_target} OUTPUT_VARIABLE build_target)
|
||||
|
||||
if(NOT TARGET ${build_target})
|
||||
message(FATAL_ERROR "A valid build target \"${build_target}\" for test run \"${ly_add_googletest_NAME}\" has not been found.\
|
||||
message(FATAL_ERROR "A valid build target \"${build_target}\" for test run \"${target_name}\" has not been found.\
|
||||
A valid target via the TARGET parameter or a custom TEST_COMMAND must be supplied")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "all",
|
||||
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest --repeat until-pass:5"
|
||||
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
|
||||
}
|
||||
},
|
||||
"test_profile_nounity": {
|
||||
@@ -95,7 +95,7 @@
|
||||
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "all",
|
||||
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest --repeat until-pass:5"
|
||||
"CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
|
||||
}
|
||||
},
|
||||
"asset_profile": {
|
||||
@@ -143,7 +143,26 @@
|
||||
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "TEST_SUITE_periodic",
|
||||
"CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
|
||||
"CTEST_OPTIONS": "-L (SUITE_periodic)"
|
||||
}
|
||||
},
|
||||
"sandbox_test_profile": {
|
||||
"TAGS": [
|
||||
"nightly-incremental",
|
||||
"nightly-clean",
|
||||
"weekly-build-metrics"
|
||||
],
|
||||
"PIPELINE_ENV": {
|
||||
"ON_FAILURE_MARK": "UNSTABLE"
|
||||
},
|
||||
"COMMAND": "build_test_linux.sh",
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "profile",
|
||||
"OUTPUT_DIRECTORY": "build/linux",
|
||||
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "all",
|
||||
"CTEST_OPTIONS": "-L (SUITE_sandbox)"
|
||||
}
|
||||
},
|
||||
"benchmark_test_profile": {
|
||||
@@ -159,7 +178,7 @@
|
||||
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "TEST_SUITE_benchmark",
|
||||
"CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
|
||||
"CTEST_OPTIONS": "-L (SUITE_benchmark)"
|
||||
}
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -34,7 +34,7 @@ from cmake.Tools import registration
|
||||
|
||||
o3de_folder = registration.get_o3de_folder()
|
||||
o3de_logs_folder = registration.get_o3de_logs_folder()
|
||||
project_manager_log_file_path = o3de_log_folder / "project_manager.log"
|
||||
project_manager_log_file_path = o3de_logs_folder / "project_manager.log"
|
||||
log_file_handler = RotatingFileHandler(filename=project_manager_log_file_path, maxBytes=1024 * 1024, backupCount=1)
|
||||
formatter = logging.Formatter('%(asctime)s | %(levelname)s : %(message)s')
|
||||
log_file_handler.setFormatter(formatter)
|
||||
|
||||
Reference in New Issue
Block a user