Merge branch 'development' of https://github.com/o3de/o3de into jckand/EditorPrefabTests
Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com>
This commit is contained in:
@@ -12,12 +12,36 @@ import sys
|
||||
import os
|
||||
import pytest
|
||||
import logging
|
||||
import sqlite3
|
||||
pytest.importorskip('ly_test_tools')
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
import ly_test_tools.log.log_monitor
|
||||
import ly_test_tools.environment.waiter as waiter
|
||||
|
||||
def detect_product(sql_connection, platform, target):
|
||||
cur = sql_connection.cursor()
|
||||
product_target = f'{platform}/{target}'
|
||||
print(f'Detecting {product_target} in assetdb.sqlite')
|
||||
hits = 0
|
||||
for row in cur.execute(f'select ProductID from Products where ProductName is "{product_target}"'):
|
||||
hits = hits + 1
|
||||
assert hits == 1
|
||||
|
||||
|
||||
def find_products(cache_folder, platform):
|
||||
con = sqlite3.connect(os.path.join(cache_folder, 'assetdb.sqlite'))
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel')
|
||||
detect_product(con, platform, 'gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel')
|
||||
con.close()
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize('launcher_platform', ['windows_editor'])
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@@ -25,16 +49,7 @@ import ly_test_tools.environment.waiter as waiter
|
||||
class TestPythonAssetProcessing(object):
|
||||
def test_DetectPythonCreatedAsset(self, request, editor, level, launcher_platform):
|
||||
unexpected_lines = []
|
||||
expected_lines = [
|
||||
'Mock asset exists',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found'
|
||||
]
|
||||
expected_lines = []
|
||||
timeout = 180
|
||||
halt_on_unexpected = False
|
||||
test_directory = os.path.join(os.path.dirname(__file__))
|
||||
@@ -50,3 +65,9 @@ class TestPythonAssetProcessing(object):
|
||||
exc=("Log file '{}' was never opened by another process.".format(editorlog_file)),
|
||||
interval=1)
|
||||
log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout)
|
||||
|
||||
cache_folder = editor.workspace.paths.cache()
|
||||
platform = editor.workspace.asset_processor_platform
|
||||
if platform == 'windows':
|
||||
platform = 'pc'
|
||||
find_products(cache_folder, platform)
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ def output_test_data(scene):
|
||||
# Just write something to the file, but the filename is the main information
|
||||
# used for the test.
|
||||
f.write(f"scene.sourceFilename: {scene.sourceFilename}\n")
|
||||
return True
|
||||
return ''
|
||||
|
||||
mySceneJobHandler = None
|
||||
|
||||
|
||||
@@ -0,0 +1,566 @@
|
||||
{
|
||||
"ContainerEntity": {
|
||||
"Id": "ContainerEntity",
|
||||
"Name": "ShadowTest",
|
||||
"Components": {
|
||||
"Component_[10182366347512475253]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 10182366347512475253
|
||||
},
|
||||
"Component_[12917798267488243668]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 12917798267488243668
|
||||
},
|
||||
"Component_[3261249813163778338]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3261249813163778338
|
||||
},
|
||||
"Component_[3837204912784440039]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 3837204912784440039
|
||||
},
|
||||
"Component_[4272963378099646759]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 4272963378099646759,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[4848458548047175816]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 4848458548047175816
|
||||
},
|
||||
"Component_[5787060997243919943]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 5787060997243919943
|
||||
},
|
||||
"Component_[7804170251266531779]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7804170251266531779
|
||||
},
|
||||
"Component_[7874177159288365422]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 7874177159288365422
|
||||
},
|
||||
"Component_[8018146290632383969]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 8018146290632383969
|
||||
},
|
||||
"Component_[8452360690590857075]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 8452360690590857075
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[232650527119]": {
|
||||
"Id": "Entity_[232650527119]",
|
||||
"Name": "DirectionalLight",
|
||||
"Components": {
|
||||
"Component_[10660156197505313227]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 10660156197505313227
|
||||
},
|
||||
"Component_[14184823757717157844]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14184823757717157844,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 9854879901259791898
|
||||
},
|
||||
{
|
||||
"ComponentId": 3968519938187714949,
|
||||
"SortIndex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[1495573908681275492]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 1495573908681275492
|
||||
},
|
||||
"Component_[15580233403487968826]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 15580233403487968826
|
||||
},
|
||||
"Component_[3968519938187714949]": {
|
||||
"$type": "AZ::Render::EditorDirectionalLightComponent",
|
||||
"Id": 3968519938187714949,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Intensity": 0.0,
|
||||
"CameraEntityId": "",
|
||||
"ShadowmapSize": "Size2048"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[4961040003466069196]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 4961040003466069196
|
||||
},
|
||||
"Component_[7824884165323036147]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 7824884165323036147
|
||||
},
|
||||
"Component_[8741866916946672319]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 8741866916946672319
|
||||
},
|
||||
"Component_[9288966876314965560]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 9288966876314965560
|
||||
},
|
||||
"Component_[9313163355156975968]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 9313163355156975968
|
||||
},
|
||||
"Component_[9854879901259791898]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 9854879901259791898,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.0,
|
||||
0.0,
|
||||
2.0
|
||||
],
|
||||
"Rotate": [
|
||||
-32.05662536621094,
|
||||
-26.103206634521484,
|
||||
47.54806137084961
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[260824893221]": {
|
||||
"Id": "Entity_[260824893221]",
|
||||
"Name": "SpotLight",
|
||||
"Components": {
|
||||
"Component_[16098295228434057928]": {
|
||||
"$type": "EditorDiskShapeComponent",
|
||||
"Id": 16098295228434057928,
|
||||
"ShapeColor": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"DiskShape": {
|
||||
"Configuration": {
|
||||
"Radius": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[16175995808158769171]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 16175995808158769171,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.6417449712753296,
|
||||
1.3211734294891357,
|
||||
3.022759199142456
|
||||
],
|
||||
"Rotate": [
|
||||
243.31329345703125,
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[17136787899581093377]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 17136787899581093377
|
||||
},
|
||||
"Component_[17938027566627202610]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 17938027566627202610
|
||||
},
|
||||
"Component_[190081405128299223]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 190081405128299223
|
||||
},
|
||||
"Component_[2181418147135573579]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 2181418147135573579
|
||||
},
|
||||
"Component_[2564149706319215342]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 2564149706319215342
|
||||
},
|
||||
"Component_[3716169383940064541]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 3716169383940064541,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 16175995808158769171
|
||||
},
|
||||
{
|
||||
"ComponentId": 16665800442781289114,
|
||||
"SortIndex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[4143676462074671972]": {
|
||||
"$type": "AZ::Render::EditorAreaLightComponent",
|
||||
"Id": 4143676462074671972,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"LightType": 2,
|
||||
"AttenuationRadius": 31.62277603149414,
|
||||
"EnableShutters": true,
|
||||
"InnerShutterAngleDegrees": 22.5,
|
||||
"OuterShutterAngleDegrees": 27.5,
|
||||
"Enable Shadow": true,
|
||||
"Shadowmap Max Size": "Size2048",
|
||||
"Filtering Sample Count": 32
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[6706371214647538019]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 6706371214647538019
|
||||
},
|
||||
"Component_[7493944209625718550]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7493944209625718550
|
||||
},
|
||||
"Component_[7614113482082939165]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 7614113482082939165
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[269117486973]": {
|
||||
"Id": "Entity_[269117486973]",
|
||||
"Name": "Floor",
|
||||
"Components": {
|
||||
"Component_[10562678944594915756]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 10562678944594915756
|
||||
},
|
||||
"Component_[1175452962278157526]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 1175452962278157526
|
||||
},
|
||||
"Component_[13598353801231166887]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 13598353801231166887
|
||||
},
|
||||
"Component_[13735087293504923475]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 13735087293504923475
|
||||
},
|
||||
"Component_[13888244442459268363]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 13888244442459268363,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{E65E9ED3-3E38-5ABA-9E22-95E34DA4C3AE}",
|
||||
"subId": 280178048
|
||||
},
|
||||
"assetHint": "objects/plane.azmodel"
|
||||
},
|
||||
"LodOverride": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[1525720357937234014]": {
|
||||
"$type": "EditorMaterialComponent",
|
||||
"Id": 1525720357937234014,
|
||||
"materialSlotsByLodEnabled": true
|
||||
},
|
||||
"Component_[16568998871680422442]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 16568998871680422442
|
||||
},
|
||||
"Component_[2147751093058990131]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 2147751093058990131,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 3266761149114817871
|
||||
},
|
||||
{
|
||||
"ComponentId": 13888244442459268363,
|
||||
"SortIndex": 1
|
||||
},
|
||||
{
|
||||
"ComponentId": 1525720357937234014,
|
||||
"SortIndex": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[3266761149114817871]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 3266761149114817871,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Scale": [
|
||||
100.0,
|
||||
100.0,
|
||||
100.0
|
||||
],
|
||||
"UniformScale": 100.0
|
||||
}
|
||||
},
|
||||
"Component_[4625895382416898670]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 4625895382416898670
|
||||
},
|
||||
"Component_[4856699190357614535]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 4856699190357614535
|
||||
},
|
||||
"Component_[6466465153982575739]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 6466465153982575739
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[282757803856]": {
|
||||
"Id": "Entity_[282757803856]",
|
||||
"Name": "Cube",
|
||||
"Components": {
|
||||
"Component_[11189870094752260272]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 11189870094752260272
|
||||
},
|
||||
"Component_[11909086967677513257]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 11909086967677513257,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{593006BE-FE73-5A4B-A0A6-06C02EFFE458}",
|
||||
"subId": 285127096
|
||||
},
|
||||
"loadBehavior": "PreLoad",
|
||||
"assetHint": "objects/cube.azmodel"
|
||||
},
|
||||
"LodOverride": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[1443341568598731610]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 1443341568598731610
|
||||
},
|
||||
"Component_[18339772707807258951]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 18339772707807258951,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.6083869934082031,
|
||||
3.137901782989502,
|
||||
0.5876787900924683
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[2447207272572065708]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 2447207272572065708
|
||||
},
|
||||
"Component_[3281906807632213471]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 3281906807632213471
|
||||
},
|
||||
"Component_[3412442673858204671]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 3412442673858204671
|
||||
},
|
||||
"Component_[5382641380294287889]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 5382641380294287889
|
||||
},
|
||||
"Component_[7221534636342494619]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 7221534636342494619,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 18339772707807258951
|
||||
},
|
||||
{
|
||||
"ComponentId": 11909086967677513257,
|
||||
"SortIndex": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[7701217952253676487]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7701217952253676487
|
||||
},
|
||||
"Component_[7758436981023123121]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 7758436981023123121
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[372196702077]": {
|
||||
"Id": "Entity_[372196702077]",
|
||||
"Name": "Bunny",
|
||||
"Components": {
|
||||
"Component_[11345914745205508221]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 11345914745205508221
|
||||
},
|
||||
"Component_[11507863983962969790]": {
|
||||
"$type": "EditorMaterialComponent",
|
||||
"Id": 11507863983962969790,
|
||||
"materialSlotsByLodEnabled": true
|
||||
},
|
||||
"Component_[1342998773562921470]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 1342998773562921470
|
||||
},
|
||||
"Component_[14975835087235718844]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 14975835087235718844,
|
||||
"ComponentOrderEntryArray": [
|
||||
{
|
||||
"ComponentId": 5012565883129470759
|
||||
},
|
||||
{
|
||||
"ComponentId": 7975043234993822905,
|
||||
"SortIndex": 1
|
||||
},
|
||||
{
|
||||
"ComponentId": 11507863983962969790,
|
||||
"SortIndex": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"Component_[16460806723667032929]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 16460806723667032929
|
||||
},
|
||||
"Component_[18225690044585951363]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 18225690044585951363
|
||||
},
|
||||
"Component_[18314752491697618927]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 18314752491697618927
|
||||
},
|
||||
"Component_[2431610550789583502]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 2431610550789583502
|
||||
},
|
||||
"Component_[5012565883129470759]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 5012565883129470759,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.20401419699192047
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[7975043234993822905]": {
|
||||
"$type": "AZ::Render::EditorMeshComponent",
|
||||
"Id": 7975043234993822905,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{0C6BBB76-4EC2-583A-B8C6-1A4C4FD1FE9D}",
|
||||
"subId": 283109893
|
||||
},
|
||||
"assetHint": "objects/bunny.azmodel"
|
||||
},
|
||||
"LodOverride": 255
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[8510666363380501112]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 8510666363380501112
|
||||
},
|
||||
"Component_[9639060480533776634]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 9639060480533776634
|
||||
}
|
||||
}
|
||||
},
|
||||
"Entity_[670308843764]": {
|
||||
"Id": "Entity_[670308843764]",
|
||||
"Name": "Camera1",
|
||||
"Components": {
|
||||
"Component_[12951260100632682169]": {
|
||||
"$type": "GenericComponentWrapper",
|
||||
"Id": 12951260100632682169,
|
||||
"m_template": {
|
||||
"$type": "FlyCameraInputComponent"
|
||||
}
|
||||
},
|
||||
"Component_[14180723329646459524]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 14180723329646459524
|
||||
},
|
||||
"Component_[14996469885773917977]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 14996469885773917977,
|
||||
"Parent Entity": "ContainerEntity",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
4.563776969909668,
|
||||
0.7667046785354614,
|
||||
3.000542640686035
|
||||
],
|
||||
"Rotate": [
|
||||
-9.740042686462402,
|
||||
-20.20942497253418,
|
||||
63.57760238647461
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[17638492356673689530]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 17638492356673689530
|
||||
},
|
||||
"Component_[2421853983468750254]": {
|
||||
"$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
|
||||
"Id": 2421853983468750254,
|
||||
"Controller": {
|
||||
"Configuration": {
|
||||
"Field of View": 90.00020599365234,
|
||||
"EditorEntityId": 666013876468
|
||||
}
|
||||
}
|
||||
},
|
||||
"Component_[2572028619185965684]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 2572028619185965684
|
||||
},
|
||||
"Component_[2782900516907042776]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 2782900516907042776
|
||||
},
|
||||
"Component_[2849166119438883669]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 2849166119438883669
|
||||
},
|
||||
"Component_[4618311795498613781]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 4618311795498613781
|
||||
},
|
||||
"Component_[5402004894214413002]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 5402004894214413002
|
||||
},
|
||||
"Component_[6111028576371006514]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 6111028576371006514
|
||||
},
|
||||
"Component_[8203141294643544464]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 8203141294643544464
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
0,0,0,0,0,0
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f5f7a86a693878c10f91783955cc72535bf7d7c495163087a4c1982f228d27f0
|
||||
size 2145248
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ef71257b240a7e704731806f8cd4b966af5d3c60f22881f9c6a6320180ee71a4
|
||||
size 2496384
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:531b6473b314259504ab595e4983838b5866035ef4d70cedaf4cc9c7d9e65c3a
|
||||
size 24512
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e32877eab35459499c73ff093df898f93bf3e7379de25eef6875d693be9bec81
|
||||
size 18015
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2949a50eec079a7d43a1d92e056c580ef625ee39e00e91cc25318319e37dcd3b
|
||||
size 115689
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0a1f8d75dcd85e8b4aa57f6c0c81af0300ff96915ba3c2b591095c215d5e1d8c
|
||||
size 12072
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e3bcfac5de831c269dac58e7d73d1dc61eb8d9f6d8a241f5c029537b6bcdf166
|
||||
size 1088304
|
||||
@@ -28,7 +28,7 @@ def update_manifest(scene):
|
||||
meshGroup = sceneManifest.add_mesh_group(chunkName)
|
||||
meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, scene.sourceFilename + chunkName)) + '}'
|
||||
sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by test_chunks_builder')
|
||||
sceneManifest.mesh_group_set_origin(meshGroup, None, 0, 0, 0, 1.0)
|
||||
sceneManifest.mesh_group_add_advanced_coordinate_system(meshGroup)
|
||||
for meshIndex in range(len(chunkNameList)):
|
||||
if (activeMeshIndex == meshIndex):
|
||||
sceneManifest.mesh_group_select_node(meshGroup, chunkNameList[meshIndex])
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "DeepSelection.h"
|
||||
|
||||
// Editor
|
||||
#include "Objects/BaseObject.h"
|
||||
|
||||
|
||||
//! Functor for sorting selected objects on deep selection mode.
|
||||
struct NearDistance
|
||||
{
|
||||
NearDistance(){}
|
||||
bool operator()(const CDeepSelection::RayHitObject& lhs, const CDeepSelection::RayHitObject& rhs) const
|
||||
{
|
||||
return lhs.distance < rhs.distance;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CDeepSelection::CDeepSelection()
|
||||
: m_Mode(DSM_NONE)
|
||||
, m_previousMode(DSM_NONE)
|
||||
, m_CandidateObjectCount(0)
|
||||
, m_CurrentSelectedPos(-1)
|
||||
{
|
||||
m_LastPickPoint = QPoint(-1, -1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CDeepSelection::~CDeepSelection()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDeepSelection::Reset(bool bResetLastPick)
|
||||
{
|
||||
for (int i = 0; i < m_CandidateObjectCount; ++i)
|
||||
{
|
||||
m_RayHitObjects[i].object->ClearFlags(OBJFLAG_NO_HITTEST);
|
||||
}
|
||||
|
||||
m_CandidateObjectCount = 0;
|
||||
m_CurrentSelectedPos = -1;
|
||||
|
||||
m_RayHitObjects.clear();
|
||||
|
||||
if (bResetLastPick)
|
||||
{
|
||||
m_LastPickPoint = QPoint(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDeepSelection::AddObject(float distance, CBaseObject* pObj)
|
||||
{
|
||||
m_RayHitObjects.push_back(RayHitObject(distance, pObj));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDeepSelection::OnCycling (const QPoint& pt)
|
||||
{
|
||||
QPoint diff = m_LastPickPoint - pt;
|
||||
LONG epsilon = 2;
|
||||
m_LastPickPoint = pt;
|
||||
|
||||
if (abs(diff.x()) < epsilon && abs(diff.y()) < epsilon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDeepSelection::ExcludeHitTest(int except)
|
||||
{
|
||||
int nExcept = except % m_CandidateObjectCount;
|
||||
|
||||
for (int i = 0; i < m_CandidateObjectCount; ++i)
|
||||
{
|
||||
m_RayHitObjects[i].object->SetFlags(OBJFLAG_NO_HITTEST);
|
||||
}
|
||||
|
||||
m_RayHitObjects[nExcept].object->ClearFlags(OBJFLAG_NO_HITTEST);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDeepSelection::CollectCandidate(float fMinDistance, float fRange)
|
||||
{
|
||||
m_CandidateObjectCount = 0;
|
||||
|
||||
if (!m_RayHitObjects.empty())
|
||||
{
|
||||
std::sort(m_RayHitObjects.begin(), m_RayHitObjects.end(), NearDistance());
|
||||
|
||||
for (std::vector<CDeepSelection::RayHitObject>::iterator itr = m_RayHitObjects.begin();
|
||||
itr != m_RayHitObjects.end(); ++itr)
|
||||
{
|
||||
if (itr->distance - fMinDistance < fRange)
|
||||
{
|
||||
++m_CandidateObjectCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_CandidateObjectCount;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseObject* CDeepSelection::GetCandidateObject(int index)
|
||||
{
|
||||
m_CurrentSelectedPos = index % m_CandidateObjectCount;
|
||||
|
||||
return m_RayHitObjects[m_CurrentSelectedPos].object;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//!
|
||||
void CDeepSelection::SetMode(EDeepSelectionMode mode)
|
||||
{
|
||||
m_previousMode = m_Mode;
|
||||
m_Mode = mode;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Deep Selection Header
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
||||
#define CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
||||
#pragma once
|
||||
|
||||
class CBaseObject;
|
||||
|
||||
//! Deep Selection
|
||||
//! Additional output information of HitContext on using "deep selection mode".
|
||||
//! At the deep selection mode, it supports second selection pass for easy
|
||||
//! selection on crowded area with two different method.
|
||||
//! One is to show pop menu of candidate objects list. Another is the cyclic
|
||||
//! selection on pick clicking.
|
||||
class CDeepSelection
|
||||
: public _i_reference_target_t
|
||||
{
|
||||
public:
|
||||
//! Deep Selection Mode Definition
|
||||
enum EDeepSelectionMode
|
||||
{
|
||||
DSM_NONE = 0, // Not using deep selection.
|
||||
DSM_POP = 1, // Deep selection mode with pop context menu.
|
||||
DSM_CYCLE = 2 // Deep selection mode with cyclic selection on each clinking same point.
|
||||
};
|
||||
|
||||
//! Subclass for container of the selected object with hit distance.
|
||||
struct RayHitObject
|
||||
{
|
||||
RayHitObject(float dist, CBaseObject* pObj)
|
||||
: distance(dist)
|
||||
, object(pObj)
|
||||
{
|
||||
}
|
||||
|
||||
float distance;
|
||||
CBaseObject* object;
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
CDeepSelection();
|
||||
virtual ~CDeepSelection();
|
||||
|
||||
void Reset(bool bResetLastPick = false);
|
||||
void AddObject(float distance, CBaseObject* pObj);
|
||||
//! Check if clicking point is same position with last position,
|
||||
//! to decide whether to continue cycling mode.
|
||||
bool OnCycling (const QPoint& pt);
|
||||
//! All objects in list are excluded for hitting test except one, current selection.
|
||||
void ExcludeHitTest(int except);
|
||||
void SetMode(EDeepSelectionMode mode);
|
||||
inline EDeepSelectionMode GetMode() const { return m_Mode; }
|
||||
inline EDeepSelectionMode GetPreviousMode() const { return m_previousMode; }
|
||||
//! Collect object in the deep selection range. The distance from the minimum
|
||||
//! distance is less than deep selection range.
|
||||
int CollectCandidate(float fMinDistance, float fRange);
|
||||
//! Return the candidate object in index position, then it is to be current
|
||||
//! selection position.
|
||||
CBaseObject* GetCandidateObject(int index);
|
||||
//! Return the current selection position that is update in "GetCandidateObject"
|
||||
//! function call.
|
||||
inline int GetCurrentSelectPos() const { return m_CurrentSelectedPos; }
|
||||
//! Return the number of objects in the deep selection range.
|
||||
inline int GetCandidateObjectCount() const { return m_CandidateObjectCount; }
|
||||
|
||||
private:
|
||||
//! Current mode
|
||||
EDeepSelectionMode m_Mode;
|
||||
EDeepSelectionMode m_previousMode;
|
||||
//! Last picking point to check whether cyclic selection continue.
|
||||
QPoint m_LastPickPoint;
|
||||
//! List of the selected objects with ray hitting
|
||||
std::vector<RayHitObject> m_RayHitObjects;
|
||||
int m_CandidateObjectCount;
|
||||
int m_CurrentSelectedPos;
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_EDITMODE_DEEPSELECTION_H
|
||||
@@ -1,587 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "TriMesh.h"
|
||||
|
||||
// Editor
|
||||
#include "Util/fastlib.h"
|
||||
#include "Objects/SubObjSelection.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTriMesh::CTriMesh()
|
||||
{
|
||||
pFaces = nullptr;
|
||||
pVertices = nullptr;
|
||||
pWSVertices = nullptr;
|
||||
pUV = nullptr;
|
||||
pColors = nullptr;
|
||||
pEdges = nullptr;
|
||||
pWeights = nullptr;
|
||||
|
||||
nFacesCount = 0;
|
||||
nVertCount = 0;
|
||||
nUVCount = 0;
|
||||
nEdgeCount = 0;
|
||||
|
||||
selectionType = SO_ELEM_NONE;
|
||||
|
||||
memset(m_streamSize, 0, sizeof(m_streamSize));
|
||||
memset(m_streamSel, 0, sizeof(m_streamSel));
|
||||
streamSelMask = 0;
|
||||
|
||||
m_streamSel[VERTICES] = &vertSel;
|
||||
m_streamSel[EDGES] = &edgeSel;
|
||||
m_streamSel[FACES] = &faceSel;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTriMesh::~CTriMesh()
|
||||
{
|
||||
free(pFaces);
|
||||
free(pEdges);
|
||||
free(pVertices);
|
||||
free(pUV);
|
||||
free(pColors);
|
||||
free(pWSVertices);
|
||||
free(pWeights);
|
||||
}
|
||||
|
||||
// Set stream size.
|
||||
void CTriMesh::ReallocStream(int stream, int nNewCount)
|
||||
{
|
||||
assert(stream >= 0 && stream < LAST_STREAM);
|
||||
if (stream < 0 || stream >= LAST_STREAM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_streamSize[stream] == nNewCount)
|
||||
{
|
||||
return; // Stream already have required size.
|
||||
}
|
||||
void* pStream = nullptr;
|
||||
int nElementSize = 0;
|
||||
GetStreamInfo(stream, pStream, nElementSize);
|
||||
pStream = ReAllocElements(pStream, nNewCount, nElementSize);
|
||||
m_streamSize[stream] = nNewCount;
|
||||
|
||||
switch (stream)
|
||||
{
|
||||
case VERTICES:
|
||||
pVertices = (CTriVertex*)pStream;
|
||||
nVertCount = nNewCount;
|
||||
vertSel.resize(nNewCount);
|
||||
break;
|
||||
case FACES:
|
||||
pFaces = (CTriFace*)pStream;
|
||||
nFacesCount = nNewCount;
|
||||
faceSel.resize(nNewCount);
|
||||
break;
|
||||
case EDGES:
|
||||
pEdges = (CTriEdge*)pStream;
|
||||
nEdgeCount = nNewCount;
|
||||
edgeSel.resize(nNewCount);
|
||||
break;
|
||||
case TEXCOORDS:
|
||||
pUV = (SMeshTexCoord*)pStream;
|
||||
nUVCount = nNewCount;
|
||||
break;
|
||||
case COLORS:
|
||||
pColors = (SMeshColor*)pStream;
|
||||
break;
|
||||
case WEIGHTS:
|
||||
pWeights = (float*)pStream;
|
||||
break;
|
||||
case LINES:
|
||||
pLines = (CTriLine*)pStream;
|
||||
break;
|
||||
case WS_POSITIONS:
|
||||
pWSVertices = (Vec3*)pStream;
|
||||
break;
|
||||
default:
|
||||
assert(0); // unknown stream.
|
||||
}
|
||||
m_streamSize[stream] = nNewCount;
|
||||
}
|
||||
|
||||
// Set stream size.
|
||||
void CTriMesh::GetStreamInfo(int stream, void*& pStream, int& nElementSize) const
|
||||
{
|
||||
assert(stream >= 0 && stream < LAST_STREAM);
|
||||
switch (stream)
|
||||
{
|
||||
case VERTICES:
|
||||
pStream = pVertices;
|
||||
nElementSize = sizeof(CTriVertex);
|
||||
break;
|
||||
case FACES:
|
||||
pStream = pFaces;
|
||||
nElementSize = sizeof(CTriFace);
|
||||
break;
|
||||
case EDGES:
|
||||
pStream = pEdges;
|
||||
nElementSize = sizeof(CTriEdge);
|
||||
break;
|
||||
case TEXCOORDS:
|
||||
pStream = pUV;
|
||||
nElementSize = sizeof(SMeshTexCoord);
|
||||
break;
|
||||
case COLORS:
|
||||
pStream = pColors;
|
||||
nElementSize = sizeof(SMeshColor);
|
||||
break;
|
||||
case WEIGHTS:
|
||||
pStream = pWeights;
|
||||
nElementSize = sizeof(float);
|
||||
break;
|
||||
case LINES:
|
||||
pStream = pLines;
|
||||
nElementSize = sizeof(CTriLine);
|
||||
break;
|
||||
case WS_POSITIONS:
|
||||
pStream = pWSVertices;
|
||||
nElementSize = sizeof(Vec3);
|
||||
break;
|
||||
default:
|
||||
assert(0); // unknown stream.
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void* CTriMesh::ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element)
|
||||
{
|
||||
return realloc(old_ptr, new_elem_num * size_of_element);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
inline int FindVertexInHash(const Vec3& vPosToFind, const CTriVertex* pVectors, std::vector<int>& hash, float fEpsilon)
|
||||
{
|
||||
for (uint32 i = 0; i < hash.size(); i++)
|
||||
{
|
||||
const Vec3& v0 = pVectors[hash[i]].pos;
|
||||
const Vec3& v1 = vPosToFind;
|
||||
if (fabsf(v0.y - v1.y) < fEpsilon && fabsf(v0.x - v1.x) < fEpsilon && fabsf(v0.z - v1.z) < fEpsilon)
|
||||
{
|
||||
return hash[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
inline int FindTexCoordInHash(const SMeshTexCoord& coordToFind, const SMeshTexCoord* pCoords, std::vector<int>& hash, float fEpsilon)
|
||||
{
|
||||
for (uint32 i = 0; i < hash.size(); i++)
|
||||
{
|
||||
const SMeshTexCoord& t0 = pCoords[hash[i]];
|
||||
const SMeshTexCoord& t1 = coordToFind;
|
||||
|
||||
if (t0.IsEquivalent(t1, fEpsilon))
|
||||
{
|
||||
return hash[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::SharePositions()
|
||||
{
|
||||
float fEpsilon = 0.0001f;
|
||||
float fHashScale = 256.0f / MAX(bbox.GetSize().GetLength(), fEpsilon);
|
||||
std::vector<int> arrHashTable[256];
|
||||
|
||||
CTriVertex* pNewVerts = new CTriVertex[GetVertexCount()];
|
||||
SMeshColor* pNewColors = nullptr;
|
||||
if (pColors)
|
||||
{
|
||||
pNewColors = new SMeshColor[GetVertexCount()];
|
||||
}
|
||||
|
||||
int nLastIndex = 0;
|
||||
for (int f = 0; f < GetFacesCount(); f++)
|
||||
{
|
||||
CTriFace& face = pFaces[f];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
const Vec3& v = pVertices[face.v[i]].pos;
|
||||
uint8 nHash = static_cast<uint8>(RoundFloatToInt((v.x + v.y + v.z) * fHashScale));
|
||||
|
||||
int find = FindVertexInHash(v, pNewVerts, arrHashTable[nHash], fEpsilon);
|
||||
if (find < 0)
|
||||
{
|
||||
pNewVerts[nLastIndex] = pVertices[face.v[i]];
|
||||
if (pColors)
|
||||
{
|
||||
pNewColors[nLastIndex] = pColors[face.v[i]];
|
||||
}
|
||||
face.v[i] = nLastIndex;
|
||||
// Reserve some space already.
|
||||
arrHashTable[nHash].reserve(100);
|
||||
arrHashTable[nHash].push_back(nLastIndex);
|
||||
nLastIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
face.v[i] = find;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetVertexCount(nLastIndex);
|
||||
memcpy(pVertices, pNewVerts, nLastIndex * sizeof(CTriVertex));
|
||||
delete []pNewVerts;
|
||||
|
||||
if (pColors)
|
||||
{
|
||||
SetColorsCount(nLastIndex);
|
||||
memcpy(pColors, pNewColors, nLastIndex * sizeof(SMeshColor));
|
||||
delete []pNewColors;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::ShareUV()
|
||||
{
|
||||
float fEpsilon = 0.0001f;
|
||||
float fHashScale = 256.0f;
|
||||
std::vector<int> arrHashTable[256];
|
||||
|
||||
SMeshTexCoord* pNewUV = new SMeshTexCoord[GetUVCount()];
|
||||
|
||||
int nLastIndex = 0;
|
||||
for (int f = 0; f < GetFacesCount(); f++)
|
||||
{
|
||||
CTriFace& face = pFaces[f];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
const Vec2 uv = pUV[face.uv[i]].GetUV();
|
||||
uint8 nHash = static_cast<uint8>(RoundFloatToInt((uv.x + uv.y) * fHashScale));
|
||||
|
||||
int find = FindTexCoordInHash(pUV[face.uv[i]], pNewUV, arrHashTable[nHash], fEpsilon);
|
||||
if (find < 0)
|
||||
{
|
||||
pNewUV[nLastIndex] = pUV[face.uv[i]];
|
||||
face.uv[i] = nLastIndex;
|
||||
arrHashTable[nHash].reserve(100);
|
||||
arrHashTable[nHash].push_back(nLastIndex);
|
||||
nLastIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
face.uv[i] = find;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetUVCount(nLastIndex);
|
||||
memcpy(pUV, pNewUV, nLastIndex * sizeof(SMeshTexCoord));
|
||||
delete []pNewUV;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::CalcFaceNormals()
|
||||
{
|
||||
for (int i = 0; i < nFacesCount; i++)
|
||||
{
|
||||
CTriFace& face = pFaces[i];
|
||||
Vec3 p1 = pVertices[face.v[0]].pos;
|
||||
Vec3 p2 = pVertices[face.v[1]].pos;
|
||||
Vec3 p3 = pVertices[face.v[2]].pos;
|
||||
face.normal = (p2 - p1).Cross(p3 - p1);
|
||||
face.normal.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
#define TEX_EPS 0.001f
|
||||
#define VER_EPS 0.001f
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::CopyStream(CTriMesh& fromMesh, int stream)
|
||||
{
|
||||
void* pTrgStream = nullptr;
|
||||
void* pSrcStream = nullptr;
|
||||
int nElemSize = 0;
|
||||
fromMesh.GetStreamInfo(stream, pSrcStream, nElemSize);
|
||||
if (pSrcStream)
|
||||
{
|
||||
ReallocStream(stream, fromMesh.GetStreamSize(stream));
|
||||
GetStreamInfo(stream, pTrgStream, nElemSize);
|
||||
memcpy(pTrgStream, pSrcStream, nElemSize * fromMesh.GetStreamSize(stream));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::Copy(CTriMesh& fromMesh, int nCopyFlags)
|
||||
{
|
||||
streamSelMask = fromMesh.streamSelMask;
|
||||
|
||||
if (nCopyFlags & COPY_VERTICES)
|
||||
{
|
||||
CopyStream(fromMesh, VERTICES);
|
||||
}
|
||||
if (nCopyFlags & COPY_FACES)
|
||||
{
|
||||
CopyStream(fromMesh, FACES);
|
||||
}
|
||||
if (nCopyFlags & COPY_EDGES)
|
||||
{
|
||||
CopyStream(fromMesh, EDGES);
|
||||
}
|
||||
if (nCopyFlags & COPY_TEXCOORDS)
|
||||
{
|
||||
CopyStream(fromMesh, TEXCOORDS);
|
||||
}
|
||||
if (nCopyFlags & COPY_COLORS)
|
||||
{
|
||||
CopyStream(fromMesh, COLORS);
|
||||
}
|
||||
if (nCopyFlags & COPY_WEIGHTS)
|
||||
{
|
||||
CopyStream(fromMesh, WEIGHTS);
|
||||
}
|
||||
if (nCopyFlags & COPY_LINES)
|
||||
{
|
||||
CopyStream(fromMesh, LINES);
|
||||
}
|
||||
|
||||
if (nCopyFlags & COPY_VERT_SEL)
|
||||
{
|
||||
vertSel = fromMesh.vertSel;
|
||||
}
|
||||
if (nCopyFlags & COPY_EDGE_SEL)
|
||||
{
|
||||
edgeSel = fromMesh.edgeSel;
|
||||
}
|
||||
if (nCopyFlags & COPY_FACE_SEL)
|
||||
{
|
||||
faceSel = fromMesh.faceSel;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::UpdateEdges()
|
||||
{
|
||||
SetEdgeCount(GetFacesCount() * 3);
|
||||
|
||||
std::map<CTriEdge, int> edgemap;
|
||||
|
||||
int nEdges = 0;
|
||||
for (int i = 0; i < GetFacesCount(); i++)
|
||||
{
|
||||
CTriFace& face = pFaces[i];
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
int v0 = j;
|
||||
int v1 = (j != 2) ? j + 1 : 0;
|
||||
CTriEdge edge;
|
||||
edge.flags = 0;
|
||||
|
||||
// First vertex index must always be smaller.
|
||||
if (face.v[v0] < face.v[v1])
|
||||
{
|
||||
edge.v[0] = face.v[v0];
|
||||
edge.v[1] = face.v[v1];
|
||||
}
|
||||
else
|
||||
{
|
||||
edge.v[0] = face.v[v1];
|
||||
edge.v[1] = face.v[v0];
|
||||
}
|
||||
edge.face[0] = i;
|
||||
edge.face[1] = -1;
|
||||
int nedge = stl::find_in_map(edgemap, edge, -1);
|
||||
if (nedge >= 0)
|
||||
{
|
||||
// Assign this face as a second member of the edge.
|
||||
if (pEdges[nedge].face[1] < 0)
|
||||
{
|
||||
pEdges[nedge].face[1] = i;
|
||||
}
|
||||
|
||||
face.edge[j] = nedge;
|
||||
}
|
||||
else
|
||||
{
|
||||
edgemap[edge] = nEdges;
|
||||
pEdges[nEdges] = edge;
|
||||
face.edge[j] = nEdges;
|
||||
nEdges++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetEdgeCount(nEdges);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::SoftSelection(const SSubObjSelOptions& options)
|
||||
{
|
||||
int i;
|
||||
int nVerts = GetVertexCount();
|
||||
CTriVertex* pVerts = pVertices;
|
||||
|
||||
for (i = 0; i < nVerts; i++)
|
||||
{
|
||||
if (pWeights[i] == 1.0f)
|
||||
{
|
||||
const Vec3& vp = pVerts[i].pos;
|
||||
for (int j = 0; j < nVerts; j++)
|
||||
{
|
||||
if (pWeights[j] != 1.0f)
|
||||
{
|
||||
if (vp.IsEquivalent(pVerts[j].pos, options.fSoftSelFalloff))
|
||||
{
|
||||
float fDist = vp.GetDistance(pVerts[j].pos);
|
||||
if (fDist < options.fSoftSelFalloff)
|
||||
{
|
||||
float fWeight = 1.0f - (fDist / options.fSoftSelFalloff);
|
||||
if (fWeight > pWeights[j])
|
||||
{
|
||||
pWeights[j] = fWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTriMesh::UpdateSelection()
|
||||
{
|
||||
bool bAnySelected = false;
|
||||
if (selectionType == SO_ELEM_VERTEX)
|
||||
{
|
||||
for (int i = 0; i < GetVertexCount(); i++)
|
||||
{
|
||||
if (vertSel[i])
|
||||
{
|
||||
bAnySelected = true;
|
||||
pWeights[i] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pWeights[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectionType == SO_ELEM_EDGE)
|
||||
{
|
||||
// Clear weights.
|
||||
for (int i = 0; i < GetVertexCount(); i++)
|
||||
{
|
||||
pWeights[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < GetEdgeCount(); i++)
|
||||
{
|
||||
if (edgeSel[i])
|
||||
{
|
||||
bAnySelected = true;
|
||||
CTriEdge& edge = pEdges[i];
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
pWeights[edge.v[j]] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selectionType == SO_ELEM_FACE)
|
||||
{
|
||||
// Clear weights.
|
||||
for (int i = 0; i < GetVertexCount(); i++)
|
||||
{
|
||||
pWeights[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < GetFacesCount(); i++)
|
||||
{
|
||||
if (faceSel[i])
|
||||
{
|
||||
bAnySelected = true;
|
||||
CTriFace& face = pFaces[i];
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
pWeights[face.v[j]] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bAnySelected;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CTriMesh::ClearSelection()
|
||||
{
|
||||
bool bWasSelected = false;
|
||||
// Remove all selections.
|
||||
int i;
|
||||
for (i = 0; i < GetVertexCount(); i++)
|
||||
{
|
||||
pWeights[i] = 0;
|
||||
}
|
||||
streamSelMask = 0;
|
||||
for (int ii = 0; ii < LAST_STREAM; ii++)
|
||||
{
|
||||
if (m_streamSel[ii] && !m_streamSel[ii]->is_zero())
|
||||
{
|
||||
bWasSelected = true;
|
||||
m_streamSel[ii]->clear();
|
||||
}
|
||||
}
|
||||
return bWasSelected;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges)
|
||||
{
|
||||
// Brute force algorithm using binary search.
|
||||
// for every edge check if edge vertex is inside inVertices array.
|
||||
std::sort(inVertices.begin(), inVertices.end());
|
||||
for (int i = 0; i < GetEdgeCount(); i++)
|
||||
{
|
||||
if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pEdges[i].v[0])) != inVertices.end())
|
||||
{
|
||||
outEdges.push_back(i);
|
||||
}
|
||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pEdges[i].v[1])) != inVertices.end())
|
||||
{
|
||||
outEdges.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CTriMesh::GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces)
|
||||
{
|
||||
// Brute force algorithm using binary search.
|
||||
// for every face check if face vertex is inside inVertices array.
|
||||
std::sort(inVertices.begin(), inVertices.end());
|
||||
for (int i = 0; i < GetFacesCount(); i++)
|
||||
{
|
||||
if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[0])) != inVertices.end())
|
||||
{
|
||||
outFaces.push_back(i);
|
||||
}
|
||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[1])) != inVertices.end())
|
||||
{
|
||||
outFaces.push_back(i);
|
||||
}
|
||||
else if (stl::binary_find(inVertices.begin(), inVertices.end(), static_cast<int>(pFaces[i].v[2])) != inVertices.end())
|
||||
{
|
||||
outFaces.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
||||
#define CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
||||
#pragma once
|
||||
|
||||
#include <IIndexedMesh.h>
|
||||
#include "Util/bitarray.h"
|
||||
|
||||
struct SSubObjSelOptions;
|
||||
|
||||
typedef std::vector<int> MeshElementsArray;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Vertex used in the TriMesh.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CTriVertex
|
||||
{
|
||||
Vec3 pos;
|
||||
//float weight; // Selection weight in 0-1 range.
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Triangle face used by the Triangle mesh.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CTriFace
|
||||
{
|
||||
uint32 v[3]; // Indices to vertices array.
|
||||
uint32 uv[3]; // Indices to texture coordinates array.
|
||||
Vec3 n[3]; // Vertex normals at face vertices.
|
||||
Vec3 normal; // Face normal.
|
||||
uint32 edge[3]; // Indices to the face edges.
|
||||
unsigned char MatID; // Index of face sub material.
|
||||
unsigned char flags; // see ETriMeshFlags
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mesh edge.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CTriEdge
|
||||
{
|
||||
uint32 v[2]; // Indices to edge vertices.
|
||||
int face[2]; // Indices to edge faces (-1 if no face).
|
||||
uint32 flags; // see ETriMeshFlags
|
||||
|
||||
CTriEdge() {}
|
||||
bool operator==(const CTriEdge& edge) const
|
||||
{
|
||||
if ((v[0] == edge.v[0] && v[1] == edge.v[1]) ||
|
||||
(v[0] == edge.v[1] && v[1] == edge.v[0]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator!=(const CTriEdge& edge) const { return !(*this == edge); }
|
||||
bool operator<(const CTriEdge& edge) const { return (*(uint64*)v < *(uint64*)edge.v); }
|
||||
bool operator>(const CTriEdge& edge) const { return (*(uint64*)v > *(uint64*)edge.v); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mesh line.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CTriLine
|
||||
{
|
||||
uint32 v[2]; // Indices to edge vertices.
|
||||
|
||||
CTriLine() {}
|
||||
bool operator==(const CTriLine& edge) const
|
||||
{
|
||||
if ((v[0] == edge.v[0] && v[1] == edge.v[1]) ||
|
||||
(v[0] == edge.v[1] && v[1] == edge.v[0]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool operator!=(const CTriLine& edge) const { return !(*this == edge); }
|
||||
bool operator<(const CTriLine& edge) const { return (*(uint64*)v < *(uint64*)edge.v); }
|
||||
bool operator>(const CTriLine& edge) const { return (*(uint64*)v > *(uint64*)edge.v); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct CTriMeshPoly
|
||||
{
|
||||
std::vector<uint32> v; // Indices to vertices array.
|
||||
std::vector<uint32> uv; // Indices to texture coordinates array.
|
||||
std::vector<Vec3> n; // Vertex normals at face vertices.
|
||||
Vec3 normal; // Polygon normal.
|
||||
uint32 edge[3]; // Indices to the face edges.
|
||||
unsigned char MatID; // Index of face sub material.
|
||||
unsigned char flags; // optional flags.
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CTriMesh is used in the Editor as a general purpose editable triangle mesh.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CTriMesh
|
||||
{
|
||||
public:
|
||||
enum EStream
|
||||
{
|
||||
VERTICES,
|
||||
FACES,
|
||||
EDGES,
|
||||
TEXCOORDS,
|
||||
COLORS,
|
||||
WEIGHTS,
|
||||
LINES,
|
||||
WS_POSITIONS,
|
||||
LAST_STREAM,
|
||||
};
|
||||
enum ECopyFlags
|
||||
{
|
||||
COPY_VERTICES = BIT(1),
|
||||
COPY_FACES = BIT(2),
|
||||
COPY_EDGES = BIT(3),
|
||||
COPY_TEXCOORDS = BIT(4),
|
||||
COPY_COLORS = BIT(5),
|
||||
COPY_VERT_SEL = BIT(6),
|
||||
COPY_EDGE_SEL = BIT(7),
|
||||
COPY_FACE_SEL = BIT(8),
|
||||
COPY_WEIGHTS = BIT(9),
|
||||
COPY_LINES = BIT(10),
|
||||
COPY_ALL = 0xFFFF,
|
||||
};
|
||||
// geometry data
|
||||
CTriFace* pFaces;
|
||||
CTriEdge* pEdges;
|
||||
CTriVertex* pVertices;
|
||||
SMeshTexCoord* pUV;
|
||||
SMeshColor* pColors; // If allocated same size as pVerts array.
|
||||
Vec3* pWSVertices; // World space vertices.
|
||||
float* pWeights;
|
||||
CTriLine* pLines;
|
||||
|
||||
int nFacesCount;
|
||||
int nVertCount;
|
||||
int nUVCount;
|
||||
int nEdgeCount;
|
||||
int nLinesCount;
|
||||
|
||||
AABB bbox;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Selections.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBitArray vertSel;
|
||||
CBitArray edgeSel;
|
||||
CBitArray faceSel;
|
||||
// Every bit of the selection mask correspond to a stream, if bit is set this stream have some elements selected
|
||||
int streamSelMask;
|
||||
|
||||
// Selection element type.
|
||||
// see ESubObjElementType
|
||||
int selectionType;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Vertices of the front facing triangles.
|
||||
CBitArray frontFacingVerts;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Functions.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CTriMesh();
|
||||
~CTriMesh();
|
||||
|
||||
int GetFacesCount() const { return nFacesCount; }
|
||||
int GetVertexCount() const { return nVertCount; }
|
||||
int GetUVCount() const { return nUVCount; }
|
||||
int GetEdgeCount() const { return nEdgeCount; }
|
||||
int GetLinesCount() const { return nLinesCount; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SetFacesCount(int nNewCount) { ReallocStream(FACES, nNewCount); }
|
||||
void SetVertexCount(int nNewCount)
|
||||
{
|
||||
ReallocStream(VERTICES, nNewCount);
|
||||
if (pColors)
|
||||
{
|
||||
ReallocStream(COLORS, nNewCount);
|
||||
}
|
||||
ReallocStream(WEIGHTS, nNewCount);
|
||||
}
|
||||
void SetColorsCount(int nNewCount) { ReallocStream(COLORS, nNewCount); }
|
||||
void SetUVCount(int nNewCount) { ReallocStream(TEXCOORDS, nNewCount); }
|
||||
void SetEdgeCount(int nNewCount) { ReallocStream(EDGES, nNewCount); }
|
||||
void SetLinesCount(int nNewCount) { ReallocStream(LINES, nNewCount); }
|
||||
|
||||
void ReallocStream(int stream, int nNewCount);
|
||||
void GetStreamInfo(int stream, void*& pStream, int& nElementSize) const;
|
||||
int GetStreamSize(int stream) const { return m_streamSize[stream]; };
|
||||
|
||||
// Calculate per face normal.
|
||||
void CalcFaceNormals();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Welding functions.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SharePositions();
|
||||
void ShareUV();
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Recreate edges of the mesh.
|
||||
void UpdateEdges();
|
||||
|
||||
void Copy(CTriMesh& fromMesh, int nCopyFlags = COPY_ALL);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sub-object selection specific methods.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Return true if something is selected.
|
||||
bool UpdateSelection();
|
||||
// Clear all selections, return true if something was selected.
|
||||
bool ClearSelection();
|
||||
void SoftSelection(const SSubObjSelOptions& options);
|
||||
CBitArray* GetStreamSelection(int nStream) { return m_streamSel[nStream]; };
|
||||
// Returns true if specified stream have any selected elements.
|
||||
bool StreamHaveSelection(int nStream) { return streamSelMask & (1 << nStream); }
|
||||
void GetEdgesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outEdges);
|
||||
void GetFacesByVertex(MeshElementsArray& inVertices, MeshElementsArray& outFaces);
|
||||
|
||||
private:
|
||||
void* ReAllocElements(void* old_ptr, int new_elem_num, int size_of_element);
|
||||
void CopyStream(CTriMesh& fromMesh, int stream);
|
||||
|
||||
// For internal use.
|
||||
int m_streamSize[LAST_STREAM];
|
||||
CBitArray* m_streamSel[LAST_STREAM];
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_GEOMETRY_TRIMESH_H
|
||||
@@ -17,7 +17,6 @@
|
||||
class CGizmo;
|
||||
class CBaseObject;
|
||||
struct IDisplayViewport;
|
||||
class CDeepSelection;
|
||||
struct AABB;
|
||||
|
||||
#include <QRect>
|
||||
@@ -105,8 +104,6 @@ struct HitContext
|
||||
CBaseObject* object;
|
||||
//! gizmo object that have been hit.
|
||||
CGizmo* gizmo;
|
||||
//! for deep selection mode
|
||||
CDeepSelection* pDeepSelection;
|
||||
//! For linking tool
|
||||
const char* name;
|
||||
//! true if this hit was from the object icon
|
||||
@@ -131,7 +128,6 @@ struct HitContext
|
||||
bIgnoreAxis = false;
|
||||
bOnlyGizmo = false;
|
||||
bUseSelectionHelpers = false;
|
||||
pDeepSelection = 0;
|
||||
name = nullptr;
|
||||
iconHit = false;
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
||||
#pragma once
|
||||
|
||||
struct IAnimationCompressionManager
|
||||
{
|
||||
virtual bool IsEnabled() const = 0;
|
||||
virtual void UpdateLocalAnimations() = 0;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IANIMATIONCOMPRESSIONMANAGER_H
|
||||
@@ -1,433 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Standard interface for asset display in the asset browser,
|
||||
// this header should be used to create plugins.
|
||||
// The method Release of this interface should NOT be called.
|
||||
// Instead, the FreeData from the database (from IAssetItemDatabase) should
|
||||
// be used as it will safely release all the items from the database.
|
||||
// It is still possible to call the release method, but this is not the
|
||||
// recomended method, specially for usage outside of the plugins because there
|
||||
// is no guarantee that a the asset will be properly removed from the database
|
||||
// manager.
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
||||
#pragma once
|
||||
|
||||
struct IAssetItemDatabase;
|
||||
|
||||
namespace AssetViewer
|
||||
{
|
||||
// Used in GetAssetFieldValue for each asset type to check if field name is the right one
|
||||
inline bool IsFieldName(const char* pIncomingFieldName, const char* pFieldName)
|
||||
{
|
||||
return !strncmp(pIncomingFieldName, pFieldName, strlen(pIncomingFieldName));
|
||||
}
|
||||
}
|
||||
|
||||
// Description:
|
||||
// This interface allows the programmer to extend asset display types visible in the asset browser.
|
||||
struct IAssetItem
|
||||
: public IUnknown
|
||||
{
|
||||
DEFINE_UUID(0x04F20346, 0x2EC3, 0x43f2, 0xBD, 0xA1, 0x2C, 0x0B, 0x97, 0x76, 0xF3, 0x84);
|
||||
|
||||
// The supported asset flags
|
||||
enum EAssetFlags
|
||||
{
|
||||
// asset is visible in the database for filtering and sorting (not asset view control related)
|
||||
eFlag_Visible = BIT(0),
|
||||
// the asset is loaded
|
||||
eFlag_Loaded = BIT(1),
|
||||
// the asset is loaded
|
||||
eFlag_Cached = BIT(2),
|
||||
// the asset is selected in a selection set
|
||||
eFlag_Selected = BIT(3),
|
||||
// this asset is invalid, no thumb is shown/available
|
||||
eFlag_Invalid = BIT(4),
|
||||
// this asset has some errors/warnings, in the asset browser it will show some blinking/red elements
|
||||
// and the user can check out the errors. Error text will be fetched using GetAssetFieldValue( "errors", &someStringVar )
|
||||
eFlag_HasErrors = BIT(5),
|
||||
// this flag is set when the asset is rendering its contents using GDI, and not the engine's rendering capabilities
|
||||
// (this flags is used as hint for the preview tool, which will use a double-buffer canvas if this flag is set,
|
||||
// and send a memory HDC to the OnBeginPreview method, for drawing of the asset)
|
||||
eFlag_UseGdiRendering = BIT(6),
|
||||
// set if this asset is draggable into the render viewports, and can be created there
|
||||
eFlag_CanBeDraggedInViewports = BIT(7),
|
||||
// set if this asset can be moved after creation, otherwise the asset instance will just be created where user clicked
|
||||
eFlag_CanBeMovedAfterDroppedIntoViewport = BIT(8),
|
||||
// the asset thumbnail image is loaded
|
||||
eFlag_ThumbnailLoaded = BIT(9),
|
||||
// the asset thumbnail image is loaded
|
||||
eFlag_UsedInLevel = BIT(10)
|
||||
};
|
||||
|
||||
// Asset field name and field values map
|
||||
typedef std::map < QString/*fieldName*/, QString/*value*/ > TAssetFieldValuesMap;
|
||||
// Dependency category names and corresponding files map, example: "Textures"=>{ "foam.dds","water.dds","normal.dds" }
|
||||
typedef std::map < QString/*dependencyCategory*/, std::set<QString>/*dependency filenames*/ > TAssetDependenciesMap;
|
||||
|
||||
virtual ~IAssetItem() {
|
||||
}
|
||||
|
||||
// Description:
|
||||
// Get the hash number/key used for database thumbnail and info records management
|
||||
virtual uint32 GetHash() const = 0;
|
||||
// Description:
|
||||
// Set the hash number/key used for database thumbnail and info records management
|
||||
virtual void SetHash(uint32 hash) = 0;
|
||||
// Description:
|
||||
// Get the owner database for this asset
|
||||
// Return Value:
|
||||
// The owner database for this asset
|
||||
// See Also:
|
||||
// SetOwnerDatabase()
|
||||
virtual IAssetItemDatabase* GetOwnerDatabase() const = 0;
|
||||
// Description:
|
||||
// Set the owner database for this asset
|
||||
// Arguments:
|
||||
// piOwnerDisplayDatabase - the owner database
|
||||
// See Also:
|
||||
// GetOwnerDatabase()
|
||||
virtual void SetOwnerDatabase(IAssetItemDatabase* pOwnerDisplayDatabase) = 0;
|
||||
// Description:
|
||||
// Get the asset's dependency files / objects
|
||||
// Return Value:
|
||||
// The vector with filenames which this asset is dependent upon, ex.: ["Textures"].(vector of textures)
|
||||
virtual const TAssetDependenciesMap& GetDependencies() const = 0;
|
||||
// Description:
|
||||
// Set the file size of this asset in bytes
|
||||
// Arguments:
|
||||
// aSize - size of the file in bytes
|
||||
// See Also:
|
||||
// GetFileSize()
|
||||
virtual void SetFileSize(quint64 aSize) = 0;
|
||||
// Description:
|
||||
// Get the file size of this asset in bytes
|
||||
// Return Value:
|
||||
// The file size of this asset in bytes
|
||||
// See Also:
|
||||
// SetFileSize()
|
||||
virtual quint64 GetFileSize() const = 0;
|
||||
// Description:
|
||||
// Set asset filename (extension included and no path)
|
||||
// Arguments:
|
||||
// pName - the asset filename (extension included and no path)
|
||||
// See Also:
|
||||
// GetFilename()
|
||||
virtual void SetFilename(const char* pName) = 0;
|
||||
// Description:
|
||||
// Get asset filename (extension included and no path)
|
||||
// Return Value:
|
||||
// The asset filename (extension included and no path)
|
||||
// See Also:
|
||||
// SetFilename()
|
||||
virtual QString GetFilename() const = 0;
|
||||
// Description:
|
||||
// Set the asset's relative path
|
||||
// Arguments:
|
||||
// pName - file's relative path
|
||||
// See Also:
|
||||
// GetRelativePath()
|
||||
virtual void SetRelativePath(const char* pName) = 0;
|
||||
// Description:
|
||||
// Get the asset's relative path
|
||||
// Return Value:
|
||||
// The asset's relative path
|
||||
// See Also:
|
||||
// SetRelativePath()
|
||||
virtual QString GetRelativePath() const = 0;
|
||||
// Description:
|
||||
// Set the file extension ( dot(s) must be included )
|
||||
// Arguments:
|
||||
// pExt - the file's extension
|
||||
// See Also:
|
||||
// GetFileExtension()
|
||||
virtual void SetFileExtension(const char* pExt) = 0;
|
||||
// Description:
|
||||
// Get the file extension ( dot(s) included )
|
||||
// Return Value:
|
||||
// The file extension ( dot(s) included )
|
||||
// See Also:
|
||||
// SetFileExtension()
|
||||
virtual QString GetFileExtension() const = 0;
|
||||
// Description:
|
||||
// Get the asset flags, with values from IAssetItem::EAssetFlags
|
||||
// Return Value:
|
||||
// The asset flags, with values from IAssetItem::EAssetFlags
|
||||
// See Also:
|
||||
// SetFlags(), SetFlag(), IsFlagSet()
|
||||
virtual UINT GetFlags() const = 0;
|
||||
// Description:
|
||||
// Set the asset flags
|
||||
// Arguments:
|
||||
// aFlags - flags, OR-ed values from IAssetItem::EAssetFlags
|
||||
// See Also:
|
||||
// GetFlags(), SetFlag(), IsFlagSet()
|
||||
virtual void SetFlags(UINT aFlags) = 0;
|
||||
// Description:
|
||||
// Set/clear a single flag bit for the asset
|
||||
// Arguments:
|
||||
// aFlag - the flag to set/clear, with values from IAssetItem::EAssetFlags
|
||||
// See Also:
|
||||
// GetFlags(), SetFlags(), IsFlagSet()
|
||||
virtual void SetFlag(EAssetFlags aFlag, bool bSet = true) = 0;
|
||||
// Description:
|
||||
// Check if a specified flag is set
|
||||
// Arguments:
|
||||
// aFlag - the flag to check, with values from IAssetItem::EAssetFlags
|
||||
// Return Value:
|
||||
// True if the flag is set
|
||||
// See Also:
|
||||
// GetFlags(), SetFlags(), SetFlag()
|
||||
virtual bool IsFlagSet(EAssetFlags aFlag) const = 0;
|
||||
// Description:
|
||||
// Set this asset's index; used in sorting, selections, and to know where an asset is in the current list
|
||||
// Arguments:
|
||||
// aIndex - the asset's index
|
||||
// See Also:
|
||||
// GetIndex()
|
||||
virtual void SetIndex(UINT aIndex) = 0;
|
||||
// Description:
|
||||
// Get the asset's index in the current list
|
||||
// Return Value:
|
||||
// The asset's index in the current list
|
||||
// See Also:
|
||||
// SetIndex()
|
||||
virtual UINT GetIndex() const = 0;
|
||||
// Description:
|
||||
// Get the asset's field raw data value into a user location, you must check the field's type ( from asset item's owner database )
|
||||
// before using this function and send the correct pointer to destination according to the type ( int8, float32, string, etc. )
|
||||
// Arguments:
|
||||
// pFieldName - the asset field name to query the value for
|
||||
// pDest - the destination variable address, must be the same type as the field type
|
||||
// Return Value:
|
||||
// True if the asset field name is found and the value is returned correctly
|
||||
// See Also:
|
||||
// SetAssetFieldValue()
|
||||
virtual QVariant GetAssetFieldValue(const char* pFieldName) const = 0;
|
||||
// Description:
|
||||
// Set the asset's field raw data value from a user location, you must check the field's type ( from asset item's owner database )
|
||||
// before using this function and send the correct pointer to source according to the type ( int8, float32, string, etc. )
|
||||
// Arguments:
|
||||
// pFieldName - the asset field name to set the value for
|
||||
// pSrc - the source variable address, must be the same type as the field type
|
||||
// Return Value:
|
||||
// True if the asset field name is found and the value is set correctly
|
||||
// See Also:
|
||||
// GetAssetFieldValue()
|
||||
virtual bool SetAssetFieldValue(const char* pFieldName, void* pSrc) = 0;
|
||||
// Description:
|
||||
// Get the drawing rectangle for the asset's thumb ( absolute viewer canvas location )
|
||||
// Arguments:
|
||||
// rstDrawingRectangle - destination location to set with the asset's thumbnail rectangle location
|
||||
// See Also:
|
||||
// SetDrawingRectangle()
|
||||
virtual void GetDrawingRectangle(QRect& rstDrawingRectangle) const = 0;
|
||||
// Description:
|
||||
// Set the drawing rectangle for the asset's thumb ( absolute viewer canvas location )
|
||||
// Arguments:
|
||||
// crstDrawingRectangle - source to set the asset's thumbnail rectangle
|
||||
// See Also:
|
||||
// GetDrawingRectangle()
|
||||
virtual void SetDrawingRectangle(const QRect& crstDrawingRectangle) = 0;
|
||||
// Description:
|
||||
// Checks if the given 2D point is inside the asset's thumb rectangle
|
||||
// Arguments:
|
||||
// nX - mouse pointer position on X axis, relative to the asset viewer control
|
||||
// nY - mouse pointer position on Y axis, relative to the asset viewer control
|
||||
// Return Value:
|
||||
// True if the given 2D point is inside the asset's thumb rectangle
|
||||
// See Also:
|
||||
// HitTest(CRect)
|
||||
virtual bool HitTest(int nX, int nY) const = 0;
|
||||
// Description:
|
||||
// Checks if the given rectangle intersects the asset thumb's rectangle
|
||||
// Arguments:
|
||||
// nX - mouse pointer position on X axis, relative to the asset viewer control
|
||||
// nY - mouse pointer position on Y axis, relative to the asset viewer control
|
||||
// Return Value:
|
||||
// True if the given rectangle intersects the asset thumb's rectangle
|
||||
// See Also:
|
||||
// HitTest(int nX,int nY)
|
||||
virtual bool HitTest(const QRect& roTestRect) const = 0;
|
||||
// Description:
|
||||
// When user drags this asset item into a viewport, this method is called when the dragging operation ends
|
||||
// and the mouse button is released, for the asset to return an instance of the asset object to be placed in the level
|
||||
// Arguments:
|
||||
// aX - instance's X position component in world coordinates
|
||||
// aY - instance's Y position component in world coordinates
|
||||
// aZ - instance's Z position component in world coordinates
|
||||
// Return Value:
|
||||
// The newly created asset instance (Example: BrushObject*)
|
||||
// See Also:
|
||||
// MoveInstanceInViewport()
|
||||
virtual void* CreateInstanceInViewport(float aX, float aY, float aZ) = 0;
|
||||
// Description:
|
||||
// When the mouse button is released after level object creation, the user now can move the mouse
|
||||
// and move the asset instance in the 3D world
|
||||
// Arguments:
|
||||
// pDraggedObject - the actual entity or brush object (CBaseObject* usually) to be moved around with the mouse
|
||||
// returned by the CreateInstanceInViewport()
|
||||
// aNewX - the new X world coordinates of the asset instance
|
||||
// aNewY - the new Y world coordinates of the asset instance
|
||||
// aNewZ - the new Z world coordinates of the asset instance
|
||||
// Return Value:
|
||||
// True if asset instance was moved properly
|
||||
// See Also:
|
||||
// CreateInstanceInViewport()
|
||||
virtual bool MoveInstanceInViewport(const void* pDraggedObject, float aNewX, float aNewY, float aNewZ) = 0;
|
||||
// Description:
|
||||
// This will be called when the user presses ESCAPE key when dragging the asset in the viewport, you must delete the given object
|
||||
// because the creation was aborted
|
||||
// Arguments:
|
||||
// pDraggedObject - the asset instance to be deleted ( you must cast to the needed type, and delete it properly )
|
||||
// See Also:
|
||||
// CreateInstanceInViewport()
|
||||
virtual void AbortCreateInstanceInViewport(const void* pDraggedObject) = 0;
|
||||
// Description:
|
||||
// This method is used to cache/load asset's data, so it can be previewed/rendered
|
||||
// Return Value:
|
||||
// True if the asset was successfully cached
|
||||
// See Also:
|
||||
// UnCache()
|
||||
virtual bool Cache() = 0;
|
||||
// Description:
|
||||
// This method is used to force cache/load asset's data, so it can be previewed/rendered
|
||||
// Return Value:
|
||||
// True if the asset was successfully forced cached
|
||||
// See Also:
|
||||
// UnCache(), Cache()
|
||||
virtual bool ForceCache() = 0;
|
||||
// Description:
|
||||
// This method is used to load the thumbnail image of the asset
|
||||
// Return Value:
|
||||
// True if thumb loaded ok
|
||||
// See Also:
|
||||
// UnloadThumbnail()
|
||||
virtual bool LoadThumbnail() = 0;
|
||||
// Description:
|
||||
// This method is used to unload the thumbnail image of the asset
|
||||
// See Also:
|
||||
// LoadThumbnail()
|
||||
virtual void UnloadThumbnail() = 0;
|
||||
// Description:
|
||||
// This is called when the asset starts to be previewed in full detail, so here you can load the whole asset, in fine detail
|
||||
// ( textures are fully loaded, models etc. ). It is called once, when the Preview dialog is shown
|
||||
// Arguments:
|
||||
// hPreviewWnd - the window handle of the quick preview dialog
|
||||
// hMemDC - the memory DC used to render assets that can render themselves in the DC, otherwise they will render in the dialog's HWND
|
||||
// See Also:
|
||||
// OnEndPreview(), GetCustomPreviewPanelHeader()
|
||||
virtual void OnBeginPreview(QWidget* hPreviewWnd) = 0;
|
||||
// Description:
|
||||
// Called when the Preview dialog is closed, you may release the detail asset data here
|
||||
// See Also:
|
||||
// OnBeginPreview(), GetCustomPreviewPanelHeader()
|
||||
virtual void OnEndPreview() = 0;
|
||||
// Description:
|
||||
// If the asset has a special preview panel with utility controls, to be placed at the top of the Preview window, it can return an child dialog window
|
||||
// otherwise it can return nullptr, if no panel is available
|
||||
// Arguments:
|
||||
// pParentWnd - a valid CDialog*, or nullptr
|
||||
// Return Value:
|
||||
// A valid child dialog window handle, if this asset wants to have a custom panel in the top side of the Asset Preview window,
|
||||
// otherwise it can return nullptr, if no panel is available
|
||||
// See Also:
|
||||
// OnBeginPreview(), OnEndPreview()
|
||||
virtual QWidget* GetCustomPreviewPanelHeader(QWidget* pParentWnd) = 0;
|
||||
virtual QWidget* GetCustomPreviewPanelFooter(QWidget* pParentWnd) = 0;
|
||||
// Description:
|
||||
// Used when dragging/rotate/zoom a model, or other asset that can support preview
|
||||
// Arguments:
|
||||
// hRenderWindow - the rendering window handle
|
||||
// rstViewport - the viewport rectangle
|
||||
// aMouseX - the render window relative mouse pointer X coordinate
|
||||
// aMouseY - the render window relative mouse pointer Y coordinate
|
||||
// aMouseDeltaX - the X coordinate delta between two mouse movements
|
||||
// aMouseDeltaY - the Y coordinate delta between two mouse movements
|
||||
// aMouseWheelDelta - the mouse wheel scroll delta/step
|
||||
// aKeyFlags - the key flags, see WM_LBUTTONUP
|
||||
// See Also:
|
||||
// OnPreviewRenderKeyEvent()
|
||||
virtual void PreviewRender(
|
||||
QWidget* hRenderWindow,
|
||||
const QRect& rstViewport,
|
||||
int aMouseX = 0, int aMouseY = 0,
|
||||
int aMouseDeltaX = 0, int aMouseDeltaY = 0,
|
||||
int aMouseWheelDelta = 0, UINT aKeyFlags = 0) = 0;
|
||||
// Description:
|
||||
// This is called when the user manipulates the assets in interactive render and a key is pressed ( with down or up state )
|
||||
// Arguments:
|
||||
// bKeyDown - true if this is a WM_KEYDOWN event, else it is a WM_KEYUP event
|
||||
// aChar - the char/key code pressed/released
|
||||
// aKeyFlags - the key flags, compatible with WM_KEYDOWN/UP events
|
||||
// See Also:
|
||||
// InteractiveRender()
|
||||
virtual void OnPreviewRenderKeyEvent(bool bKeyDown, UINT aChar, UINT aKeyFlags) = 0;
|
||||
// Description:
|
||||
// Called when user clicked once on the thumb image
|
||||
// Arguments:
|
||||
// point - mouse coordinates relative to the thumbnail rectangle
|
||||
// aKeyFlags - the key flags, see WM_LBUTTONDOWN
|
||||
// See Also:
|
||||
// OnThumbDblClick()
|
||||
virtual void OnThumbClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0;
|
||||
// Description:
|
||||
// Called when user double clicked on the thumb image
|
||||
// Arguments:
|
||||
// point - mouse coordinates relative to the thumbnail rectangle
|
||||
// aKeyFlags - the key flags, see WM_LBUTTONDOWN
|
||||
// See Also:
|
||||
// OnThumbClick()
|
||||
//! called when user clicked twice on the thumb image
|
||||
virtual void OnThumbDblClick(const QPoint& point, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) = 0;
|
||||
// Description:
|
||||
// Draw the cached thumb bitmap only, if any, no other kind of rendering
|
||||
// Arguments:
|
||||
// hDC - the destination DC, where to draw the thumb
|
||||
// rRect - the destination rectangle
|
||||
// Return Value:
|
||||
// True if drawing of the thumbnail was done OK
|
||||
// See Also:
|
||||
// Render()
|
||||
virtual bool DrawThumbImage(QPainter* painter, const QRect& rRect) = 0;
|
||||
// Description:
|
||||
// Writes asset info to a XML node.
|
||||
// This is needed to save cached info as a persistent XML file for the next run of the editor.
|
||||
// Arguments:
|
||||
// node - An XML node to contain the info
|
||||
// See Also:
|
||||
// FromXML()
|
||||
virtual void ToXML(XmlNodeRef& node) const = 0;
|
||||
// Description:
|
||||
// Gets asset info from a XML node.
|
||||
// This is needed to get the asset info from previous runs of the editor without re-caching it.
|
||||
// Arguments:
|
||||
// node - An XML node that contains info for this asset
|
||||
// See Also:
|
||||
// ToXML()
|
||||
virtual void FromXML(const XmlNodeRef& node) = 0;
|
||||
|
||||
// From IUnknown
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] const IID& riid, [[maybe_unused]] void** ppvObject)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
};
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
virtual ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEM_H
|
||||
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : Standard interface for asset database creators used to
|
||||
// create an asset plugin for the asset browser
|
||||
// The category of the plugin must be Asset Item DB
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
||||
#pragma once
|
||||
struct IAssetItem;
|
||||
struct IAssetViewer;
|
||||
|
||||
class QString;
|
||||
class QStringList;
|
||||
|
||||
// Description:
|
||||
// This struct keeps the info, filter and sorting settings for an asset field
|
||||
struct SAssetField
|
||||
{
|
||||
// the condition for the current filter on the field
|
||||
enum EAssetFilterCondition
|
||||
{
|
||||
eCondition_Any = 0,
|
||||
// string conditions
|
||||
// this also supports '*' and '?' as wildcards inside text
|
||||
eCondition_Contains,
|
||||
// this filter will search the target for at least one of the words specified
|
||||
// ( ex: filter: "water car moon" , field value : "the_great_moon.dds", this will pass the test
|
||||
// it also supports '*' and '?' as wildcards inside words text
|
||||
eCondition_ContainsOneOfTheWords,
|
||||
eCondition_StartsWith,
|
||||
eCondition_EndsWith,
|
||||
// string & numerical conditions
|
||||
eCondition_Equal,
|
||||
eCondition_Greater,
|
||||
eCondition_Less,
|
||||
eCondition_GreaterOrEqual,
|
||||
eCondition_LessOrEqual,
|
||||
eCondition_Not,
|
||||
eCondition_InsideRange
|
||||
};
|
||||
|
||||
// the asset field type
|
||||
enum EAssetFieldType
|
||||
{
|
||||
eType_None = 0,
|
||||
eType_Bool,
|
||||
eType_Int8,
|
||||
eType_Int16,
|
||||
eType_Int32,
|
||||
eType_Int64,
|
||||
eType_Float,
|
||||
eType_Double,
|
||||
eType_String
|
||||
};
|
||||
|
||||
// used when a field can have different specific values
|
||||
typedef QStringList TFieldEnumValues;
|
||||
|
||||
SAssetField(
|
||||
const char* pFieldName = "",
|
||||
const char* pDisplayName = "Unnamed field",
|
||||
EAssetFieldType aFieldType = eType_None,
|
||||
UINT aColumnWidth = 50,
|
||||
bool bVisibleInUI = true,
|
||||
bool bReadOnly = true)
|
||||
{
|
||||
m_fieldName = pFieldName;
|
||||
m_displayName = pDisplayName;
|
||||
m_fieldType = aFieldType;
|
||||
m_filterCondition = eCondition_Equal;
|
||||
m_bUseEnumValues = false;
|
||||
m_bReadOnly = bReadOnly;
|
||||
m_listColumnWidth = aColumnWidth;
|
||||
m_bFieldVisibleInUI = bVisibleInUI;
|
||||
m_bPostFilter = false;
|
||||
|
||||
SetupEnumValues();
|
||||
}
|
||||
|
||||
void SetupEnumValues()
|
||||
{
|
||||
m_bUseEnumValues = true;
|
||||
|
||||
if (m_fieldType == eType_Bool)
|
||||
{
|
||||
m_enumValues.clear();
|
||||
m_enumValues.push_back("Yes");
|
||||
m_enumValues.push_back("No");
|
||||
}
|
||||
}
|
||||
|
||||
// the field's display name, used in UI
|
||||
QString m_displayName,
|
||||
// the field internal name, used in C++ code
|
||||
m_fieldName,
|
||||
// the current filter value, if its empty "" then no filter is applied
|
||||
m_filterValue,
|
||||
// the field's max value, valid when the field's filter condition is eAssertFilterCondition_InsideRange
|
||||
m_maxFilterValue,
|
||||
// the name of the database holding this field, used in Asset Browser preset editor, if its "" then the field
|
||||
// is common to all current databases
|
||||
m_parentDatabaseName;
|
||||
// is this field visible in the UI ?
|
||||
bool m_bFieldVisibleInUI,
|
||||
// if true, then you cannot modify this field of an asset item, only use it
|
||||
m_bReadOnly,
|
||||
// this field filter is applied after the other filters
|
||||
m_bPostFilter;
|
||||
// the field data type
|
||||
EAssetFieldType m_fieldType;
|
||||
// the filter's condition
|
||||
EAssetFilterCondition m_filterCondition;
|
||||
// use the enum list values to choose a value for the field ?
|
||||
bool m_bUseEnumValues;
|
||||
// this map is used when asset field has m_bUseEnumValues on true,
|
||||
// choose a value for the field from this list in the UI
|
||||
TFieldEnumValues m_enumValues;
|
||||
// recommended list column width
|
||||
unsigned int m_listColumnWidth;
|
||||
};
|
||||
|
||||
struct SFieldFiltersPreset
|
||||
{
|
||||
QString presetName2;
|
||||
QStringList checkedDatabaseNames;
|
||||
bool bUsedInLevel;
|
||||
std::vector<SAssetField> fields;
|
||||
};
|
||||
|
||||
// Description:
|
||||
// This interface allows the programmer to extend asset display types
|
||||
// visible in the asset browser.
|
||||
struct IAssetItemDatabase
|
||||
: public IUnknown
|
||||
{
|
||||
DEFINE_UUID(0xFB09B039, 0x1D9D, 0x4057, 0xA5, 0xF0, 0xAA, 0x3C, 0x7B, 0x97, 0xAE, 0xA8)
|
||||
|
||||
typedef std::vector<SAssetField> TAssetFields;
|
||||
typedef std::map < QString/*field name*/, SAssetField > TAssetFieldFiltersMap;
|
||||
typedef std::map < QString/*asset filename*/, IAssetItem* > TFilenameAssetMap;
|
||||
typedef AZStd::function<bool(const IAssetItem*)> MetaDataChangeListener;
|
||||
|
||||
// Description:
|
||||
// Refresh the database by scanning the folders/paks for files, does not load the files, only filename and filesize are fetched
|
||||
virtual void Refresh() = 0;
|
||||
// Description:
|
||||
// Fills the asset meta data from the loaded xml meta data DB.
|
||||
// Arguments:
|
||||
// db - the database XML node from where to cache the info
|
||||
virtual void PrecacheFieldsInfoFromFileDB(const XmlNodeRef& db) = 0;
|
||||
// Description:
|
||||
// Return all assets loaded/scanned by this database
|
||||
// Return Value:
|
||||
// The assets map reference (filename-asset)
|
||||
virtual TFilenameAssetMap& GetAssets() = 0;
|
||||
// Description:
|
||||
// Get an asset item by its filename
|
||||
// Return Value:
|
||||
// A single asset from the database given the filename
|
||||
virtual IAssetItem* GetAsset(const char* pAssetFilename) = 0;
|
||||
// Description:
|
||||
// Return the asset fields this database's items support
|
||||
// Return Value:
|
||||
// The asset fields vector reference
|
||||
virtual TAssetFields& GetAssetFields() = 0;
|
||||
// Description:
|
||||
// Return an asset field object pointer by the field internal name
|
||||
// Arguments:
|
||||
// pFieldName - the internal field's name (ex: "filename", "relativepath")
|
||||
// Return Value:
|
||||
// The asset field object pointer
|
||||
virtual SAssetField* GetAssetFieldByName(const char* pFieldName) = 0;
|
||||
// Description:
|
||||
// Get the database name
|
||||
// Return Value:
|
||||
// Returns the database name, ex: "Textures"
|
||||
virtual const char* GetDatabaseName() const = 0;
|
||||
// Description:
|
||||
// Get the database supported file name extension(s)
|
||||
// Return Value:
|
||||
// Returns the supported extensions, separated by comma, ex: "tga,bmp,dds"
|
||||
virtual const char* GetSupportedExtensions() const = 0;
|
||||
// Description:
|
||||
// Free the database internal data structures
|
||||
virtual void FreeData() = 0;
|
||||
// Description:
|
||||
// Apply filters to this database which will set/unset the IAssetItem::eAssetFlag_Visible of each asset, based
|
||||
// on the given field filters
|
||||
// Arguments:
|
||||
// rFieldFilters - a reference to the field filters map (fieldname-field)
|
||||
// See Also:
|
||||
// ClearFilters()
|
||||
virtual void ApplyFilters(const TAssetFieldFiltersMap& rFieldFilters) = 0;
|
||||
// Description:
|
||||
// Clear the current filters, by setting the IAssetItem::eAssetFlag_Visible of each asset to true
|
||||
// See Also:
|
||||
// ApplyFilters()
|
||||
virtual void ClearFilters() = 0;
|
||||
virtual QWidget* CreateDbFilterDialog(QWidget* pParent, IAssetViewer* pViewerCtrl) = 0;
|
||||
virtual void UpdateDbFilterDialogUI(QWidget* pDlg) = 0;
|
||||
virtual void OnAssetBrowserOpen() = 0;
|
||||
virtual void OnAssetBrowserClose() = 0;
|
||||
// Description:
|
||||
// Gets the filename for saving new cached asset info.
|
||||
// Return Value:
|
||||
// A file name to save new transactions to the persistent asset info DB
|
||||
// See Also:
|
||||
// CAssetInfoFileDB, IAssetItem::ToXML(), IAssetItem::FromXML()
|
||||
virtual const char* GetTransactionFilename() const = 0;
|
||||
// Description:
|
||||
// Adds a callback to be called when the meta data of this asset changed.
|
||||
// Arguments:
|
||||
// callBack - A functor to be added
|
||||
// Return Value:
|
||||
// True if successful, false otherwise.
|
||||
// See Also:
|
||||
// RemoveMetaDataChangeListener()
|
||||
virtual bool AddMetaDataChangeListener(MetaDataChangeListener callBack) = 0;
|
||||
// Description:
|
||||
// Removes a callback from the list of meta data change listeners.
|
||||
// Arguments:
|
||||
// callBack - A functor to be removed
|
||||
// Return Value:
|
||||
// True if successful, false otherwise.
|
||||
// See Also:
|
||||
// AddMetaDataCHangeListener()
|
||||
virtual bool RemoveMetaDataChangeListener(MetaDataChangeListener callBack) = 0;
|
||||
// Description:
|
||||
// The method that should be called when the meta data of an asset item changes to notify all listeners
|
||||
// Arguments:
|
||||
// pAssetItem - An asset item whose meta data have changed
|
||||
// See Also:
|
||||
// AddMetaDataCHangeListener(), RemoveMetaDataChangeListener()
|
||||
virtual void OnMetaDataChange(const IAssetItem* pAssetItem) = 0;
|
||||
|
||||
//! from IUnknown
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface([[maybe_unused]] REFIID riid, [[maybe_unused]] void** ppvObject)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
};
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
virtual ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETITEMDATABASE_H
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// Description : This file declares a control which objective is to display
|
||||
// multiple assets allowing selection and preview of such things
|
||||
// It also handles scrolling and changes in the thumbnail display size
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
||||
#define CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
||||
#pragma once
|
||||
#include "IObservable.h"
|
||||
#include "IAssetItemDatabase.h"
|
||||
|
||||
struct IAssetItem;
|
||||
struct IAssetItemDatabase;
|
||||
|
||||
// Description:
|
||||
// Observer for the asset viewer events
|
||||
struct IAssetViewerObserver
|
||||
{
|
||||
virtual void OnChangeStatusBarInfo(UINT nSelectedItems, UINT nVisibleItems, UINT nTotalItems) {};
|
||||
virtual void OnSelectionChanged() {};
|
||||
virtual void OnChangedPreviewedAsset(IAssetItem* pAsset) {};
|
||||
virtual void OnAssetDblClick(IAssetItem* pAsset) {};
|
||||
virtual void OnAssetFilterChanged() {};
|
||||
};
|
||||
|
||||
// Description:
|
||||
// The asset viewer interface for the asset database plugins to use
|
||||
struct IAssetViewer
|
||||
{
|
||||
DEFINE_OBSERVABLE_PURE_METHODS(IAssetViewerObserver);
|
||||
|
||||
virtual HWND GetRenderWindow() = 0;
|
||||
virtual void ApplyFilters(const IAssetItemDatabase::TAssetFieldFiltersMap& rFieldFilters) = 0;
|
||||
virtual const IAssetItemDatabase::TAssetFieldFiltersMap& GetCurrentFilters() = 0;
|
||||
virtual void ClearFilters() = 0;
|
||||
};
|
||||
#endif // CRYINCLUDE_EDITOR_INCLUDE_IASSETVIEWER_H
|
||||
@@ -116,9 +116,6 @@ struct IFileUtil
|
||||
virtual bool ExtractFile(QString& file, bool bMsgBoxAskForExtraction = true, const char* pDestinationFilename = nullptr) = 0;
|
||||
virtual void EditTextureFile(const char* txtureFile, bool bUseGameFolder) = 0;
|
||||
|
||||
//! dcc filename calculation and extraction sub-routines
|
||||
virtual bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename) = 0;
|
||||
|
||||
//! Reformat filter string for (MFC) CFileDialog style file filtering
|
||||
virtual void FormatFilterString(QString& filter) = 0;
|
||||
|
||||
|
||||
@@ -1,506 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "EditorDefs.h"
|
||||
|
||||
#include "SimpleTriangleRasterizer.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if !defined FLT_MAX
|
||||
#define FLT_MAX 3.402823466e+38F
|
||||
#endif
|
||||
|
||||
void CSimpleTriangleRasterizer::lambertHorizlineConservative(float fx1, float fx2, int yy, IRasterizeSink* inpSink)
|
||||
{
|
||||
int x1 = (int)floorf(fx1 + 0.25f), x2 = (int)floorf(fx2 + .75f);
|
||||
|
||||
if (x1 < m_iMinX)
|
||||
{
|
||||
x1 = m_iMinX;
|
||||
}
|
||||
if (x2 > m_iMaxX + 1)
|
||||
{
|
||||
x2 = m_iMaxX + 1;
|
||||
}
|
||||
if (x1 > m_iMaxX + 1)
|
||||
{
|
||||
x1 = m_iMaxX + 1;
|
||||
}
|
||||
if (x2 < m_iMinX)
|
||||
{
|
||||
x2 = m_iMinX;
|
||||
}
|
||||
|
||||
|
||||
inpSink->Line(fx1, fx2, x1, x2, yy);
|
||||
}
|
||||
|
||||
void CSimpleTriangleRasterizer::lambertHorizlineSubpixelCorrect(float fx1, float fx2, int yy, IRasterizeSink* inpSink)
|
||||
{
|
||||
int x1 = (int)floorf(fx1 + 0.5f), x2 = (int)floorf(fx2 + 0.5f);
|
||||
// int x1=(int)floorf(fx1*1023.f/1024.f+1.f),x2=(int)floorf(fx2*1023.f/1024.f+1.f);
|
||||
|
||||
if (x1 < m_iMinX)
|
||||
{
|
||||
x1 = m_iMinX;
|
||||
}
|
||||
if (x2 > m_iMaxX)
|
||||
{
|
||||
x2 = m_iMaxX;
|
||||
}
|
||||
if (x1 > m_iMaxX)
|
||||
{
|
||||
x1 = m_iMaxX;
|
||||
}
|
||||
if (x2 < m_iMinX)
|
||||
{
|
||||
x2 = m_iMinX;
|
||||
}
|
||||
|
||||
inpSink->Line(fx1, fx2, x1, x2, yy);
|
||||
}
|
||||
|
||||
// optimizable
|
||||
void CSimpleTriangleRasterizer::CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3])
|
||||
{
|
||||
outfX[0] = infX[0];
|
||||
outfY[0] = infY[0];
|
||||
outfX[1] = infX[1];
|
||||
outfY[1] = infY[1];
|
||||
outfX[2] = infX[2];
|
||||
outfY[2] = infY[2];
|
||||
|
||||
// Sort the coordinates, so that (x[1], y[1]) becomes the highest coord
|
||||
float tmp;
|
||||
|
||||
if (outfY[0] > outfY[1])
|
||||
{
|
||||
if (outfY[1] > outfY[2])
|
||||
{
|
||||
tmp = outfY[0];
|
||||
outfY[0] = outfY[1];
|
||||
outfY[1] = tmp;
|
||||
tmp = outfX[0];
|
||||
outfX[0] = outfX[1];
|
||||
outfX[1] = tmp;
|
||||
tmp = outfY[1];
|
||||
outfY[1] = outfY[2];
|
||||
outfY[2] = tmp;
|
||||
tmp = outfX[1];
|
||||
outfX[1] = outfX[2];
|
||||
outfX[2] = tmp;
|
||||
|
||||
if (outfY[0] > outfY[1])
|
||||
{
|
||||
tmp = outfY[0];
|
||||
outfY[0] = outfY[1];
|
||||
outfY[1] = tmp;
|
||||
tmp = outfX[0];
|
||||
outfX[0] = outfX[1];
|
||||
outfX[1] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = outfY[0];
|
||||
outfY[0] = outfY[1];
|
||||
outfY[1] = tmp;
|
||||
tmp = outfX[0];
|
||||
outfX[0] = outfX[1];
|
||||
outfX[1] = tmp;
|
||||
|
||||
if (outfY[1] > outfY[2])
|
||||
{
|
||||
tmp = outfY[1];
|
||||
outfY[1] = outfY[2];
|
||||
outfY[2] = tmp;
|
||||
tmp = outfX[1];
|
||||
outfX[1] = outfX[2];
|
||||
outfX[2] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outfY[1] > outfY[2])
|
||||
{
|
||||
tmp = outfY[1];
|
||||
outfY[1] = outfY[2];
|
||||
outfY[2] = tmp;
|
||||
tmp = outfX[1];
|
||||
outfX[1] = outfX[2];
|
||||
outfX[2] = tmp;
|
||||
|
||||
if (outfY[0] > outfY[1])
|
||||
{
|
||||
tmp = outfY[0];
|
||||
outfY[0] = outfY[1];
|
||||
outfY[1] = tmp;
|
||||
tmp = outfX[0];
|
||||
outfX[0] = outfX[1];
|
||||
outfX[1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleTriangleRasterizer::CallbackFillRectConservative(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
||||
{
|
||||
inpSink->Triangle(m_iMinY);
|
||||
|
||||
float fMinX = (std::min)(_x[0], (std::min)(_x[1], _x[2]));
|
||||
float fMaxX = (std::max)(_x[0], (std::max)(_x[1], _x[2]));
|
||||
float fMinY = (std::min)(_y[0], (std::min)(_y[1], _y[2]));
|
||||
float fMaxY = (std::max)(_y[0], (std::max)(_y[1], _y[2]));
|
||||
|
||||
int iMinX = (std::max)(m_iMinX, (int)floorf(fMinX));
|
||||
int iMaxX = (std::min)(m_iMaxX + 1, (int)ceilf(fMaxX));
|
||||
int iMinY = (std::max)(m_iMinY, (int)floorf(fMinY));
|
||||
int iMaxY = (std::min)(m_iMaxY + 1, (int)ceilf(fMaxY));
|
||||
|
||||
for (int y = iMinY; y < iMaxY; y++)
|
||||
{
|
||||
inpSink->Line(fMinX, fMaxX, iMinX, iMaxX, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CSimpleTriangleRasterizer::CallbackFillConservative(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
||||
{
|
||||
float x[3], y[3];
|
||||
|
||||
CopyAndSortY(_x, _y, x, y);
|
||||
|
||||
// Calculate interpolation steps
|
||||
float fX1toX2step = 0.0f;
|
||||
float fX1toX3step = 0.0f;
|
||||
float fX2toX3step = 0.0f;
|
||||
if (fabsf(y[1] - y[0]) > FLT_EPSILON)
|
||||
{
|
||||
fX1toX2step = (x[1] - x[0]) / (float)(y[1] - y[0]);
|
||||
}
|
||||
if (fabsf(y[2] - y[0]) > FLT_EPSILON)
|
||||
{
|
||||
fX1toX3step = (x[2] - x[0]) / (float)(y[2] - y[0]);
|
||||
}
|
||||
if (fabsf(y[2] - y[1]) > FLT_EPSILON)
|
||||
{
|
||||
fX2toX3step = (x[2] - x[1]) / (float)(y[2] - y[1]);
|
||||
}
|
||||
|
||||
float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1];
|
||||
bool bFirstLine = true;
|
||||
bool bTriangleCallDone = false;
|
||||
|
||||
// Go through the scanlines of the triangle
|
||||
int yy = (int)floorf(y[0]); // was floor
|
||||
|
||||
for (; yy <= (int)floorf(y[2]); yy++)
|
||||
// for(yy=m_iMinY; yy<=m_iMaxY; yy++) // juhu
|
||||
{
|
||||
float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f;
|
||||
float start, end;
|
||||
|
||||
// first line
|
||||
if (bFirstLine)
|
||||
{
|
||||
fSubPixelYStart = y[0] - floorf(y[0]);
|
||||
start = x[0];
|
||||
end = x[0];
|
||||
bFirstLine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// top part without middle corner line
|
||||
if (yy <= (int)floorf(y[1]))
|
||||
{
|
||||
start = (std::min)(fX1toX2, fX1toX3);
|
||||
end = (std::max)(fX1toX2, fX1toX3);
|
||||
}
|
||||
else
|
||||
{
|
||||
start = (std::min)(fX2toX3, fX1toX3);
|
||||
end = (std::max)(fX2toX3, fX1toX3);
|
||||
}
|
||||
}
|
||||
|
||||
// middle corner line
|
||||
if (yy == (int)floorf(y[1]))
|
||||
{
|
||||
fSubPixelYEnd = y[1] - floorf(y[1]);
|
||||
|
||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
start = (std::min)(start, fX1toX3);
|
||||
end = (std::max)(end, fX1toX3);
|
||||
start = (std::min)(start, x[1]);
|
||||
end = (std::max)(end, x[1]);
|
||||
|
||||
fSubPixelYStart = fSubPixelYEnd;
|
||||
fSubPixelYEnd = 1.0f;
|
||||
}
|
||||
|
||||
// last line
|
||||
if (yy == (int)floorf(y[2]))
|
||||
{
|
||||
start = (std::min)(start, x[2]);
|
||||
end = (std::max)(end, x[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// top part without middle corner line
|
||||
if (yy < (int)floorf(y[1]))
|
||||
{
|
||||
fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
start = (std::min)(start, fX1toX2);
|
||||
end = (std::max)(end, fX1toX2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
start = (std::min)(start, fX2toX3);
|
||||
end = (std::max)(end, fX2toX3);
|
||||
}
|
||||
|
||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
start = (std::min)(start, fX1toX3);
|
||||
end = (std::max)(end, fX1toX3);
|
||||
}
|
||||
|
||||
if (yy >= m_iMinY && yy <= m_iMaxY)
|
||||
{
|
||||
if (!bTriangleCallDone)
|
||||
{
|
||||
inpSink->Triangle(yy);
|
||||
bTriangleCallDone = true;
|
||||
}
|
||||
|
||||
lambertHorizlineConservative(start, end, yy, inpSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CSimpleTriangleRasterizer::CallbackFillSubpixelCorrect(float _x[3], float _y[3], IRasterizeSink* inpSink)
|
||||
{
|
||||
float x[3], y[3];
|
||||
|
||||
CopyAndSortY(_x, _y, x, y);
|
||||
|
||||
if (fabs(y[0] - floorf(y[0])) < FLT_EPSILON)
|
||||
{
|
||||
y[0] -= FLT_EPSILON;
|
||||
}
|
||||
|
||||
// Calculate interpolation steps
|
||||
float fX1toX2step = 0.0f;
|
||||
float fX1toX3step = 0.0f;
|
||||
float fX2toX3step = 0.0f;
|
||||
if (fabsf(y[1] - y[0]) > FLT_EPSILON)
|
||||
{
|
||||
fX1toX2step = (x[1] - x[0]) / (y[1] - y[0]);
|
||||
}
|
||||
if (fabsf(y[2] - y[0]) > FLT_EPSILON)
|
||||
{
|
||||
fX1toX3step = (x[2] - x[0]) / (y[2] - y[0]);
|
||||
}
|
||||
if (fabsf(y[2] - y[1]) > FLT_EPSILON)
|
||||
{
|
||||
fX2toX3step = (x[2] - x[1]) / (y[2] - y[1]);
|
||||
}
|
||||
|
||||
float fX1toX2 = x[0], fX1toX3 = x[0], fX2toX3 = x[1];
|
||||
bool bFirstLine = true;
|
||||
bool bTriangleCallDone = false;
|
||||
|
||||
y[0] -= 0.5f;
|
||||
y[1] -= 0.5f;
|
||||
y[2] -= 0.5f;
|
||||
// y[0]=y[0]*1023.f/1024.f+1.f;
|
||||
// y[1]=y[1]*1023.f/1024.f+1.f;
|
||||
// y[2]=y[2]*1023.f/1024.f+1.f;
|
||||
|
||||
for (int yy = (int)floorf(y[0]); yy <= (int)floorf(y[2]); yy++)
|
||||
{
|
||||
float fSubPixelYStart = 0.0f, fSubPixelYEnd = 1.0f;
|
||||
float start, end;
|
||||
|
||||
// first line
|
||||
if (bFirstLine)
|
||||
{
|
||||
fSubPixelYStart = y[0] - floorf(y[0]);
|
||||
start = x[0];
|
||||
end = x[0];
|
||||
bFirstLine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// top part without middle corner line
|
||||
if (yy <= (int)floorf(y[1]))
|
||||
{
|
||||
start = (std::min)(fX1toX2, fX1toX3);
|
||||
end = (std::max)(fX1toX2, fX1toX3);
|
||||
}
|
||||
else
|
||||
{
|
||||
start = (std::min)(fX2toX3, fX1toX3);
|
||||
end = (std::max)(fX2toX3, fX1toX3);
|
||||
}
|
||||
}
|
||||
|
||||
// middle corner line
|
||||
if (yy == (int)floorf(y[1]))
|
||||
{
|
||||
fSubPixelYEnd = y[1] - floorf(y[1]);
|
||||
|
||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
|
||||
fSubPixelYStart = fSubPixelYEnd;
|
||||
fSubPixelYEnd = 1.0f;
|
||||
}
|
||||
|
||||
// last line
|
||||
if (yy != (int)floorf(y[2]))
|
||||
{
|
||||
// top part without middle corner line
|
||||
if (yy < (int)floorf(y[1]))
|
||||
{
|
||||
fX1toX2 += fX1toX2step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
fX2toX3 += fX2toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
}
|
||||
|
||||
fX1toX3 += fX1toX3step * (fSubPixelYEnd - fSubPixelYStart);
|
||||
}
|
||||
|
||||
if (start != end)
|
||||
{
|
||||
if (yy >= m_iMinY && yy <= m_iMaxY)
|
||||
{
|
||||
if (!bTriangleCallDone)
|
||||
{
|
||||
inpSink->Triangle(yy);
|
||||
bTriangleCallDone = true;
|
||||
}
|
||||
|
||||
lambertHorizlineSubpixelCorrect(start, end, yy, inpSink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// shrink triangle by n pixel, optimizable
|
||||
void CSimpleTriangleRasterizer::ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount)
|
||||
{
|
||||
float fX[3] = { inoutfX[0], inoutfX[1], inoutfX[2] };
|
||||
float fY[3] = { inoutfY[0], inoutfY[1], inoutfY[2] };
|
||||
|
||||
/*
|
||||
// move edge to opposing vertex
|
||||
float dx,dy,fLength;
|
||||
|
||||
for(int a=0;a<3;a++)
|
||||
{
|
||||
int b=a+1;if(b>=3)b=0;
|
||||
int c=b+1;if(c>=3)c=0;
|
||||
|
||||
dx=fX[a]-(fX[b]+fX[c])*0.5f;
|
||||
dy=fY[a]-(fY[b]+fY[c])*0.5f;
|
||||
fLength=(float)sqrt(dx*dx+dy*dy);
|
||||
if(fLength>1.0f)
|
||||
{
|
||||
dx/=fLength;dy/=fLength;
|
||||
inoutfX[b]+=dx;inoutfY[b]+=dy;
|
||||
inoutfX[c]+=dx;inoutfY[c]+=dy;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// move vertex to opposing edge
|
||||
float dx,dy,fLength;
|
||||
|
||||
for(int a=0;a<3;a++)
|
||||
{
|
||||
int b=a+1;if(b>=3)b=0;
|
||||
int c=b+1;if(c>=3)c=0;
|
||||
|
||||
dx=fX[a]-(fX[b]+fX[c])*0.5f;
|
||||
dy=fY[a]-(fY[b]+fY[c])*0.5f;
|
||||
fLength=(float)sqrt(dx*dx+dy*dy);
|
||||
if(fLength>1.0f)
|
||||
{
|
||||
dx/=fLength;dy/=fLength;
|
||||
inoutfX[a]-=dx;inoutfY[a]-=dy;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// move vertex to get edges shifted perpendicular for 1 unit
|
||||
for (int a = 0; a < 3; a++)
|
||||
{
|
||||
float dx1, dy1, dx2, dy2, fLength;
|
||||
|
||||
int b = a + 1;
|
||||
if (b >= 3)
|
||||
{
|
||||
b = 0;
|
||||
}
|
||||
int c = b + 1;
|
||||
if (c >= 3)
|
||||
{
|
||||
c = 0;
|
||||
}
|
||||
|
||||
dx1 = fX[b] - fX[a];
|
||||
dy1 = fY[b] - fY[a];
|
||||
fLength = (float)sqrt(dx1 * dx1 + dy1 * dy1);
|
||||
if (infAmount > 0)
|
||||
{
|
||||
if (fLength < infAmount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fLength == 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dx1 /= fLength;
|
||||
dy1 /= fLength;
|
||||
|
||||
dx2 = fX[c] - fX[a];
|
||||
dy2 = fY[c] - fY[a];
|
||||
fLength = (float)sqrt(dx2 * dx2 + dy2 * dy2);
|
||||
if (infAmount > 0)
|
||||
{
|
||||
if (fLength < infAmount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fLength == 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dx2 /= fLength;
|
||||
dy2 /= fLength;
|
||||
|
||||
inoutfX[a] += (dx1 + dx2) * infAmount;
|
||||
inoutfY[a] += (dy1 + dy2) * infAmount;
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
||||
#define CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
||||
#pragma once
|
||||
|
||||
class CSimpleTriangleRasterizer
|
||||
{
|
||||
public:
|
||||
|
||||
class IRasterizeSink
|
||||
{
|
||||
public:
|
||||
|
||||
//! is called once per triangel for the first possible visible line
|
||||
//! /param iniStartY
|
||||
virtual void Triangle([[maybe_unused]] const int iniStartY)
|
||||
{
|
||||
}
|
||||
|
||||
//! callback function
|
||||
//! /param infXLeft included - not clipped against left and reight border
|
||||
//! /param infXRight excluded - not clipped against left and reight border
|
||||
//! /param iniXLeft included
|
||||
//! /param iniXRight excluded
|
||||
//! /param iniY
|
||||
virtual void Line(const float infXLeft, const float infXRight,
|
||||
const int iniXLeft, const int iniXRight, const int iniY) = 0;
|
||||
};
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
//! implementation sink sample
|
||||
class CDWORDFlatFill
|
||||
: public IRasterizeSink
|
||||
{
|
||||
public:
|
||||
|
||||
//! constructor
|
||||
CDWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, DWORD indwValue)
|
||||
{
|
||||
m_dwValue = indwValue;
|
||||
m_pBuffer = inpBuffer;
|
||||
m_dwPitchInPixels = indwPitchInPixels;
|
||||
}
|
||||
|
||||
virtual void Triangle(const int iniY)
|
||||
{
|
||||
m_pBufferLine = &m_pBuffer[iniY * m_dwPitchInPixels];
|
||||
}
|
||||
|
||||
virtual void Line([[maybe_unused]] const float infXLeft, [[maybe_unused]] const float infXRight,
|
||||
const int iniLeft, const int iniRight, [[maybe_unused]] const int iniY)
|
||||
{
|
||||
DWORD* mem = &m_pBufferLine[iniLeft];
|
||||
|
||||
for (int x = iniLeft; x < iniRight; x++)
|
||||
{
|
||||
*mem++ = m_dwValue;
|
||||
}
|
||||
|
||||
m_pBufferLine += m_dwPitchInPixels;
|
||||
}
|
||||
|
||||
private:
|
||||
DWORD m_dwValue; //!< fill value
|
||||
DWORD* m_pBufferLine; //!< to get rid of the multiplication per line
|
||||
|
||||
DWORD m_dwPitchInPixels; //!< in DWORDS, not in Bytes
|
||||
DWORD* m_pBuffer; //!< pointer to the buffer
|
||||
};
|
||||
|
||||
// -----------------------------------------------------
|
||||
|
||||
//! constructor
|
||||
//! /param iniWidth excluded
|
||||
//! /param iniHeight excluded
|
||||
CSimpleTriangleRasterizer(const int iniWidth, const int iniHeight)
|
||||
{
|
||||
m_iMinX = 0;
|
||||
m_iMinY = 0;
|
||||
m_iMaxX = iniWidth - 1;
|
||||
m_iMaxY = iniHeight - 1;
|
||||
}
|
||||
/*
|
||||
//! constructor
|
||||
//! /param iniMinX included
|
||||
//! /param iniMinY included
|
||||
//! /param iniMaxX included
|
||||
//! /param iniMaxY included
|
||||
CSimpleTriangleRasterizer( const int iniMinX, const int iniMinY, const int iniMaxX, const int iniMaxY )
|
||||
{
|
||||
m_iMinX=iniMinX;
|
||||
m_iMinY=iniMinY;
|
||||
m_iMaxX=iniMaxX;
|
||||
m_iMaxY=iniMaxY;
|
||||
}
|
||||
*/
|
||||
//! simple triangle filler with clipping (optimizable), not subpixel correct
|
||||
//! /param pBuffer pointer o the color buffer
|
||||
//! /param indwWidth width of the color buffer
|
||||
//! /param indwHeight height of the color buffer
|
||||
//! /param x array of the x coordiantes of the three vertices
|
||||
//! /param y array of the x coordiantes of the three vertices
|
||||
//! /param indwValue value of the triangle
|
||||
void DWORDFlatFill(DWORD* inpBuffer, const DWORD indwPitchInPixels, float x[3], float y[3], DWORD indwValue, bool inbConservative)
|
||||
{
|
||||
CDWORDFlatFill pix(inpBuffer, indwPitchInPixels, indwValue);
|
||||
|
||||
if (inbConservative)
|
||||
{
|
||||
CallbackFillConservative(x, y, &pix);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackFillSubpixelCorrect(x, y, &pix);
|
||||
}
|
||||
}
|
||||
|
||||
// Rectangle around triangle - more stable - use for debugging purpose
|
||||
void CallbackFillRectConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
||||
|
||||
|
||||
//! subpixel correct triangle filler (conservative or not conservative)
|
||||
//! \param pBuffer pointe to the DWORD
|
||||
//! \param indwWidth width of the buffer pBuffer pointes to
|
||||
//! \param indwHeight height of the buffer pBuffer pointes to
|
||||
//! \param x array of the x coordiantes of the three vertices
|
||||
//! \param y array of the x coordiantes of the three vertices
|
||||
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
||||
void CallbackFillConservative(float x[3], float y[3], IRasterizeSink * inpSink);
|
||||
|
||||
//! subpixel correct triangle filler (conservative or not conservative)
|
||||
//! \param pBuffer pointe to the DWORD
|
||||
//! \param indwWidth width of the buffer pBuffer pointes to
|
||||
//! \param indwHeight height of the buffer pBuffer pointes to
|
||||
//! \param x array of the x coordiantes of the three vertices
|
||||
//! \param y array of the x coordiantes of the three vertices
|
||||
//! \param inpSink pointer to the sink interface (is called per triangle and per triangle line)
|
||||
void CallbackFillSubpixelCorrect(float x[3], float y[3], IRasterizeSink * inpSink);
|
||||
|
||||
//!
|
||||
//! /param inoutfX
|
||||
//! /param inoutfY
|
||||
//! /param infAmount could be positive or negative
|
||||
static void ShrinkTriangle(float inoutfX[3], float inoutfY[3], float infAmount);
|
||||
|
||||
private:
|
||||
|
||||
// Clipping Rect;
|
||||
|
||||
int m_iMinX; //!< minimum x value included
|
||||
int m_iMinY; //!< minimum y value included
|
||||
int m_iMaxX; //!< maximum x value included
|
||||
int m_iMaxY; //!< maximum x value included
|
||||
|
||||
void lambertHorizlineConservative(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
||||
void lambertHorizlineSubpixelCorrect(float fx1, float fx2, int y, IRasterizeSink* inpSink);
|
||||
void CopyAndSortY(const float infX[3], const float infY[3], float outfX[3], float outfY[3]);
|
||||
};
|
||||
|
||||
|
||||
// extension ideas:
|
||||
// * callback with coverage mask (possible non ordered sampling)
|
||||
// * z-buffer behaviour
|
||||
// * gouraud shading
|
||||
// * texture mapping with nearest/bicubic/bilinear filter
|
||||
// * further primitives: thick line, ellipse
|
||||
// * build a template version
|
||||
// *
|
||||
|
||||
#endif // CRYINCLUDE_EDITOR_LIGHTMAPCOMPILER_SIMPLETRIANGLERASTERIZER_H
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "Util/Image.h"
|
||||
#include "ObjectManagerLegacyUndo.h"
|
||||
#include "Include/HitContext.h"
|
||||
#include "EditMode/DeepSelection.h"
|
||||
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
|
||||
|
||||
#include <AzCore/Console/Console.h>
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
#include "CheckOutDialog.h"
|
||||
#include "ISourceControl.h"
|
||||
#include "Dialogs/Generic/UserOptions.h"
|
||||
#include "IAssetItem.h"
|
||||
#include "IAssetItemDatabase.h"
|
||||
#include "Include/IObjectManager.h"
|
||||
#include "UsedResources.h"
|
||||
#include "Objects/BaseObject.h"
|
||||
@@ -223,106 +221,6 @@ void CFileUtil::EditTextureFile(const char* textureFile, [[maybe_unused]] bool b
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CFileUtil::CalculateDccFilename(const QString& assetFilename, QString& dccFilename)
|
||||
{
|
||||
if (ExtractDccFilenameFromAssetDatabase(assetFilename, dccFilename))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ExtractDccFilenameUsingNamingConventions(assetFilename, dccFilename))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
GetIEditor()->GetEnv()->pLog->LogError("Failed to find psd file for texture: '%s'", assetFilename.toUtf8().data());
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CFileUtil::ExtractDccFilenameFromAssetDatabase(const QString& assetFilename, QString& dccFilename)
|
||||
{
|
||||
IAssetItemDatabase* pCurrentDatabaseInterface = nullptr;
|
||||
std::vector<IClassDesc*> assetDatabasePlugins;
|
||||
IEditorClassFactory* pClassFactory = GetIEditor()->GetClassFactory();
|
||||
pClassFactory->GetClassesByCategory("Asset Item DB", assetDatabasePlugins);
|
||||
|
||||
for (size_t i = 0; i < assetDatabasePlugins.size(); ++i)
|
||||
{
|
||||
if (assetDatabasePlugins[i]->QueryInterface(__az_uuidof(IAssetItemDatabase), (void**)&pCurrentDatabaseInterface) == S_OK)
|
||||
{
|
||||
if (!pCurrentDatabaseInterface)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QString assetDatabaseDccFilename;
|
||||
IAssetItem* pAssetItem = pCurrentDatabaseInterface->GetAsset(assetFilename.toUtf8().data());
|
||||
if (pAssetItem)
|
||||
{
|
||||
if ((pAssetItem->GetFlags() & IAssetItem::eFlag_Cached))
|
||||
{
|
||||
QVariant v = pAssetItem->GetAssetFieldValue("dccfilename");
|
||||
assetDatabaseDccFilename = v.toString();
|
||||
if (!v.isNull())
|
||||
{
|
||||
dccFilename = assetDatabaseDccFilename;
|
||||
dccFilename = Path::GetRelativePath(dccFilename, false);
|
||||
|
||||
uint32 attr = CFileUtil::GetAttributes(dccFilename.toUtf8().data());
|
||||
|
||||
if (CFileUtil::FileExists(dccFilename))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (GetIEditor()->IsSourceControlAvailable() && (attr & SCC_FILE_ATTRIBUTE_MANAGED))
|
||||
{
|
||||
return CFileUtil::GetLatestFromSourceControl(dccFilename.toUtf8().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CFileUtil::ExtractDccFilenameUsingNamingConventions(const QString& assetFilename, QString& dccFilename)
|
||||
{
|
||||
//else to try find it by naming conventions
|
||||
QString tempStr = assetFilename;
|
||||
int foundSplit = -1;
|
||||
if ((foundSplit = tempStr.lastIndexOf('.')) > 0)
|
||||
{
|
||||
QString first = tempStr.mid(0, foundSplit);
|
||||
tempStr = first + ".psd";
|
||||
}
|
||||
if (CFileUtil::FileExists(tempStr))
|
||||
{
|
||||
dccFilename = tempStr;
|
||||
return true;
|
||||
}
|
||||
|
||||
//else try to find it by replacing post fix _<description> with .psd
|
||||
tempStr = assetFilename;
|
||||
foundSplit = -1;
|
||||
if ((foundSplit = tempStr.lastIndexOf('_')) > 0)
|
||||
{
|
||||
QString first = tempStr.mid(0, foundSplit);
|
||||
tempStr = first + ".psd";
|
||||
}
|
||||
if (CFileUtil::FileExists(tempStr))
|
||||
{
|
||||
dccFilename = tempStr;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CFileUtil::FormatFilterString(QString& filter)
|
||||
{
|
||||
|
||||
@@ -29,9 +29,6 @@ public:
|
||||
static void EditTextFile(const char* txtFile, int line = 0, IFileUtil::ETextFileType fileType = IFileUtil::FILE_TYPE_SCRIPT);
|
||||
static void EditTextureFile(const char* txtureFile, bool bUseGameFolder);
|
||||
|
||||
//! dcc filename calculation and extraction sub-routines
|
||||
static bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename);
|
||||
|
||||
//! Reformat filter string for (MFC) CFileDialog style file filtering
|
||||
static void FormatFilterString(QString& filter);
|
||||
|
||||
@@ -155,9 +152,6 @@ private:
|
||||
|
||||
// Keep this variant of this method private! pIsSelected is captured in a lambda, and so requires menu use exec() and never use show()
|
||||
static void PopulateQMenu(QWidget* caller, QMenu* menu, AZStd::string_view fullGamePath, bool* pIsSelected);
|
||||
|
||||
static bool ExtractDccFilenameFromAssetDatabase(const QString& assetFilename, QString& dccFilename);
|
||||
static bool ExtractDccFilenameUsingNamingConventions(const QString& assetFilename, QString& dccFilename);
|
||||
};
|
||||
|
||||
class CAutoRestorePrimaryCDRoot
|
||||
|
||||
@@ -30,11 +30,6 @@ void CFileUtil_impl::EditTextureFile(const char* txtureFile, bool bUseGameFolder
|
||||
CFileUtil::EditTextureFile(txtureFile, bUseGameFolder);
|
||||
}
|
||||
|
||||
bool CFileUtil_impl::CalculateDccFilename(const QString& assetFilename, QString& dccFilename)
|
||||
{
|
||||
return CFileUtil::CalculateDccFilename(assetFilename, dccFilename);
|
||||
}
|
||||
|
||||
void CFileUtil_impl::FormatFilterString(QString& filter)
|
||||
{
|
||||
CFileUtil::FormatFilterString(filter);
|
||||
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
bool ExtractFile(QString& file, bool bMsgBoxAskForExtraction = true, const char* pDestinationFilename = nullptr) override;
|
||||
void EditTextureFile(const char* txtureFile, bool bUseGameFolder) override;
|
||||
|
||||
//! dcc filename calculation and extraction sub-routines
|
||||
bool CalculateDccFilename(const QString& assetFilename, QString& dccFilename) override;
|
||||
|
||||
//! Reformat filter string for (MFC) CFileDialog style file filtering
|
||||
void FormatFilterString(QString& filter) override;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "ViewportTitleDlg.h"
|
||||
|
||||
// Qt
|
||||
#include <QCheckBox>
|
||||
#include <QLabel>
|
||||
#include <QInputDialog>
|
||||
|
||||
@@ -43,6 +44,7 @@
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportSettings.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
#include <AzQtComponents/Components/Widgets/CheckBox.h>
|
||||
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
|
||||
@@ -51,6 +53,8 @@ AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#endif //! defined(Q_MOC_RUN)
|
||||
|
||||
static constexpr int MiniumOverflowMenuWidth = 200;
|
||||
|
||||
// CViewportTitleDlg dialog
|
||||
|
||||
namespace
|
||||
@@ -257,21 +261,56 @@ void CViewportTitleDlg::SetupHelpersButton()
|
||||
|
||||
void CViewportTitleDlg::SetupOverflowMenu()
|
||||
{
|
||||
// Setup the overflow menu
|
||||
QMenu* overFlowMenu = new QMenu(this);
|
||||
// simple override of QMenu that does not respond to keyboard events
|
||||
// note: this prevents the menu from being prematurely closed
|
||||
class IgnoreKeyboardMenu : public QMenu
|
||||
{
|
||||
public:
|
||||
IgnoreKeyboardMenu(QWidget *parent = nullptr) : QMenu(parent)
|
||||
{
|
||||
}
|
||||
|
||||
m_audioMuteAction = new QAction("Mute Audio", overFlowMenu);
|
||||
private:
|
||||
void keyPressEvent(QKeyEvent* event) override
|
||||
{
|
||||
// regular escape key handling
|
||||
if (event->key() == Qt::Key_Escape)
|
||||
{
|
||||
QMenu::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// setup the overflow menu
|
||||
auto* overflowMenu = new IgnoreKeyboardMenu(this);
|
||||
overflowMenu->setMinimumWidth(MiniumOverflowMenuWidth);
|
||||
|
||||
m_audioMuteAction = new QAction("Mute Audio", overflowMenu);
|
||||
connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio);
|
||||
overFlowMenu->addAction(m_audioMuteAction);
|
||||
overflowMenu->addAction(m_audioMuteAction);
|
||||
|
||||
overFlowMenu->addSeparator();
|
||||
overflowMenu->addSeparator();
|
||||
|
||||
m_enableGridSnappingAction = new QAction("Enable Grid Snapping", overFlowMenu);
|
||||
connect(m_enableGridSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnGridSnappingToggled);
|
||||
m_enableGridSnappingAction->setCheckable(true);
|
||||
overFlowMenu->addAction(m_enableGridSnappingAction);
|
||||
m_enableGridSnappingCheckBox = new QCheckBox("Enable Grid Snapping", overflowMenu);
|
||||
AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableGridSnappingCheckBox);
|
||||
auto gridSnappingWidgetAction = new QWidgetAction(overflowMenu);
|
||||
gridSnappingWidgetAction->setDefaultWidget(m_enableGridSnappingCheckBox);
|
||||
connect(m_enableGridSnappingCheckBox, &QCheckBox::stateChanged, this, &CViewportTitleDlg::OnGridSnappingToggled);
|
||||
overflowMenu->addAction(gridSnappingWidgetAction);
|
||||
|
||||
m_gridSizeActionWidget = new QWidgetAction(overFlowMenu);
|
||||
m_enableGridVisualizationCheckBox = new QCheckBox("Show Grid", overflowMenu);
|
||||
AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableGridVisualizationCheckBox);
|
||||
auto gridVisualizationWidgetAction = new QWidgetAction(overflowMenu);
|
||||
gridVisualizationWidgetAction->setDefaultWidget(m_enableGridVisualizationCheckBox);
|
||||
connect(
|
||||
m_enableGridVisualizationCheckBox, &QCheckBox::stateChanged,
|
||||
[](const int state)
|
||||
{
|
||||
SandboxEditor::SetShowingGrid(state == Qt::Checked);
|
||||
});
|
||||
overflowMenu->addAction(gridVisualizationWidgetAction);
|
||||
|
||||
m_gridSizeActionWidget = new QWidgetAction(overflowMenu);
|
||||
m_gridSpinBox = new AzQtComponents::DoubleSpinBox();
|
||||
m_gridSpinBox->setValue(SandboxEditor::GridSnappingSize());
|
||||
m_gridSpinBox->setMinimum(1e-2f);
|
||||
@@ -281,31 +320,33 @@ void CViewportTitleDlg::SetupOverflowMenu()
|
||||
m_gridSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this, &CViewportTitleDlg::OnGridSpinBoxChanged);
|
||||
|
||||
m_gridSizeActionWidget->setDefaultWidget(m_gridSpinBox);
|
||||
overFlowMenu->addAction(m_gridSizeActionWidget);
|
||||
overflowMenu->addAction(m_gridSizeActionWidget);
|
||||
|
||||
overFlowMenu->addSeparator();
|
||||
overflowMenu->addSeparator();
|
||||
|
||||
m_enableAngleSnappingAction = new QAction("Enable Angle Snapping", overFlowMenu);
|
||||
connect(m_enableAngleSnappingAction, &QAction::triggered, this, &CViewportTitleDlg::OnAngleSnappingToggled);
|
||||
m_enableAngleSnappingAction->setCheckable(true);
|
||||
overFlowMenu->addAction(m_enableAngleSnappingAction);
|
||||
m_enableAngleSnappingCheckBox = new QCheckBox("Enable Angle Snapping", overflowMenu);
|
||||
AzQtComponents::CheckBox::applyToggleSwitchStyle(m_enableAngleSnappingCheckBox);
|
||||
auto angleSnappingWidgetAction = new QWidgetAction(overflowMenu);
|
||||
angleSnappingWidgetAction->setDefaultWidget(m_enableAngleSnappingCheckBox);
|
||||
connect(m_enableAngleSnappingCheckBox, &QCheckBox::stateChanged, this, &CViewportTitleDlg::OnAngleSnappingToggled);
|
||||
overflowMenu->addAction(angleSnappingWidgetAction);
|
||||
|
||||
m_angleSizeActionWidget = new QWidgetAction(overFlowMenu);
|
||||
m_angleSizeActionWidget = new QWidgetAction(overflowMenu);
|
||||
m_angleSpinBox = new AzQtComponents::DoubleSpinBox();
|
||||
m_angleSpinBox->setValue(SandboxEditor::AngleSnappingSize());
|
||||
m_angleSpinBox->setMinimum(1e-2f);
|
||||
m_angleSpinBox->setToolTip(tr("Angle Snapping"));
|
||||
m_angleSpinBox->setToolTip(tr("Angle size"));
|
||||
|
||||
QObject::connect(
|
||||
m_angleSpinBox, QOverload<double>::of(&AzQtComponents::DoubleSpinBox::valueChanged), this,
|
||||
&CViewportTitleDlg::OnAngleSpinBoxChanged);
|
||||
|
||||
m_angleSizeActionWidget->setDefaultWidget(m_angleSpinBox);
|
||||
overFlowMenu->addAction(m_angleSizeActionWidget);
|
||||
overflowMenu->addAction(m_angleSizeActionWidget);
|
||||
|
||||
m_ui->m_overflowBtn->setMenu(overFlowMenu);
|
||||
m_ui->m_overflowBtn->setMenu(overflowMenu);
|
||||
m_ui->m_overflowBtn->setPopupMode(QToolButton::InstantPopup);
|
||||
connect(overFlowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState);
|
||||
connect(overflowMenu, &QMenu::aboutToShow, this, &CViewportTitleDlg::UpdateOverFlowMenuState);
|
||||
|
||||
UpdateMuteActionText();
|
||||
}
|
||||
@@ -982,43 +1023,49 @@ void CViewportTitleDlg::CheckForCameraSpeedUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::OnGridSnappingToggled()
|
||||
void CViewportTitleDlg::OnGridSnappingToggled(const int state)
|
||||
{
|
||||
m_gridSizeActionWidget->setEnabled(m_enableGridSnappingAction->isChecked());
|
||||
m_gridSizeActionWidget->setEnabled(state == Qt::Checked);
|
||||
m_enableGridVisualizationCheckBox->setEnabled(state == Qt::Checked);
|
||||
MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->trigger();
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::OnAngleSnappingToggled()
|
||||
void CViewportTitleDlg::OnAngleSnappingToggled(const int state)
|
||||
{
|
||||
m_angleSizeActionWidget->setEnabled(m_enableAngleSnappingAction->isChecked());
|
||||
m_angleSizeActionWidget->setEnabled(state == Qt::Checked);
|
||||
MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->trigger();
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::OnGridSpinBoxChanged(double value)
|
||||
void CViewportTitleDlg::OnGridSpinBoxChanged(const double value)
|
||||
{
|
||||
SandboxEditor::SetGridSnappingSize(static_cast<float>(value));
|
||||
SandboxEditor::SetGridSnappingSize(aznumeric_cast<float>(value));
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::OnAngleSpinBoxChanged(double value)
|
||||
void CViewportTitleDlg::OnAngleSpinBoxChanged(const double value)
|
||||
{
|
||||
SandboxEditor::SetAngleSnappingSize(static_cast<float>(value));
|
||||
SandboxEditor::SetAngleSnappingSize(aznumeric_cast<float>(value));
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::UpdateOverFlowMenuState()
|
||||
{
|
||||
bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->isChecked();
|
||||
const bool gridSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapToGrid)->isChecked();
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_enableGridSnappingAction);
|
||||
m_enableGridSnappingAction->setChecked(gridSnappingActive);
|
||||
QSignalBlocker signalBlocker(m_enableGridSnappingCheckBox);
|
||||
m_enableGridSnappingCheckBox->setChecked(gridSnappingActive);
|
||||
}
|
||||
m_gridSizeActionWidget->setEnabled(gridSnappingActive);
|
||||
|
||||
bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->isChecked();
|
||||
const bool angleSnappingActive = MainWindow::instance()->GetActionManager()->GetAction(AzToolsFramework::SnapAngle)->isChecked();
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_enableAngleSnappingAction);
|
||||
m_enableAngleSnappingAction->setChecked(angleSnappingActive);
|
||||
QSignalBlocker signalBlocker(m_enableAngleSnappingCheckBox);
|
||||
m_enableAngleSnappingCheckBox->setChecked(angleSnappingActive);
|
||||
}
|
||||
m_angleSizeActionWidget->setEnabled(angleSnappingActive);
|
||||
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_enableGridVisualizationCheckBox);
|
||||
m_enableGridVisualizationCheckBox->setChecked(SandboxEditor::ShowingGrid());
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
|
||||
@@ -140,8 +140,8 @@ protected:
|
||||
|
||||
void CheckForCameraSpeedUpdate();
|
||||
|
||||
void OnGridSnappingToggled();
|
||||
void OnAngleSnappingToggled();
|
||||
void OnGridSnappingToggled(int state);
|
||||
void OnAngleSnappingToggled(int state);
|
||||
|
||||
void OnGridSpinBoxChanged(double value);
|
||||
void OnAngleSpinBoxChanged(double value);
|
||||
@@ -160,8 +160,9 @@ protected:
|
||||
QAction* m_fullInformationAction = nullptr;
|
||||
QAction* m_compactInformationAction = nullptr;
|
||||
QAction* m_audioMuteAction = nullptr;
|
||||
QAction* m_enableGridSnappingAction = nullptr;
|
||||
QAction* m_enableAngleSnappingAction = nullptr;
|
||||
QCheckBox* m_enableGridSnappingCheckBox = nullptr;
|
||||
QCheckBox* m_enableGridVisualizationCheckBox = nullptr;
|
||||
QCheckBox* m_enableAngleSnappingCheckBox = nullptr;
|
||||
QComboBox* m_cameraSpeed = nullptr;
|
||||
AzQtComponents::DoubleSpinBox* m_gridSpinBox = nullptr;
|
||||
AzQtComponents::DoubleSpinBox* m_angleSpinBox = nullptr;
|
||||
@@ -175,7 +176,7 @@ protected:
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
//! A component to reflect scriptable commands for the Editor
|
||||
//! A component to reflect scriptable commands for the Editor.
|
||||
class ViewportTitleDlgPythonFuncsHandler
|
||||
: public AZ::Component
|
||||
{
|
||||
|
||||
@@ -269,9 +269,6 @@ set(FILES
|
||||
LevelTreeModel.h
|
||||
Include/Command.h
|
||||
Include/HitContext.h
|
||||
Include/IAnimationCompressionManager.h
|
||||
Include/IAssetItem.h
|
||||
Include/IAssetItemDatabase.h
|
||||
Include/ICommandManager.h
|
||||
Include/IConsoleConnectivity.h
|
||||
Include/IDataBaseItem.h
|
||||
@@ -457,18 +454,14 @@ set(FILES
|
||||
GameResourcesExporter.cpp
|
||||
GameExporter.h
|
||||
GameResourcesExporter.h
|
||||
Geometry/TriMesh.cpp
|
||||
Geometry/TriMesh.h
|
||||
AboutDialog.h
|
||||
AboutDialog.ui
|
||||
DocMultiArchive.h
|
||||
EditMode/DeepSelection.h
|
||||
FBXExporterDialog.h
|
||||
FileTypeUtils.h
|
||||
GridUtils.h
|
||||
IObservable.h
|
||||
IPostRenderer.h
|
||||
LightmapCompiler/SimpleTriangleRasterizer.h
|
||||
ToolBox.h
|
||||
TrackViewNewSequenceDialog.h
|
||||
UndoConfigSpec.h
|
||||
@@ -559,11 +552,9 @@ set(FILES
|
||||
AboutDialog.cpp
|
||||
ErrorReportTableModel.h
|
||||
ErrorReportTableModel.cpp
|
||||
EditMode/DeepSelection.cpp
|
||||
FBXExporterDialog.cpp
|
||||
FBXExporterDialog.ui
|
||||
FileTypeUtils.cpp
|
||||
LightmapCompiler/SimpleTriangleRasterizer.cpp
|
||||
ToolBox.cpp
|
||||
TrackViewNewSequenceDialog.cpp
|
||||
TrackViewNewSequenceDialog.ui
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Plane Plane::CreateFromNormalAndDistance(const Vector3& normal, float dist)
|
||||
{
|
||||
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
|
||||
Plane result;
|
||||
result.Set(normal, dist);
|
||||
return result;
|
||||
@@ -35,7 +34,6 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Plane Plane::CreateFromCoefficients(const float a, const float b, const float c, const float d)
|
||||
{
|
||||
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
|
||||
Plane result;
|
||||
result.Set(a, b, c, d);
|
||||
return result;
|
||||
@@ -68,21 +66,21 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE void Plane::Set(const Vector3& normal, float d)
|
||||
{
|
||||
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
|
||||
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
|
||||
m_plane.Set(normal, d);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE void Plane::Set(float a, float b, float c, float d)
|
||||
{
|
||||
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is notormalized");
|
||||
AZ_MATH_ASSERT(Vector3(a, b, c).IsNormalized(), "This normal is not normalized");
|
||||
m_plane.Set(a, b, c, d);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE void Plane::SetNormal(const Vector3& normal)
|
||||
{
|
||||
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is notormalized");
|
||||
AZ_MATH_ASSERT(normal.IsNormalized(), "This normal is not normalized");
|
||||
m_plane.SetX(normal.GetX());
|
||||
m_plane.SetY(normal.GetY());
|
||||
m_plane.SetZ(normal.GetZ());
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
#if AZ_DEBUG_BUILD
|
||||
#define AZ_MATH_TEST_START_TRACE_SUPPRESSION AZ_TEST_START_TRACE_SUPPRESSION
|
||||
#define AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(x) AZ_TEST_STOP_TRACE_SUPPRESSION(x)
|
||||
#else
|
||||
#define AZ_MATH_TEST_START_TRACE_SUPPRESSION
|
||||
#define AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(x)
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <Math/MathTest.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
@@ -47,7 +48,9 @@ namespace UnitTest
|
||||
TEST(MATH_Plane, TestSet)
|
||||
{
|
||||
Plane pl;
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
pl.Set(12.0f, 13.0f, 14.0f, 15.0f);
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetDistance(), 15.0f);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetX(), 12.0f);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetY(), 13.0f);
|
||||
@@ -57,7 +60,9 @@ namespace UnitTest
|
||||
TEST(MATH_Plane, TestSetVector3)
|
||||
{
|
||||
Plane pl;
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
pl.Set(Vector3(22.0f, 23.0f, 24.0f), 25.0f);
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetDistance(), 25.0f);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetX(), 22.0f);
|
||||
AZ_TEST_ASSERT_FLOAT_CLOSE(pl.GetNormal().GetY(), 23.0f);
|
||||
@@ -177,17 +182,21 @@ namespace UnitTest
|
||||
pl.Set(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
AZ_TEST_ASSERT(pl.IsFinite());
|
||||
const float infinity = std::numeric_limits<float>::infinity();
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
pl.Set(infinity, infinity, infinity, infinity);
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
AZ_TEST_ASSERT(!pl.IsFinite());
|
||||
}
|
||||
|
||||
TEST(MATH_Plane, CreateFromVectorCoefficients_IsEquivalentToCreateFromCoefficients)
|
||||
{
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
Plane planeFromCoefficients = Plane::CreateFromCoefficients(1.0, 2.0, 3.0, 4.0);
|
||||
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
Vector4 coefficients(1.0, 2.0, 3.0, 4.0);
|
||||
Plane planeFromVectorCoefficients = Plane::CreateFromVectorCoefficients(coefficients);
|
||||
|
||||
|
||||
EXPECT_EQ(planeFromVectorCoefficients, planeFromCoefficients);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <AzCore/Math/Obb.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
|
||||
#include <Math/MathTest.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
namespace UnitTest
|
||||
@@ -1409,13 +1411,17 @@ namespace UnitTest
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().y,-1)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().z,0)");
|
||||
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
script->Execute("pl:Set(12, 13, 14, 15)");
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetDistance(), 15)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().x, 12)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().y, 13)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().z, 14)");
|
||||
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
script->Execute("pl:Set(Vector3(22, 23, 24), 25)");
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetDistance(), 25)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().x, 22)");
|
||||
script->Execute("AZTestAssertFloatClose(pl:GetNormal().y, 23)");
|
||||
@@ -1493,7 +1499,9 @@ namespace UnitTest
|
||||
|
||||
script->Execute("pl:Set(1, 0, 0, 0)");
|
||||
script->Execute("AZTestAssert(pl:IsFinite())");
|
||||
AZ_MATH_TEST_START_TRACE_SUPPRESSION;
|
||||
script->Execute("pl:Set(math.huge, math.huge, math.huge, math.huge)");
|
||||
AZ_MATH_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
script->Execute("AZTestAssert( not pl:IsFinite())");
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ set(FILES
|
||||
Math/Matrix4x4PerformanceTests.cpp
|
||||
Math/Matrix4x4Tests.cpp
|
||||
Math/MatrixUtilsTests.cpp
|
||||
Math/MathTest.h
|
||||
Math/MathTestData.h
|
||||
Math/ObbPerformanceTests.cpp
|
||||
Math/ObbTests.cpp
|
||||
|
||||
@@ -17,6 +17,12 @@ namespace AZ
|
||||
{
|
||||
namespace DataTypes
|
||||
{
|
||||
enum class ScriptProcessorFallbackLogic
|
||||
{
|
||||
FailBuild, // this will log error & fail the build
|
||||
ContinueBuild // this will log the errors but continue the build logic
|
||||
};
|
||||
|
||||
class IScriptProcessorRule
|
||||
: public IRule
|
||||
{
|
||||
@@ -26,6 +32,8 @@ namespace AZ
|
||||
virtual ~IScriptProcessorRule() override = default;
|
||||
|
||||
virtual const AZStd::string& GetScriptFilename() const = 0;
|
||||
|
||||
virtual ScriptProcessorFallbackLogic GetScriptProcessorFallbackLogic() const = 0;
|
||||
};
|
||||
} // DataTypes
|
||||
} // SceneAPI
|
||||
|
||||
@@ -173,10 +173,13 @@ namespace AZ::SceneAPI::Behaviors
|
||||
UnloadPython();
|
||||
}
|
||||
|
||||
bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath)
|
||||
bool ScriptProcessorRuleBehavior::LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath, Events::ProcessingResult& fallbackResult)
|
||||
{
|
||||
using namespace AZ::SceneAPI;
|
||||
|
||||
fallbackResult = Events::ProcessingResult::Failure;
|
||||
int scriptDiscoveryAttempts = 0;
|
||||
const AZ::SceneAPI::Containers::SceneManifest& manifest = scene.GetManifest();
|
||||
const Containers::SceneManifest& manifest = scene.GetManifest();
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(manifest.GetValueStorage());
|
||||
for (const auto& scriptItem : view)
|
||||
{
|
||||
@@ -188,6 +191,8 @@ namespace AZ::SceneAPI::Behaviors
|
||||
}
|
||||
|
||||
++scriptDiscoveryAttempts;
|
||||
fallbackResult = (scriptItem.GetScriptProcessorFallbackLogic() == DataTypes::ScriptProcessorFallbackLogic::ContinueBuild) ?
|
||||
Events::ProcessingResult::Ignored : Events::ProcessingResult::Failure;
|
||||
|
||||
// check for file exist via absolute path
|
||||
if (!IO::FileIOBase::GetInstance()->Exists(scriptFilename.c_str()))
|
||||
@@ -301,7 +306,8 @@ namespace AZ::SceneAPI::Behaviors
|
||||
}
|
||||
};
|
||||
|
||||
if (LoadPython(context.GetScene(), scriptPath))
|
||||
[[maybe_unused]] Events::ProcessingResult fallbackResult;
|
||||
if (LoadPython(context.GetScene(), scriptPath, fallbackResult))
|
||||
{
|
||||
EditorPythonConsoleNotificationHandler logger;
|
||||
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
|
||||
@@ -333,8 +339,9 @@ namespace AZ::SceneAPI::Behaviors
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
Events::ProcessingResult fallbackResult;
|
||||
AZStd::string scriptPath;
|
||||
if (LoadPython(scene, scriptPath))
|
||||
if (LoadPython(scene, scriptPath, fallbackResult))
|
||||
{
|
||||
AZStd::string manifestUpdate;
|
||||
auto executeCallback = [&scene, &manifestUpdate, &scriptPath]()
|
||||
@@ -349,6 +356,12 @@ namespace AZ::SceneAPI::Behaviors
|
||||
EditorPythonConsoleNotificationHandler logger;
|
||||
m_editorPythonEventsInterface->ExecuteWithLock(executeCallback);
|
||||
|
||||
// if the returned scene manifest is empty then ignore the script update
|
||||
if (manifestUpdate.empty())
|
||||
{
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
EntityUtilityBus::Broadcast(&EntityUtilityBus::Events::ResetEntityContext);
|
||||
AZ::Interface<Prefab::PrefabSystemComponentInterface>::Get()->RemoveAllTemplates();
|
||||
|
||||
@@ -364,6 +377,11 @@ namespace AZ::SceneAPI::Behaviors
|
||||
}
|
||||
return Events::ProcessingResult::Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the manifest was not updated by the script, then return back the fallback result
|
||||
return fallbackResult;
|
||||
}
|
||||
}
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace AZ::SceneAPI::Behaviors
|
||||
|
||||
SCENE_DATA_API void GetManifestDependencyPaths(AZStd::vector<AZStd::string>& paths) override;
|
||||
protected:
|
||||
bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath);
|
||||
bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath, Events::ProcessingResult& fallbackResult);
|
||||
void UnloadPython();
|
||||
bool DoPrepareForExport(Events::PreExportEventContext& context);
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
// Enum types must have a TypeId tied to it in order for the reflection to succeed.
|
||||
AZ_TYPE_INFO_SPECIALIZE(SceneAPI::DataTypes::ScriptProcessorFallbackLogic, "{3DCABF3D-E8EF-43E7-B3C7-373E05825F60}");
|
||||
|
||||
namespace SceneAPI
|
||||
{
|
||||
namespace SceneData
|
||||
@@ -23,13 +26,23 @@ namespace AZ
|
||||
return m_scriptFilename;
|
||||
}
|
||||
|
||||
DataTypes::ScriptProcessorFallbackLogic ScriptProcessorRule::GetScriptProcessorFallbackLogic() const
|
||||
{
|
||||
return m_fallbackLogic;
|
||||
}
|
||||
|
||||
void ScriptProcessorRule::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<ScriptProcessorRule, DataTypes::IScriptProcessorRule>()->Version(1)
|
||||
->Field("scriptFilename", &ScriptProcessorRule::m_scriptFilename);
|
||||
serializeContext->Class<ScriptProcessorRule, DataTypes::IScriptProcessorRule>()->Version(2)
|
||||
->Field("scriptFilename", &ScriptProcessorRule::m_scriptFilename)
|
||||
->Field("fallbackLogic", &ScriptProcessorRule::m_fallbackLogic);
|
||||
|
||||
serializeContext->Enum<DataTypes::ScriptProcessorFallbackLogic>()
|
||||
->Value("FailBuild", DataTypes::ScriptProcessorFallbackLogic::FailBuild)
|
||||
->Value("ContinueBuild", DataTypes::ScriptProcessorFallbackLogic::ContinueBuild);
|
||||
|
||||
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
||||
if (editContext)
|
||||
|
||||
@@ -35,10 +35,13 @@ namespace AZ
|
||||
m_scriptFilename = AZStd::move(scriptFilename);
|
||||
}
|
||||
|
||||
DataTypes::ScriptProcessorFallbackLogic GetScriptProcessorFallbackLogic() const override;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
protected:
|
||||
AZStd::string m_scriptFilename;
|
||||
DataTypes::ScriptProcessorFallbackLogic m_fallbackLogic = DataTypes::ScriptProcessorFallbackLogic::FailBuild;
|
||||
};
|
||||
} // SceneData
|
||||
} // SceneAPI
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <SceneAPI/SceneCore/Containers/SceneManifest.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/Rules/IScriptProcessorRule.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
||||
#include <SceneAPI/SceneData/ReflectionRegistrar.h>
|
||||
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
|
||||
#include <SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h>
|
||||
@@ -271,5 +272,79 @@ namespace AZ
|
||||
auto update = scriptProcessorRuleBehavior.UpdateManifest(scene, AssetImportRequest::Update, AssetImportRequest::Generic);
|
||||
EXPECT_EQ(update, ProcessingResult::Ignored);
|
||||
}
|
||||
|
||||
TEST_F(SceneManifest_JSON, ScriptProcessorRule_DefaultFallbackLogic_Works)
|
||||
{
|
||||
using namespace AZ::SceneAPI;
|
||||
|
||||
constexpr const char* defaultJson = { R"JSON(
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ScriptProcessorRule",
|
||||
"scriptFilename": "foo.py"
|
||||
}
|
||||
]
|
||||
})JSON" };
|
||||
|
||||
auto scene = Containers::Scene("mock");
|
||||
auto result = scene.GetManifest().LoadFromString(defaultJson, m_serializeContext.get(), m_jsonRegistrationContext.get());
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_FALSE(scene.GetManifest().IsEmpty());
|
||||
ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1);
|
||||
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(scene.GetManifest().GetValueStorage());
|
||||
EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::FailBuild);
|
||||
}
|
||||
|
||||
TEST_F(SceneManifest_JSON, ScriptProcessorRule_ExplicitFallbackLogic_Works)
|
||||
{
|
||||
using namespace AZ::SceneAPI;
|
||||
|
||||
constexpr const char* fallbackLogicJson = { R"JSON(
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ScriptProcessorRule",
|
||||
"scriptFilename": "foo.py",
|
||||
"fallbackLogic": "FailBuild"
|
||||
}
|
||||
]
|
||||
})JSON" };
|
||||
|
||||
auto scene = Containers::Scene("mock");
|
||||
auto result = scene.GetManifest().LoadFromString(fallbackLogicJson, m_serializeContext.get(), m_jsonRegistrationContext.get());
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_FALSE(scene.GetManifest().IsEmpty());
|
||||
ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1);
|
||||
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(scene.GetManifest().GetValueStorage());
|
||||
EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::FailBuild);
|
||||
}
|
||||
|
||||
TEST_F(SceneManifest_JSON, ScriptProcessorRule_ContinueBuildFallbackLogic_Works)
|
||||
{
|
||||
using namespace AZ::SceneAPI;
|
||||
|
||||
constexpr const char* fallbackLogicJson = { R"JSON(
|
||||
{
|
||||
"values": [
|
||||
{
|
||||
"$type": "ScriptProcessorRule",
|
||||
"scriptFilename": "foo.py",
|
||||
"fallbackLogic": "ContinueBuild"
|
||||
}
|
||||
]
|
||||
})JSON" };
|
||||
|
||||
auto scene = Containers::Scene("mock");
|
||||
auto result = scene.GetManifest().LoadFromString(fallbackLogicJson, m_serializeContext.get(), m_jsonRegistrationContext.get());
|
||||
EXPECT_TRUE(result.IsSuccess());
|
||||
EXPECT_FALSE(scene.GetManifest().IsEmpty());
|
||||
ASSERT_EQ(scene.GetManifest().GetEntryCount(), 1);
|
||||
|
||||
auto view = Containers::MakeDerivedFilterView<DataTypes::IScriptProcessorRule>(scene.GetManifest().GetValueStorage());
|
||||
EXPECT_EQ(view.begin()->GetScriptProcessorFallbackLogic(), DataTypes::ScriptProcessorFallbackLogic::ContinueBuild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,10 @@ namespace AZ::Render
|
||||
// Render aabb
|
||||
if (renderFlags[EMotionFX::ActorRenderFlag::RENDER_AABB])
|
||||
{
|
||||
RenderAABB(instance, renderActorSettings.m_staticAABBColor);
|
||||
RenderAABB(instance,
|
||||
renderActorSettings.m_enabledNodeBasedAabb, renderActorSettings.m_nodeAABBColor,
|
||||
renderActorSettings.m_enabledMeshBasedAabb, renderActorSettings.m_meshAABBColor,
|
||||
renderActorSettings.m_enabledStaticBasedAabb, renderActorSettings.m_staticAABBColor);
|
||||
}
|
||||
|
||||
// Render simple line skeleton
|
||||
@@ -201,11 +204,46 @@ namespace AZ::Render
|
||||
return AzFramework::DebugDisplayRequestBus::FindFirstHandler(debugDisplayBus);
|
||||
}
|
||||
|
||||
void AtomActorDebugDraw::RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor)
|
||||
void AtomActorDebugDraw::RenderAABB(EMotionFX::ActorInstance* instance,
|
||||
bool enableNodeAabb,
|
||||
const AZ::Color& nodeAabbColor,
|
||||
bool enableMeshAabb,
|
||||
const AZ::Color& meshAabbColor,
|
||||
bool enableStaticAabb,
|
||||
const AZ::Color& staticAabbColor)
|
||||
{
|
||||
RPI::AuxGeomDrawPtr auxGeom = m_auxGeomFeatureProcessor->GetDrawQueue();
|
||||
const AZ::Aabb& aabb = instance->GetAabb();
|
||||
auxGeom->DrawAabb(aabb, aabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
||||
|
||||
if (enableNodeAabb)
|
||||
{
|
||||
AZ::Aabb aabb;
|
||||
instance->CalcNodeBasedAabb(&aabb);
|
||||
if (aabb.IsValid())
|
||||
{
|
||||
auxGeom->DrawAabb(aabb, nodeAabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
||||
}
|
||||
}
|
||||
|
||||
if (enableMeshAabb)
|
||||
{
|
||||
AZ::Aabb aabb;
|
||||
const size_t lodLevel = instance->GetLODLevel();
|
||||
instance->CalcMeshBasedAabb(lodLevel, &aabb);
|
||||
if (aabb.IsValid())
|
||||
{
|
||||
auxGeom->DrawAabb(aabb, meshAabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
||||
}
|
||||
}
|
||||
|
||||
if (enableStaticAabb)
|
||||
{
|
||||
AZ::Aabb aabb;
|
||||
instance->CalcStaticBasedAabb(&aabb);
|
||||
if (aabb.IsValid())
|
||||
{
|
||||
auxGeom->DrawAabb(aabb, staticAabbColor, RPI::AuxGeomDraw::DrawStyle::Line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AtomActorDebugDraw::RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor)
|
||||
|
||||
@@ -49,7 +49,13 @@ namespace AZ::Render
|
||||
void PrepareForMesh(EMotionFX::Mesh* mesh, const AZ::Transform& worldTM);
|
||||
AzFramework::DebugDisplayRequests* GetDebugDisplay(AzFramework::ViewportId viewportId);
|
||||
|
||||
void RenderAABB(EMotionFX::ActorInstance* instance, const AZ::Color& aabbColor);
|
||||
void RenderAABB(EMotionFX::ActorInstance* instance,
|
||||
bool enableNodeAabb,
|
||||
const AZ::Color& nodeAabbColor,
|
||||
bool enableMeshAabb,
|
||||
const AZ::Color& meshAabbColor,
|
||||
bool enableStaticAabb,
|
||||
const AZ::Color& staticAabbColor);
|
||||
void RenderLineSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor);
|
||||
void RenderSkeleton(EMotionFX::ActorInstance* instance, const AZ::Color& skeletonColor);
|
||||
void RenderEMFXDebugDraw(EMotionFX::ActorInstance* instance);
|
||||
|
||||
+2
@@ -1071,6 +1071,8 @@ namespace EMStudio
|
||||
settings.m_mirroredBitangentsColor = m_mirroredBitangentsColor;
|
||||
settings.m_bitangentsColor = m_bitangentsColor;
|
||||
settings.m_wireframeColor = m_wireframeColor;
|
||||
settings.m_nodeAABBColor = m_nodeAABBColor;
|
||||
settings.m_meshAABBColor = m_meshAABBColor;
|
||||
settings.m_staticAABBColor = m_staticAABBColor;
|
||||
settings.m_skeletonColor = m_skeletonColor;
|
||||
settings.m_lineSkeletonColor = m_lineSkeletonColor;
|
||||
|
||||
@@ -28,6 +28,10 @@ namespace AZ::Render
|
||||
float m_wireframeScale = 1.0f;
|
||||
float m_nodeOrientationScale = 1.0f;
|
||||
|
||||
bool m_enabledNodeBasedAabb = true;
|
||||
bool m_enabledMeshBasedAabb = true;
|
||||
bool m_enabledStaticBasedAabb = true;
|
||||
|
||||
AZ::Color m_hitDetectionColliderColor{0.44f, 0.44f, 0.44f, 1.0f};
|
||||
AZ::Color m_selectedHitDetectionColliderColor{ 0.3f, 0.56f, 0.88f, 1.0f };
|
||||
AZ::Color m_ragdollColliderColor{ 0.44f, 0.44f, 0.44f, 1.0f };
|
||||
@@ -44,9 +48,12 @@ namespace AZ::Render
|
||||
AZ::Color m_mirroredBitangentsColor{ 1.0f, 1.0f, 0.0f, 1.0f };
|
||||
AZ::Color m_bitangentsColor{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
AZ::Color m_wireframeColor{ 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
AZ::Color m_staticAABBColor{ 0.0f, 0.7f, 0.7f, 1.0f };
|
||||
AZ::Color m_lineSkeletonColor{ 0.33333f, 1.0f, 0.0f, 1.0f };
|
||||
AZ::Color m_skeletonColor{ 0.19f, 0.58f, 0.19f, 1.0f };
|
||||
AZ::Color m_jointNameColor{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
AZ::Color m_nodeAABBColor{ 1.0f, 0.0f, 0.0f, 1.0f };
|
||||
AZ::Color m_meshAABBColor{ 0.0f, 0.0f, 0.7f, 1.0f };
|
||||
AZ::Color m_staticAABBColor{ 0.0f, 0.7f, 0.7f, 1.0f };
|
||||
};
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -50,6 +50,7 @@ public: // types
|
||||
{
|
||||
AZ::Vector3 color = AZ::Vector3(1.0f, 1.0f, 1.0f);
|
||||
Rounding pixelRounding = Rounding::Nearest;
|
||||
bool m_clamp = false;
|
||||
RenderState m_renderState;
|
||||
};
|
||||
|
||||
@@ -145,6 +146,7 @@ public: // member functions
|
||||
virtual void DrawQuad(AZ::Data::Instance<AZ::RPI::Image> image,
|
||||
VertexPosColUV* verts,
|
||||
Rounding pixelRounding = Rounding::Nearest,
|
||||
bool clamp = false,
|
||||
const RenderState& renderState = RenderState{});
|
||||
|
||||
//! Draw a line
|
||||
@@ -257,6 +259,8 @@ protected: // types and constants
|
||||
{
|
||||
AZ::RHI::ShaderInputImageIndex m_imageInputIndex;
|
||||
AZ::RHI::ShaderInputConstantIndex m_viewProjInputIndex;
|
||||
AZ::RPI::ShaderVariantId m_shaderOptionsClamp;
|
||||
AZ::RPI::ShaderVariantId m_shaderOptionsWrap;
|
||||
};
|
||||
|
||||
class DeferredPrimitive
|
||||
@@ -281,6 +285,7 @@ protected: // types and constants
|
||||
AZ::Vector2 m_texCoords[4];
|
||||
uint32 m_packedColors[4];
|
||||
AZ::Data::Instance<AZ::RPI::Image> m_image;
|
||||
bool m_clamp;
|
||||
RenderState m_renderState;
|
||||
};
|
||||
|
||||
@@ -455,11 +460,12 @@ public: // member functions
|
||||
//! See IDraw2d:DrawQuad for parameter descriptions
|
||||
void DrawQuad(AZ::Data::Instance<AZ::RPI::Image> image, CDraw2d::VertexPosColUV* verts,
|
||||
IDraw2d::Rounding pixelRounding = IDraw2d::Rounding::Nearest,
|
||||
bool clamp = false,
|
||||
const CDraw2d::RenderState& renderState = CDraw2d::RenderState{})
|
||||
{
|
||||
if (m_draw2d)
|
||||
{
|
||||
m_draw2d->DrawQuad(image, verts, pixelRounding, renderState);
|
||||
m_draw2d->DrawQuad(image, verts, pixelRounding, clamp, renderState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,6 +551,9 @@ public: // member functions
|
||||
//! Set the base state (that blend mode etc is combined with) used for images, default is GS_NODEPTHTEST.
|
||||
void SetImageDepthState(const AZ::RHI::DepthState& depthState) { m_imageOptions.m_renderState.m_depthState = depthState; }
|
||||
|
||||
//! Set image clamp mode
|
||||
void SetImageClamp(bool clamp) { m_imageOptions.m_clamp = clamp; }
|
||||
|
||||
//! Set the text font.
|
||||
void SetTextFont(AZStd::string_view fontName) { m_textOptions.fontName = fontName; }
|
||||
|
||||
|
||||
@@ -103,10 +103,7 @@ void CDraw2d::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene)
|
||||
LyShinePassRequestBus::EventResult(uiCanvasPass, sceneId, &LyShinePassRequestBus::Events::GetUiCanvasPass);
|
||||
|
||||
m_dynamicDraw = AZ::RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext();
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false")));
|
||||
m_dynamicDraw->InitShaderWithVariant(shader, &shaderOptions);
|
||||
m_dynamicDraw->InitShader(shader);
|
||||
m_dynamicDraw->InitVertexFormat(
|
||||
{ {"POSITION", AZ::RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", AZ::RHI::Format::B8G8R8A8_UNORM},
|
||||
@@ -136,6 +133,16 @@ void CDraw2d::OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene)
|
||||
m_shaderData.m_viewProjInputIndex = layout->FindShaderInputConstantIndex(AZ::Name(worldToProjIndexName));
|
||||
AZ_Error("Draw2d", m_shaderData.m_viewProjInputIndex.IsValid(), "Failed to find shader input constant %s.",
|
||||
worldToProjIndexName);
|
||||
|
||||
// Cache shader variants that will be used
|
||||
AZ::RPI::ShaderOptionList shaderOptionsClamp;
|
||||
shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true")));
|
||||
shaderOptionsClamp.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true")));
|
||||
m_shaderData.m_shaderOptionsClamp = m_dynamicDraw->UseShaderVariant(shaderOptionsClamp);
|
||||
AZ::RPI::ShaderOptionList shaderOptionsWrap;
|
||||
shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("false")));
|
||||
shaderOptionsWrap.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("true")));
|
||||
m_shaderData.m_shaderOptionsWrap = m_dynamicDraw->UseShaderVariant(shaderOptionsWrap);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -181,6 +188,8 @@ void CDraw2d::DrawImage(AZ::Data::Instance<AZ::RPI::Image> image, AZ::Vector2 po
|
||||
|
||||
quad.m_image = image;
|
||||
|
||||
quad.m_clamp = actualImageOptions->m_clamp;
|
||||
|
||||
// add the blendMode flags to the base state
|
||||
quad.m_renderState = actualImageOptions->m_renderState;
|
||||
|
||||
@@ -206,7 +215,7 @@ void CDraw2d::DrawImageAligned(AZ::Data::Instance<AZ::RPI::Image> image, AZ::Vec
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CDraw2d::DrawQuad(AZ::Data::Instance<AZ::RPI::Image> image, VertexPosColUV* verts, Rounding pixelRounding,
|
||||
const CDraw2d::RenderState& renderState)
|
||||
bool clamp, const CDraw2d::RenderState& renderState)
|
||||
{
|
||||
// define quad
|
||||
DeferredQuad quad;
|
||||
@@ -217,6 +226,7 @@ void CDraw2d::DrawQuad(AZ::Data::Instance<AZ::RPI::Image> image, VertexPosColUV*
|
||||
quad.m_packedColors[i] = PackARGB8888(verts[i].color);
|
||||
}
|
||||
quad.m_image = image;
|
||||
quad.m_clamp = clamp;
|
||||
|
||||
// add the blendMode flags to the base state
|
||||
quad.m_renderState = renderState;
|
||||
@@ -766,6 +776,8 @@ void CDraw2d::DeferredQuad::Draw(AZ::RHI::Ptr<AZ::RPI::DynamicDrawContext> dynam
|
||||
vertices[i].st = Vec2(m_texCoords[j].GetX(), m_texCoords[j].GetY());
|
||||
}
|
||||
|
||||
dynamicDraw->SetShaderVariant(m_clamp ? shaderData.m_shaderOptionsClamp : shaderData.m_shaderOptionsWrap);
|
||||
|
||||
// Set up per draw SRG
|
||||
AZ::Data::Instance<AZ::RPI::ShaderResourceGroup> drawSrg = dynamicDraw->NewDrawSrg();
|
||||
|
||||
|
||||
@@ -668,7 +668,7 @@ void CLyShine::LoadUiCursor()
|
||||
{
|
||||
if (!m_cursorImagePathToLoad.empty())
|
||||
{
|
||||
m_uiCursorTexture = CDraw2d::LoadTexture(m_cursorImagePathToLoad); // LYSHINE_ATOM_TODO - add clamp option to draw2d and set cursor to clamp
|
||||
m_uiCursorTexture = CDraw2d::LoadTexture(m_cursorImagePathToLoad);
|
||||
m_cursorImagePathToLoad.clear();
|
||||
}
|
||||
}
|
||||
@@ -691,7 +691,13 @@ void CLyShine::RenderUiCursor()
|
||||
AZ::RHI::Size cursorSize = m_uiCursorTexture->GetDescriptor().m_size;
|
||||
const AZ::Vector2 dimensions(aznumeric_cast<float>(cursorSize.m_width), aznumeric_cast<float>(cursorSize.m_height));
|
||||
|
||||
m_draw2d->DrawImage(m_uiCursorTexture, position, dimensions);
|
||||
CDraw2d::ImageOptions imageOptions;
|
||||
imageOptions.m_clamp = true;
|
||||
const float opacity = 1.0f;
|
||||
const float rotation = 0.0f;
|
||||
const AZ::Vector2* pivotPoint = nullptr;
|
||||
const AZ::Vector2* minMaxTexCoords = nullptr;
|
||||
m_draw2d->DrawImage(m_uiCursorTexture, position, dimensions, opacity, rotation, pivotPoint, minMaxTexCoords, &imageOptions);
|
||||
}
|
||||
|
||||
#ifndef _RELEASE
|
||||
|
||||
@@ -265,11 +265,13 @@ namespace ScriptCanvasEditor
|
||||
|
||||
action = entityMenu->addAction(QString("%1").arg(QString(displayName.c_str())));
|
||||
|
||||
QObject::connect(action, &QAction::triggered, [assetId]
|
||||
QObject::connect(action, &QAction::triggered, [assetInfo]
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
SourceHandle sourceHandle(nullptr, assetInfo.m_assetId.m_guid, "");
|
||||
CompleteDescriptionInPlace(sourceHandle);
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset
|
||||
, SourceHandle(nullptr, assetId.m_guid, "")
|
||||
, sourceHandle
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1139,7 +1139,7 @@ namespace ScriptCanvasEditor
|
||||
auto loadedGraphOutcome = LoadFromFile(fileAssetId.Path().c_str());
|
||||
if (!loadedGraphOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Failed to load graph at %s", fileAssetId.Path().c_str()));
|
||||
return AZ::Failure(AZStd::string::format("Failed to load graph at %s", fileAssetId.Path().c_str()));
|
||||
}
|
||||
|
||||
auto loadedGraph = loadedGraphOutcome.TakeValue();
|
||||
|
||||
@@ -139,8 +139,8 @@ namespace Terrain
|
||||
|
||||
AZ::Outcome<void, AZStd::string> TerrainWorldConfig::DetermineMessage(float numSamples)
|
||||
{
|
||||
const float maximumSamplesAllowed = 8.0f * 1024.0f * 1024.0f;
|
||||
if (numSamples < maximumSamplesAllowed)
|
||||
const float maximumSamplesAllowed = 16.0f * 1024.0f * 1024.0f;
|
||||
if (numSamples <= maximumSamplesAllowed)
|
||||
{
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
@@ -339,17 +339,17 @@ namespace Terrain
|
||||
AZ::Aabb region = sector.m_aabb;
|
||||
region.SetMax(region.GetMax() + AZ::Vector3(gridResolution.GetX(), gridResolution.GetY(), 0.0f));
|
||||
|
||||
// We need 4 vertices for each grid point in our sector to hold the _| shape.
|
||||
const size_t numSamplesX = aznumeric_cast<size_t>(ceil(region.GetExtents().GetX() / gridResolution.GetX()));
|
||||
const size_t numSamplesY = aznumeric_cast<size_t>(ceil(region.GetExtents().GetY() / gridResolution.GetY()));
|
||||
sector.m_lineVertices.clear();
|
||||
sector.m_lineVertices.reserve(numSamplesX * numSamplesY * 4);
|
||||
|
||||
// This keeps track of the height from the previous point for the _ line.
|
||||
float previousHeight = 0.0f;
|
||||
|
||||
// This keeps track of the heights from the previous row for the | line.
|
||||
AZStd::vector<float> rowHeights(aznumeric_cast<size_t>(ceil(region.GetExtents().GetX() / gridResolution.GetX())));
|
||||
|
||||
// We need 4 vertices for each grid point in our sector to hold the _| shape.
|
||||
const uint32_t numSamplesX = static_cast<uint32_t>((region.GetMax().GetX() - region.GetMin().GetX()) / gridResolution.GetX());
|
||||
const uint32_t numSamplesY = static_cast<uint32_t>((region.GetMax().GetY() - region.GetMin().GetY()) / gridResolution.GetY());
|
||||
sector.m_lineVertices.clear();
|
||||
sector.m_lineVertices.reserve(numSamplesX * numSamplesY * 4);
|
||||
AZStd::vector<float> rowHeights(numSamplesX);
|
||||
|
||||
// For each terrain height value in the region, create the _| grid lines for that point and cache off the height value
|
||||
// for use with subsequent grid line calculations.
|
||||
@@ -376,21 +376,21 @@ namespace Terrain
|
||||
};
|
||||
|
||||
// This set of nested loops will get replaced with a call to ProcessHeightsFromRegion once the API exists.
|
||||
uint32_t yIndex = 0;
|
||||
for (float y = region.GetMin().GetY(); y < region.GetMax().GetY(); y += gridResolution.GetY())
|
||||
for (size_t yIndex = 0; yIndex < numSamplesY; yIndex++)
|
||||
{
|
||||
uint32_t xIndex = 0;
|
||||
for (float x = region.GetMin().GetX(); x < region.GetMax().GetX(); x += gridResolution.GetX())
|
||||
float y = region.GetMin().GetY() + (gridResolution.GetY() * yIndex);
|
||||
for (size_t xIndex = 0; xIndex < numSamplesX; xIndex++)
|
||||
{
|
||||
float x = region.GetMin().GetX() + (gridResolution.GetX() * xIndex);
|
||||
|
||||
float height = worldMinZ;
|
||||
bool terrainExists = false;
|
||||
AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult(
|
||||
height, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y,
|
||||
AzFramework::Terrain::TerrainDataRequests::Sampler::EXACT, &terrainExists);
|
||||
ProcessHeightValue(xIndex, yIndex, AZ::Vector3(x, y, height), terrainExists);
|
||||
xIndex++;
|
||||
ProcessHeightValue(
|
||||
aznumeric_cast<uint32_t>(xIndex), aznumeric_cast<uint32_t>(yIndex), AZ::Vector3(x, y, height), terrainExists);
|
||||
}
|
||||
yIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,16 +41,6 @@
|
||||
"CMAKE_BUILD_ARGS":"-j!NUMBER_OF_PROCESSORS!"
|
||||
}
|
||||
},
|
||||
"android_packaging_all": {
|
||||
"TAGS": [
|
||||
"packaging"
|
||||
],
|
||||
"COMMAND": "../Windows/python_windows.cmd",
|
||||
"PARAMETERS": {
|
||||
"SCRIPT_PATH": "scripts/build/package/package.py",
|
||||
"SCRIPT_PARAMETERS": "--platform Android --type all"
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"TAGS":[
|
||||
"weekly-build-metrics",
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
"daily-pipeline-metrics": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"packaging": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"nightly-clean": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
"daily-pipeline-metrics": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"packaging": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"nightly-clean": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
}
|
||||
|
||||
@@ -153,16 +153,6 @@
|
||||
"CMAKE_TARGET": "ALL_BUILD"
|
||||
}
|
||||
},
|
||||
"mac_packaging_all": {
|
||||
"TAGS": [
|
||||
"packaging"
|
||||
],
|
||||
"COMMAND": "python_mac.sh",
|
||||
"PARAMETERS": {
|
||||
"SCRIPT_PATH": "scripts/build/package/package.py",
|
||||
"SCRIPT_PARAMETERS": "--platform Mac --type all"
|
||||
}
|
||||
},
|
||||
"install_profile": {
|
||||
"TAGS": [],
|
||||
"COMMAND": "build_mac.sh",
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
"daily-pipeline-metrics": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"packaging": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"nightly-clean": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
}
|
||||
|
||||
@@ -59,26 +59,6 @@
|
||||
"SCRIPT_PARAMETERS": "--platform=Windows --repository=%REPOSITORY_NAME% --jobname=%JOB_NAME% --jobnumber=%BUILD_NUMBER% --jobnode=%NODE_LABEL% --changelist=%CHANGE_ID%"
|
||||
}
|
||||
},
|
||||
"windows_packaging_all": {
|
||||
"TAGS": [
|
||||
"packaging"
|
||||
],
|
||||
"COMMAND": "python_windows.cmd",
|
||||
"PARAMETERS": {
|
||||
"SCRIPT_PATH": "scripts/build/package/package.py",
|
||||
"SCRIPT_PARAMETERS": "--platform Windows --type all"
|
||||
}
|
||||
},
|
||||
"3rdParty_all": {
|
||||
"TAGS": [
|
||||
"packaging"
|
||||
],
|
||||
"COMMAND": "python_windows.cmd",
|
||||
"PARAMETERS": {
|
||||
"SCRIPT_PATH": "scripts/build/package/package.py",
|
||||
"SCRIPT_PARAMETERS": "--platform 3rdParty --type 3rdParty_all"
|
||||
}
|
||||
},
|
||||
"test_impact_analysis_profile": {
|
||||
"TAGS": [
|
||||
],
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
"daily-pipeline-metrics": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"packaging": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"nightly-clean": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
}
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
"daily-pipeline-metrics": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"packaging": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
},
|
||||
"nightly-clean": {
|
||||
"CLEAN_WORKSPACE": true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user