Merge branch 'main' into Atom/jromnoa/SPEC-6849-intermittent-test-failure-fix
This commit is contained in:
@@ -115,7 +115,6 @@
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||
*.webm filter=lfs diff=lfs merge=lfs -text
|
||||
*.wem filter=lfs diff=lfs merge=lfs -text
|
||||
*.wxs filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbscene filter=lfs diff=lfs merge=lfs -text
|
||||
*.spp filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::BlastTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL TRUE
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT Blast
|
||||
)
|
||||
endif()
|
||||
@@ -15,406 +15,46 @@
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
|
||||
## Asset pipeline ##
|
||||
add_subdirectory(assetpipeline)
|
||||
|
||||
## Atom Renderer ##
|
||||
add_subdirectory(atom_renderer)
|
||||
|
||||
## Physics ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Main
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Periodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Periodic.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(physics)
|
||||
|
||||
## ScriptCanvas ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::ScriptCanvasTests
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
ScriptCanvas
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::ScriptCanvasTests_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(scripting)
|
||||
|
||||
## White Box ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::WhiteBoxTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
WhiteBox
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(WhiteBox)
|
||||
|
||||
## NvCloth ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::NvClothTests_Main
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
NvCloth
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(NvCloth)
|
||||
|
||||
## Prefab ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PrefabTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(prefab)
|
||||
|
||||
## Editor Python Bindings ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorPythonBindings
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Gem::EditorPythonBindings.Editor
|
||||
COMPONENT TestTools
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(EditorPythonBindings)
|
||||
|
||||
## Python Asset Builder ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PythonAssetBuilder
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Gem::EditorPythonBindings.Editor
|
||||
Gem::PythonAssetBuilder.Editor
|
||||
COMPONENT TestTools
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(PythonAssetBuilder)
|
||||
|
||||
## Blast ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::BlastTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL TRUE
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT Blast
|
||||
)
|
||||
endif()
|
||||
|
||||
#############
|
||||
add_subdirectory(Blast)
|
||||
|
||||
## Large Worlds ##
|
||||
|
||||
include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_LARGE_WORLDS_TEST_SUPPORTED)
|
||||
|
||||
## DynVeg ##
|
||||
# Temporarily moving all tests to periodic suite - SPEC-6553
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::DynamicVegetationTests_Main
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE main
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
# PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
# TIMEOUT 1500
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# Legacy::Editor
|
||||
# AutomatedTesting.GameLauncher
|
||||
# AutomatedTesting.Assets
|
||||
# COMPONENT
|
||||
# LargeWorlds
|
||||
#)
|
||||
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Sandbox
|
||||
TEST_SERIAL
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationFilterTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_filter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationModifierTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_modifier"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationRegressionTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_regression"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationAreaTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_area"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationMiscTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_misc"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationSurfaceTagTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
## LandscapeCanvas ##
|
||||
# Temporarily moving all tests to periodic suite - SPEC-6553
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::LandscapeCanvasTests_Main
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE main
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
|
||||
# PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
# TIMEOUT 1500
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# Legacy::Editor
|
||||
# AutomatedTesting.Assets
|
||||
# COMPONENT
|
||||
# LargeWorlds
|
||||
#)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
## GradientSignal ##
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::GradientSignalTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
endif()
|
||||
add_subdirectory(largeworlds)
|
||||
|
||||
## Editor ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Periodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/editor
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
endif()
|
||||
add_subdirectory(editor)
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
# Unstable, SPEC-3838 will restore
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::asset_load_benchmark_test
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE benchmark
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/streaming/benchmark/asset_load_benchmark_test.py
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# AZ::AssetProcessorBatch
|
||||
# AutomatedTesting.GameLauncher
|
||||
#)
|
||||
endif()
|
||||
## Streaming ##
|
||||
add_subdirectory(streaming)
|
||||
|
||||
## Smoke ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::SmokeTest
|
||||
TEST_SUITE smoke
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/smoke
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Smoke
|
||||
)
|
||||
endif()
|
||||
## Streaming ##
|
||||
add_subdirectory(smoke)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorPythonBindings
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Gem::EditorPythonBindings.Editor
|
||||
COMPONENT TestTools
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::NvClothTests_Main
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
NvCloth
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PythonAssetBuilder
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Gem::EditorPythonBindings.Editor
|
||||
Gem::PythonAssetBuilder.Editor
|
||||
COMPONENT TestTools
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::WhiteBoxTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
WhiteBox
|
||||
)
|
||||
endif()
|
||||
@@ -13,8 +13,6 @@ add_subdirectory(asset_processor_tests)
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
## AP Python Tests ##
|
||||
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AuxiliaryContent
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/auxiliary_content_tests/auxiliary_content_tests.py
|
||||
@@ -22,7 +20,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
)
|
||||
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.BankInfoParser
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/wwise_bank_dependency_tests/bank_info_parser_tests.py
|
||||
@@ -33,4 +30,3 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -141,4 +141,3 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
# )
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::EditorTests_Periodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,186 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_LARGE_WORLDS_TEST_SUPPORTED)
|
||||
|
||||
## DynVeg ##
|
||||
|
||||
# Temporarily moving all tests to periodic suite - SPEC-6553
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::DynamicVegetationTests_Main
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE main
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
# PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
# TIMEOUT 1500
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# Legacy::Editor
|
||||
# AutomatedTesting.GameLauncher
|
||||
# AutomatedTesting.Assets
|
||||
# COMPONENT
|
||||
# LargeWorlds
|
||||
#)
|
||||
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationTests_Sandbox
|
||||
TEST_SERIAL
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationFilterTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_filter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationModifierTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_modifier"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationRegressionTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_regression"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationAreaTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_area"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationMiscTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_misc"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::DynamicVegetationSurfaceTagTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
## LandscapeCanvas ##
|
||||
# Temporarily moving all tests to periodic suite - SPEC-6553
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::LandscapeCanvasTests_Main
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE main
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
|
||||
# PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
# TIMEOUT 1500
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# Legacy::Editor
|
||||
# AutomatedTesting.Assets
|
||||
# COMPONENT
|
||||
# LargeWorlds
|
||||
#)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
## GradientSignal ##
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::GradientSignalTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
endif()
|
||||
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Main
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Periodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
## Prefab ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PrefabTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::ScriptCanvasTests_Perodic
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
ScriptCanvas
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::ScriptCanvasTests_Sandbox
|
||||
TEST_SUITE sandbox
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::SmokeTest
|
||||
TEST_SUITE smoke
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Smoke
|
||||
)
|
||||
endif()
|
||||
@@ -20,6 +20,7 @@ import subprocess
|
||||
|
||||
@pytest.mark.SUITE_smoke
|
||||
class TestCLIToolAssetBuilderWorks(object):
|
||||
@pytest.mark.xfail(reason="Ignoring failure temporarily - SPEC-6905")
|
||||
def test_CLITool_AssetBuilder_Works(self, build_directory):
|
||||
file_path = os.path.join(build_directory, "AssetBuilder")
|
||||
help_message = "AssetBuilder is part of the Asset Processor"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
# Unstable, SPEC-3838 will restore
|
||||
#ly_add_pytest(
|
||||
# NAME AutomatedTesting::asset_load_benchmark_test
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE benchmark
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/benchmark/asset_load_benchmark_test.py
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# AZ::AssetProcessorBatch
|
||||
# AutomatedTesting.GameLauncher
|
||||
#)
|
||||
endif()
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
#pragma once
|
||||
|
||||
// Dynamic replacement for static 2d array
|
||||
template <class T>
|
||||
struct Array2d
|
||||
{
|
||||
Array2d()
|
||||
{
|
||||
m_nSize = 0;
|
||||
m_pData = 0;
|
||||
}
|
||||
|
||||
int GetSize() const { return m_nSize; }
|
||||
int GetDataSize() const { return m_nSize * m_nSize * sizeof(T); }
|
||||
|
||||
T* GetData() { return m_pData; }
|
||||
|
||||
T* GetDataEnd() { return &m_pData[m_nSize * m_nSize]; }
|
||||
|
||||
void SetData(T* pData, int nSize)
|
||||
{
|
||||
Allocate(nSize);
|
||||
memcpy(m_pData, pData, nSize * nSize * sizeof(T));
|
||||
}
|
||||
|
||||
void Allocate(int nSize)
|
||||
{
|
||||
if (m_nSize == nSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delete [] m_pData;
|
||||
|
||||
m_nSize = nSize;
|
||||
m_pData = new T [nSize * nSize];
|
||||
memset(m_pData, 0, nSize * nSize * sizeof(T));
|
||||
}
|
||||
|
||||
~Array2d()
|
||||
{
|
||||
delete [] m_pData;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
delete [] m_pData;
|
||||
m_pData = 0;
|
||||
m_nSize = 0;
|
||||
}
|
||||
|
||||
T* m_pData;
|
||||
int m_nSize;
|
||||
|
||||
T* operator [] (const int& nPos) const
|
||||
{
|
||||
assert(nPos >= 0 && nPos < m_nSize);
|
||||
return &m_pData[nPos * m_nSize];
|
||||
}
|
||||
|
||||
Array2d& operator = (const Array2d& other)
|
||||
{
|
||||
Allocate(other.m_nSize);
|
||||
memcpy(m_pData, other.m_pData, m_nSize * m_nSize * sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ARRAY2D_H
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
// Description: Utilities and functions used when cryphysics is disabled
|
||||
|
||||
#pragma once
|
||||
|
||||
// Assert if CryPhysics is disabled and no functionality replacement has been implemented
|
||||
// 1: Runtime AZ_Error
|
||||
// 2: Runtime Assertion
|
||||
// 3: Compilation error
|
||||
// Other: Do nothing
|
||||
#define ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT 0
|
||||
|
||||
#if (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 1)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Error("CryPhysics", false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 2)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Assert(false, "CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 3)
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT() static_assert(false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED")
|
||||
#else
|
||||
#define CRY_PHYSICS_REPLACEMENT_ASSERT()
|
||||
#endif
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
#pragma once
|
||||
|
||||
#include "CryArray.h"
|
||||
#include "CrySizer.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, class P = T*>
|
||||
struct PtrArray
|
||||
: DynArray<P>
|
||||
{
|
||||
typedef DynArray<P> super;
|
||||
|
||||
// Overrides.
|
||||
typedef T value_type;
|
||||
|
||||
ILINE ~PtrArray(){}
|
||||
|
||||
inline T& operator [](int i) const
|
||||
{ return *super::operator[](i); }
|
||||
|
||||
// Iterators.
|
||||
struct iterator
|
||||
{
|
||||
iterator(P* p)
|
||||
: _ptr(p)
|
||||
{}
|
||||
|
||||
operator P* () const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
void operator++()
|
||||
{ _ptr++; }
|
||||
void operator--()
|
||||
{ _ptr--; }
|
||||
T& operator*() const
|
||||
{ assert(_ptr); return **_ptr; }
|
||||
T* operator->() const
|
||||
{ assert(_ptr); return *_ptr; }
|
||||
|
||||
protected:
|
||||
P* _ptr;
|
||||
};
|
||||
|
||||
struct const_iterator
|
||||
{
|
||||
const_iterator(const P* p)
|
||||
: _ptr(p)
|
||||
{}
|
||||
|
||||
operator const P* () const
|
||||
{
|
||||
return _ptr;
|
||||
}
|
||||
void operator++()
|
||||
{ _ptr++; }
|
||||
void operator--()
|
||||
{ _ptr--; }
|
||||
T& operator*() const
|
||||
{ assert(_ptr); return **_ptr; }
|
||||
T* operator->() const
|
||||
{ assert(_ptr); return *_ptr; }
|
||||
|
||||
protected:
|
||||
const P* _ptr;
|
||||
};
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(this->begin(), this->get_alloc_size());
|
||||
for (int i = 0; i < this->size(); ++i)
|
||||
{
|
||||
pSizer->AddObject(this->super::operator [](i));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
struct SmartPtrArray
|
||||
: PtrArray< T, _smart_ptr<T> >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <Cry_Vector3.h>
|
||||
#include <Cry_Quat.h>
|
||||
#include <Cry_Color.h>
|
||||
#include <CryArray2d.h>
|
||||
#include <smartptr.h>
|
||||
|
||||
// forward declarations for overloads
|
||||
@@ -249,12 +248,6 @@ public:
|
||||
void AddObject([[maybe_unused]] const AZ::Vector3& rObj) {}
|
||||
void AddObject(void*) {}
|
||||
|
||||
template<typename T>
|
||||
void AddObject(const Array2d<T>& array2d)
|
||||
{
|
||||
this->AddObject(array2d.m_pData, array2d.GetDataSize());
|
||||
}
|
||||
|
||||
// overloads for container, will automaticly traverse the content
|
||||
template<typename T, typename Alloc>
|
||||
void AddObject(const std::list<T, Alloc>& rList)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include this file instead of including zlib.h directly
|
||||
// because zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those
|
||||
// definitions conflict with CryEngine's definitions.
|
||||
|
||||
#if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32)
|
||||
# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS)
|
||||
# define CRY_TMP_DEFINED_WINDOWS 1
|
||||
#endif
|
||||
#if defined(WIN32)
|
||||
# define CRY_TMP_DEFINED_WIN32 1
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#if !defined(CRY_TMP_DEFINED_WINDOWS)
|
||||
# undef WINDOWS
|
||||
#endif
|
||||
#undef CRY_TMP_DEFINED_WINDOWS
|
||||
#if !defined(CRY_TMP_DEFINED_WIN32)
|
||||
# undef WIN32
|
||||
#endif
|
||||
#undef CRY_TMP_DEFINED_WIN32
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,469 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Facility for efficiently generating random positions on geometry
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Cry_Geo.h"
|
||||
#include "CryArray.h"
|
||||
#include "Random.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Extents cache
|
||||
|
||||
class CGeomExtent
|
||||
{
|
||||
public:
|
||||
|
||||
CGeomExtent()
|
||||
: m_nEmptyEndParts(0) {}
|
||||
|
||||
ILINE operator bool() const
|
||||
{
|
||||
return m_afCumExtents.capacity() + m_nEmptyEndParts != 0;
|
||||
}
|
||||
ILINE int NumParts() const
|
||||
{
|
||||
return m_afCumExtents.size();
|
||||
}
|
||||
ILINE float TotalExtent() const
|
||||
{
|
||||
return !m_afCumExtents.empty() ? m_afCumExtents.back() : 0.f;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_afCumExtents.clear();
|
||||
m_nEmptyEndParts = 0;
|
||||
}
|
||||
void AddPart(float fExtent)
|
||||
{
|
||||
// Defer empty parts until a non-empty part is added.
|
||||
if (fExtent <= 0.f)
|
||||
{
|
||||
m_nEmptyEndParts++;
|
||||
}
|
||||
else
|
||||
{
|
||||
float fTotal = TotalExtent();
|
||||
for (; m_nEmptyEndParts; m_nEmptyEndParts--)
|
||||
{
|
||||
m_afCumExtents.push_back(fTotal);
|
||||
}
|
||||
m_afCumExtents.push_back(fTotal + fExtent);
|
||||
}
|
||||
}
|
||||
void ReserveParts(int nCount)
|
||||
{
|
||||
m_afCumExtents.reserve(nCount);
|
||||
}
|
||||
|
||||
// Find element in sorted array <= index (normalized 0 to 1)
|
||||
int GetPart(float fIndex) const
|
||||
{
|
||||
int last = m_afCumExtents.size() - 1;
|
||||
if (last <= 0)
|
||||
{
|
||||
return last;
|
||||
}
|
||||
|
||||
fIndex *= m_afCumExtents[last];
|
||||
|
||||
// Binary search thru array.
|
||||
int lo = 0, hi = last;
|
||||
while (lo < hi)
|
||||
{
|
||||
int i = (lo + hi) >> 1;
|
||||
if (fIndex < m_afCumExtents[i])
|
||||
{
|
||||
hi = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
lo = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert(lo == 0 || m_afCumExtents[lo] > m_afCumExtents[lo - 1]);
|
||||
return lo;
|
||||
}
|
||||
|
||||
int RandomPart() const
|
||||
{
|
||||
return GetPart(cry_random(0.0f, 1.0f));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
DynArray<float> m_afCumExtents;
|
||||
int m_nEmptyEndParts;
|
||||
};
|
||||
|
||||
class CGeomExtents
|
||||
{
|
||||
public:
|
||||
|
||||
ILINE CGeomExtents()
|
||||
: m_aExtents(0) {}
|
||||
~CGeomExtents()
|
||||
{ delete[] m_aExtents; }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
delete[] m_aExtents;
|
||||
m_aExtents = 0;
|
||||
}
|
||||
|
||||
ILINE CGeomExtent const& operator [](EGeomForm eForm) const
|
||||
{
|
||||
assert(eForm >= 0 && eForm < MaxGeomForm);
|
||||
if (m_aExtents)
|
||||
{
|
||||
return m_aExtents[eForm];
|
||||
}
|
||||
|
||||
static CGeomExtent s_empty;
|
||||
return s_empty;
|
||||
}
|
||||
|
||||
ILINE CGeomExtent& Make(EGeomForm eForm)
|
||||
{
|
||||
assert(eForm >= 0 && eForm < MaxGeomForm);
|
||||
if (!m_aExtents)
|
||||
{
|
||||
m_aExtents = new CGeomExtent[4];
|
||||
}
|
||||
return m_aExtents[eForm];
|
||||
}
|
||||
|
||||
protected:
|
||||
CGeomExtent* m_aExtents;
|
||||
};
|
||||
|
||||
|
||||
// Other random/extent functions
|
||||
|
||||
inline float ScaleExtent(EGeomForm eForm, float fScale)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
return 1;
|
||||
case GeomForm_Edges:
|
||||
return fScale;
|
||||
case GeomForm_Surface:
|
||||
return fScale * fScale;
|
||||
case GeomForm_Volume:
|
||||
return fScale * fScale * fScale;
|
||||
}
|
||||
}
|
||||
|
||||
inline float BoxExtent(EGeomForm eForm, Vec3 const& vSize)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
return 8.f;
|
||||
case GeomForm_Edges:
|
||||
return (vSize.x + vSize.y + vSize.z) * 8.f;
|
||||
case GeomForm_Surface:
|
||||
return (vSize.x * vSize.y + vSize.x * vSize.z + vSize.y * vSize.z) * 8.f;
|
||||
case GeomForm_Volume:
|
||||
return vSize.x * vSize.y * vSize.z * 8.f;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions.
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
const typename T::value_type& RandomElem(const T& array)
|
||||
{
|
||||
int n = cry_random(0U, array.size() - 1);
|
||||
return array[n];
|
||||
}
|
||||
|
||||
// Geometric primitive randomizing functions.
|
||||
ILINE void BoxRandomPos(PosNorm& ran, EGeomForm eForm, Vec3 const& vSize)
|
||||
{
|
||||
ran.vPos = cry_random_componentwise(-vSize, vSize);
|
||||
ran.vNorm = ran.vPos;
|
||||
|
||||
if (eForm != GeomForm_Volume)
|
||||
{
|
||||
// Generate a random corner, for collapsing random point.
|
||||
int nCorner = cry_random(0, 7);
|
||||
ran.vNorm.x = (((nCorner & 1) << 1) - 1) * vSize.x;
|
||||
ran.vNorm.y = (((nCorner & 2)) - 1) * vSize.y;
|
||||
ran.vNorm.z = (((nCorner & 4) >> 1) - 1) * vSize.z;
|
||||
|
||||
if (eForm == GeomForm_Vertices)
|
||||
{
|
||||
ran.vPos = ran.vNorm;
|
||||
}
|
||||
else if (eForm == GeomForm_Surface)
|
||||
{
|
||||
// Collapse one axis.
|
||||
float fAxis = cry_random(0.0f, vSize.x * vSize.y + vSize.y * vSize.z + vSize.z * vSize.x);
|
||||
if ((fAxis -= vSize.y * vSize.z) < 0.f)
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vNorm.y = ran.vNorm.z = 0.f;
|
||||
}
|
||||
else if ((fAxis -= vSize.z * vSize.x) < 0.f)
|
||||
{
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vNorm.x = ran.vNorm.z = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.x = ran.vNorm.y = 0.f;
|
||||
}
|
||||
}
|
||||
else if (eForm == GeomForm_Edges)
|
||||
{
|
||||
// Collapse 2 axes.
|
||||
float fAxis = cry_random(0.0f, vSize.x + vSize.y + vSize.z);
|
||||
if ((fAxis -= vSize.x) < 0.f)
|
||||
{
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.x = 0.f;
|
||||
}
|
||||
else if ((fAxis -= vSize.y) < 0.f)
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vPos.z = ran.vNorm.z;
|
||||
ran.vNorm.y = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ran.vPos.x = ran.vNorm.x;
|
||||
ran.vPos.y = ran.vNorm.y;
|
||||
ran.vNorm.z = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ran.vNorm.Normalize();
|
||||
}
|
||||
|
||||
inline float CircleExtent(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
case GeomForm_Edges:
|
||||
return gf_PI2 * fRadius;
|
||||
case GeomForm_Surface:
|
||||
return gf_PI * square(fRadius);
|
||||
default:
|
||||
return 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
inline Vec2 CircleRandomPoint(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
Vec2 vPt;
|
||||
switch (eForm)
|
||||
{
|
||||
case GeomForm_Edges:
|
||||
// Generate random angle.
|
||||
sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x);
|
||||
vPt *= fRadius;
|
||||
break;
|
||||
case GeomForm_Surface:
|
||||
// Generate random angle, and radius, adjusted for even distribution.
|
||||
sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x);
|
||||
vPt *= sqrt(cry_random(0.0f, 1.0f)) * fRadius;
|
||||
break;
|
||||
default:
|
||||
vPt.x = vPt.y = 0.f;
|
||||
}
|
||||
return vPt;
|
||||
}
|
||||
|
||||
inline float SphereExtent(EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
return 0.f;
|
||||
case GeomForm_Surface:
|
||||
return gf_PI * 4.f * sqr(fRadius);
|
||||
case GeomForm_Volume:
|
||||
return gf_PI * 4.f / 3.f * cube(fRadius);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SphereRandomPos(PosNorm& ran, EGeomForm eForm, float fRadius)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
ran.vPos.zero();
|
||||
ran.vNorm.zero();
|
||||
return;
|
||||
case GeomForm_Surface:
|
||||
case GeomForm_Volume:
|
||||
{
|
||||
// Generate point on surface, as normal.
|
||||
float fPhi = cry_random(0.0f, gf_PI2);
|
||||
float fZ = cry_random(-1.f, 1.f);
|
||||
float fH = sqrt_tpl(1.f - fZ * fZ);
|
||||
sincos_tpl(fPhi, &ran.vNorm.y, &ran.vNorm.x);
|
||||
ran.vNorm.x *= fH;
|
||||
ran.vNorm.y *= fH;
|
||||
ran.vNorm.z = fZ;
|
||||
|
||||
ran.vPos = ran.vNorm;
|
||||
if (eForm == GeomForm_Volume)
|
||||
{
|
||||
float fV = cry_random(0.0f, 1.0f);
|
||||
float fR = pow_tpl(fV, 0.333333f);
|
||||
ran.vPos *= fR;
|
||||
}
|
||||
ran.vPos *= fRadius;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Triangle randomisation functions
|
||||
|
||||
inline float TriExtent(EGeomForm eForm, Vec3 const aPos[3])
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Edges:
|
||||
return (aPos[1] - aPos[0]).GetLengthFast();
|
||||
case GeomForm_Surface:
|
||||
return ((aPos[1] - aPos[0]) % (aPos[2] - aPos[0])).GetLengthFast() * 0.5f;
|
||||
case GeomForm_Volume:
|
||||
// Generate signed volume of pyramid by computing triple product of vertices.
|
||||
return ((aPos[0] ^ aPos[1]) | aPos[2]) / 6.0f;
|
||||
}
|
||||
}
|
||||
|
||||
inline void TriRandomPos(PosNorm& ran, EGeomForm eForm, PosNorm const aRan[3], bool bDoNormals)
|
||||
{
|
||||
// Generate interpolators for verts.
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
ran = aRan[0];
|
||||
return;
|
||||
case GeomForm_Edges:
|
||||
{
|
||||
float t = cry_random(0.0f, 1.0f);
|
||||
ran.vPos = aRan[0].vPos * (1.f - t) + aRan[1].vPos * t;
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = aRan[0].vNorm * (1.f - t) + aRan[1].vNorm * t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeomForm_Surface:
|
||||
{
|
||||
float t0 = cry_random(0.0f, 1.0f);
|
||||
float t1 = cry_random(0.0f, 1.0f);
|
||||
float t2 = cry_random(0.0f, 1.0f);
|
||||
float fSum = t0 + t1 + t2;
|
||||
ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum);
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeomForm_Volume:
|
||||
{
|
||||
float t0 = cry_random(0.0f, 1.0f);
|
||||
float t1 = cry_random(0.0f, 1.0f);
|
||||
float t2 = cry_random(0.0f, 1.0f);
|
||||
float t3 = cry_random(0.0f, 1.0f);
|
||||
float fSum = t0 + t1 + t2 + t3;
|
||||
ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum);
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm = (aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2) * (1.f - t3) + ran.vPos.GetNormalizedFast() * t3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bDoNormals)
|
||||
{
|
||||
ran.vNorm.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Mesh random pos functions
|
||||
|
||||
inline int TriMeshPartCount(EGeomForm eForm, int nIndices)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices:
|
||||
case GeomForm_Edges:
|
||||
// Number of edges = verts.
|
||||
return nIndices;
|
||||
case GeomForm_Surface:
|
||||
case GeomForm_Volume:
|
||||
// Number of tris.
|
||||
assert(nIndices % 3 == 0);
|
||||
return nIndices / 3;
|
||||
}
|
||||
}
|
||||
|
||||
inline int TriIndices(int aIndices[3], int nPart, EGeomForm eForm)
|
||||
{
|
||||
switch (eForm)
|
||||
{
|
||||
default:
|
||||
assert(0);
|
||||
case GeomForm_Vertices: // Part is vert index
|
||||
aIndices[0] = nPart;
|
||||
return 1;
|
||||
case GeomForm_Edges: // Part is vert index
|
||||
aIndices[0] = nPart;
|
||||
aIndices[1] = nPart % 3 < 2 ? nPart + 1 : nPart - 2;
|
||||
return 2;
|
||||
case GeomForm_Surface: // Part is tri index
|
||||
case GeomForm_Volume:
|
||||
aIndices[0] = nPart * 3;
|
||||
aIndices[1] = aIndices[0] + 1;
|
||||
aIndices[2] = aIndices[0] + 2;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_GEOMQUERY_H
|
||||
@@ -1,617 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
#define CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
template<typename Key, typename DiscreetKey>
|
||||
struct hash_grid_2d
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
|
||||
typedef DiscreetKey discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
typedef hash_grid_2d<Key, DiscreetKey> type;
|
||||
|
||||
hash_grid_2d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ)
|
||||
: scaleFactorX(1 / cellSizeX)
|
||||
, scaleFactorY(1 / cellSizeY)
|
||||
{
|
||||
}
|
||||
|
||||
inline discreet_type discreet(const key_type& key) const
|
||||
{
|
||||
return discreet_type(static_cast<discreet_value>(key[0] * scaleFactorX),
|
||||
static_cast<discreet_value>(key[1] * scaleFactorY),
|
||||
static_cast<discreet_value>(0));
|
||||
}
|
||||
|
||||
inline size_t hash(const key_type& key) const
|
||||
{
|
||||
return hash(discreet(key));
|
||||
}
|
||||
|
||||
inline size_t hash(const discreet_type& discreet) const
|
||||
{
|
||||
return static_cast<size_t>(
|
||||
(discreet[0] ^ 920129341) +
|
||||
(discreet[1] ^ 1926129311));
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
std::swap(scaleFactorX, other.scaleFactorX);
|
||||
std::swap(scaleFactorY, other.scaleFactorY);
|
||||
}
|
||||
|
||||
private:
|
||||
key_value scaleFactorX;
|
||||
key_value scaleFactorY;
|
||||
};
|
||||
|
||||
|
||||
template<typename Key, typename DiscreetKey>
|
||||
struct hash_grid_3d
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
|
||||
typedef DiscreetKey discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
typedef hash_grid_3d<Key, DiscreetKey> type;
|
||||
|
||||
hash_grid_3d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ)
|
||||
: scaleFactorX(1 / cellSizeX)
|
||||
, scaleFactorY(1 / cellSizeY)
|
||||
, scaleFactorZ(1 / cellSizeZ)
|
||||
{
|
||||
}
|
||||
|
||||
inline discreet_type discreet(const key_type& key) const
|
||||
{
|
||||
return discreet_type(static_cast<discreet_value>(key[0] * scaleFactorX),
|
||||
static_cast<discreet_value>(key[1] * scaleFactorY),
|
||||
static_cast<discreet_value>(key[2] * scaleFactorZ));
|
||||
}
|
||||
|
||||
inline size_t hash(const key_type& key) const
|
||||
{
|
||||
return hash(discreet(key));
|
||||
}
|
||||
|
||||
inline size_t hash(const discreet_type& discreet) const
|
||||
{
|
||||
return static_cast<size_t>(
|
||||
(discreet[0] ^ 920129341ul) +
|
||||
(discreet[1] ^ 1926129311ul) +
|
||||
(discreet[2] ^ 3926129401ul));
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
std::swap(scaleFactorX, other.scaleFactorX);
|
||||
std::swap(scaleFactorY, other.scaleFactorY);
|
||||
std::swap(scaleFactorZ, other.scaleFactorZ);
|
||||
}
|
||||
|
||||
private:
|
||||
key_value scaleFactorX;
|
||||
key_value scaleFactorY;
|
||||
key_value scaleFactorZ;
|
||||
};
|
||||
|
||||
|
||||
template<typename KeyType, typename ValueType>
|
||||
struct hash_grid_no_position
|
||||
{
|
||||
KeyType operator()(const ValueType&) const
|
||||
{
|
||||
switch (0)
|
||||
{
|
||||
case 0:
|
||||
"hash_grid query performed without a valid position-retriever implementation";
|
||||
}
|
||||
;
|
||||
|
||||
return KeyType();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<int NumberOfCells, typename ValueType, typename KeyHash,
|
||||
typename PositionRetriever = hash_grid_no_position<typename KeyHash::key_type, ValueType> >
|
||||
class hash_grid
|
||||
: protected KeyHash
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
CellCount = NumberOfCells,
|
||||
};
|
||||
|
||||
typedef ValueType value_type;
|
||||
typedef KeyHash key_hash;
|
||||
|
||||
typedef typename key_hash::key_type key_type;
|
||||
typedef typename key_type::value_type key_value;
|
||||
typedef typename key_hash::discreet_type discreet_type;
|
||||
typedef typename discreet_type::value_type discreet_value;
|
||||
|
||||
|
||||
typedef PositionRetriever position_retriever_type;
|
||||
|
||||
typedef hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever> type;
|
||||
|
||||
typedef std::vector<value_type> items_type;
|
||||
|
||||
struct cell_type
|
||||
{
|
||||
cell_type()
|
||||
: query(0)
|
||||
{
|
||||
}
|
||||
|
||||
mutable uint32 query;
|
||||
items_type items;
|
||||
};
|
||||
typedef std::vector<cell_type> cells_type;
|
||||
|
||||
inline hash_grid(float cellSizeX = 20.0f, float cellSizeY = 20.0f, float cellSizeZ = 20.0f,
|
||||
const position_retriever_type& _position = position_retriever_type())
|
||||
: key_hash(cellSizeX, cellSizeY, cellSizeZ)
|
||||
, position(_position)
|
||||
, m_cells(CellCount)
|
||||
, m_count(0)
|
||||
, m_query(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
m_cells.clear();
|
||||
m_cells.resize(CellCount);
|
||||
m_count = 0;
|
||||
m_query = 0;
|
||||
}
|
||||
|
||||
inline void swap(type& other)
|
||||
{
|
||||
m_cells.swap(other);
|
||||
|
||||
std::swap(m_count, other.m_count);
|
||||
key_hash::swap(other);
|
||||
}
|
||||
|
||||
inline size_t size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
inline bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
struct iterator
|
||||
{
|
||||
iterator()
|
||||
: cell(~0u)
|
||||
, item(~0u)
|
||||
, grid(0)
|
||||
{
|
||||
}
|
||||
|
||||
value_type& operator*()
|
||||
{
|
||||
return grid->m_cells[cell][item];
|
||||
}
|
||||
|
||||
const value_type& operator*() const
|
||||
{
|
||||
return grid->m_cells[cell][item];
|
||||
}
|
||||
|
||||
value_type* operator->() const
|
||||
{
|
||||
return (&**this);
|
||||
}
|
||||
|
||||
iterator& operator++()
|
||||
{
|
||||
assert(cell < grid_type::CellCount);
|
||||
cell_type& items = grid->m_cells[cell];
|
||||
|
||||
if (!items.empty() && (item < items.size() - 1))
|
||||
{
|
||||
++item;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = 0;
|
||||
++cell;
|
||||
|
||||
while ((cell < type::CellCount) && grid->m_cells[cell].empty())
|
||||
{
|
||||
++cell;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator& operator--()
|
||||
{
|
||||
if (item > 0)
|
||||
{
|
||||
--item;
|
||||
}
|
||||
else
|
||||
{
|
||||
--cell;
|
||||
while ((cell > 0) && grid->m_cells[cell].empty())
|
||||
{
|
||||
--cell;
|
||||
}
|
||||
|
||||
assert(cell < type::CellCount);
|
||||
cell_type& items = grid->m_cells[cell];
|
||||
item = items.size() - 1;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator& other) const
|
||||
{
|
||||
return (cell == other.cell) && (item == other.item) && (grid == other.grid);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever>;
|
||||
typedef hash_grid<NumberOfCells, ValueType, KeyHash, PositionRetriever> grid_type;
|
||||
|
||||
iterator(size_t _cell, size_t _item, grid_type* _grid)
|
||||
: grid(_grid)
|
||||
, item(_item)
|
||||
, cell(_cell)
|
||||
{
|
||||
}
|
||||
|
||||
grid_type* grid;
|
||||
size_t cell;
|
||||
size_t item;
|
||||
};
|
||||
|
||||
inline iterator begin()
|
||||
{
|
||||
uint32 item = 0;
|
||||
uint32 cell = 0;
|
||||
|
||||
while ((cell < type::CellCount) && m_cells[cell].empty())
|
||||
{
|
||||
++cell;
|
||||
}
|
||||
|
||||
return iterator(cell, item, this);
|
||||
}
|
||||
|
||||
inline iterator end()
|
||||
{
|
||||
return iterator(CellCount, 0, this);
|
||||
}
|
||||
|
||||
inline iterator insert(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(key);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
|
||||
items.push_back(value);
|
||||
++m_count;
|
||||
|
||||
return iterator(index, items.size() - 1, this);
|
||||
}
|
||||
|
||||
inline void erase(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(key);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
|
||||
typename items_type::iterator it = items.begin();
|
||||
typename items_type::iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (*it == value)
|
||||
{
|
||||
std::swap(*it, items.back());
|
||||
items.pop_back();
|
||||
--m_count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline iterator erase(const iterator& it)
|
||||
{
|
||||
--m_count;
|
||||
cell_type& cell = m_cells[it.cell];
|
||||
items_type& items = cell.items;
|
||||
std::swap(items[it.item], items.back());
|
||||
items.pop_back();
|
||||
if (!items.empty())
|
||||
{
|
||||
return it;
|
||||
}
|
||||
|
||||
uint32 index = it.cell;
|
||||
while ((index < CellCount) && m_cells[index].items.empty())
|
||||
{
|
||||
++index;
|
||||
}
|
||||
|
||||
return iterator(index, 0, this);
|
||||
}
|
||||
|
||||
inline iterator find(const key_type& key, const value_type& value)
|
||||
{
|
||||
size_t index = KeyHash::hash(key) % CellCount;
|
||||
|
||||
cell_type& cell = m_cells[index];
|
||||
items_type& items = cell.items;
|
||||
typename items_type::iterator it = items.begin();
|
||||
typename items_type::iterator iend = items.end();
|
||||
|
||||
for (; it != iend; ++it)
|
||||
{
|
||||
if (*it == value)
|
||||
{
|
||||
return iterator(index, it - items.begin(), this);
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
inline iterator move(const iterator& it, const key_type& to)
|
||||
{
|
||||
size_t index = KeyHash::hash(to) % CellCount;
|
||||
|
||||
if (index == it.cell)
|
||||
{
|
||||
return it;
|
||||
}
|
||||
|
||||
cell_type& cell = m_cells[it.cell];
|
||||
items_type& items = cell.items;
|
||||
typename items_type::iterator iit = items.begin() + it.item;
|
||||
|
||||
cell_type& to_cell = m_cells[index];
|
||||
items_type& to_items = to_cell.items;
|
||||
to_items.push_back(*iit);
|
||||
|
||||
std::swap(items[it.item], items.back());
|
||||
items.pop_back();
|
||||
|
||||
return iterator(index, to_items.size() - 1, this);
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_sphere(const key_type& center, const key_value& radius, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
key_type minc(center - key_type(radius));
|
||||
key_type maxc(center + key_type(radius));
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
float radius_sq = radius * radius;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if ((position(*it) - center).len2() <= radius_sq)
|
||||
{
|
||||
container.push_back(*it);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_sphere_distance(const key_type& center, const key_value& radius, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
key_type minc(center - key_type(radius));
|
||||
key_type maxc(center + key_type(radius));
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
float radius_sq = radius * radius;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
float distance_sq = (position(*it) - center).len2();
|
||||
if (distance_sq <= radius_sq)
|
||||
{
|
||||
container.push_back(std::make_pair(distance_sq, *it));
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename Container>
|
||||
uint32 query_box(const key_type& minc, const key_type& maxc, Container& container) const
|
||||
{
|
||||
uint32 count = 0;
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
++m_query;
|
||||
|
||||
discreet_type mind = KeyHash::discreet(minc);
|
||||
discreet_type maxd = KeyHash::discreet(maxc);
|
||||
discreet_type current = mind;
|
||||
|
||||
for (; current[0] <= maxd[0]; ++current[0])
|
||||
{
|
||||
for (; current[1] <= maxd[1]; ++current[1])
|
||||
{
|
||||
for (; current[2] <= maxd[2]; ++current[2])
|
||||
{
|
||||
size_t hash_value = KeyHash::hash(current);
|
||||
size_t index = hash_value % CellCount;
|
||||
|
||||
const cell_type& cell = m_cells[index];
|
||||
|
||||
if (cell.query != m_query)
|
||||
{
|
||||
cell.query = m_query;
|
||||
const items_type& items = cell.items;
|
||||
|
||||
typename items_type::const_iterator it = items.begin();
|
||||
typename items_type::const_iterator end = items.end();
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
key_type pos = position(*it);
|
||||
|
||||
if (pos[0] >= minc[0] &&
|
||||
pos[1] >= minc[1] &&
|
||||
pos[2] >= minc[2] &&
|
||||
pos[0] <= maxc[0] &&
|
||||
pos[1] <= maxc[1] &&
|
||||
pos[2] <= maxc[2])
|
||||
{
|
||||
container.push_back(*it);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
current[2] = mind[2];
|
||||
}
|
||||
current[1] = mind[1];
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
protected:
|
||||
position_retriever_type position;
|
||||
cells_type m_cells;
|
||||
uint32 m_count;
|
||||
mutable uint32 m_query;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_HASHGRID_H
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Containers that use their own heap for allocation.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
#pragma once
|
||||
|
||||
#include "PoolAllocator.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, typename L = stl::PSyncMultiThread>
|
||||
struct HeapQueue
|
||||
: public L
|
||||
{
|
||||
typedef typename L::Lock Lock;
|
||||
|
||||
HeapQueue()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
T* push_back()
|
||||
{
|
||||
Lock lock(*this);
|
||||
return push_back(m_Allocator.New());
|
||||
}
|
||||
|
||||
template<class I>
|
||||
T* push_back(I const& init)
|
||||
{
|
||||
Lock lock(*this);
|
||||
Node* pNode = (Node*)m_Allocator.Allocate();
|
||||
new(static_cast<T*>(pNode))T(init);
|
||||
return push_back(pNode);
|
||||
}
|
||||
|
||||
template<class I, class J>
|
||||
T* push_back(I const& i, J const& j)
|
||||
{
|
||||
Lock lock(*this);
|
||||
Node* pNode = (Node*)m_Allocator.Allocate();
|
||||
new(static_cast<T*>(pNode))T(i, j);
|
||||
return push_back(pNode);
|
||||
}
|
||||
|
||||
T* pop_front()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
// Quick check, before locking.
|
||||
if (empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Node* pNode = *m_ppHead;
|
||||
if (pNode)
|
||||
{
|
||||
m_ppHead = &(*m_ppHead)->pNext;
|
||||
m_nQueued--;
|
||||
validate();
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
validate();
|
||||
|
||||
// Destruct all elements.
|
||||
size_t nCheckAlloc = 0;
|
||||
while (m_pList)
|
||||
{
|
||||
nCheckAlloc++;
|
||||
Node* pNext = m_pList->pNext;
|
||||
m_pList->~Node();
|
||||
m_pList = pNext;
|
||||
}
|
||||
assert(nCheckAlloc == m_nAlloc);
|
||||
|
||||
// Empty queue structure.
|
||||
reset();
|
||||
|
||||
// Free pool memory all at once.
|
||||
m_Allocator.FreeMemory(false);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_nQueued;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_nQueued == 0;
|
||||
}
|
||||
|
||||
size_t allocated_memory() const
|
||||
{
|
||||
// Amortise allocated mem over all list instances.
|
||||
Lock lock(*this);
|
||||
return m_Allocator.GetTotalMemory().nAlloc;
|
||||
}
|
||||
|
||||
// Additional lock against storage deletion.
|
||||
L ClearLock;
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(m_Allocator);
|
||||
}
|
||||
protected:
|
||||
|
||||
struct Node
|
||||
: T
|
||||
{
|
||||
Node* pNext;
|
||||
};
|
||||
|
||||
Node* m_pList; // First (allocated) node in list.
|
||||
Node** m_ppHead; // Points to pointer to front of queue, for popping.
|
||||
Node** m_ppTail; // Points to pointer at end of list, and of queue, for pushing.
|
||||
size_t m_nAlloc, m_nQueued;
|
||||
|
||||
void validate()
|
||||
{
|
||||
assert(m_nQueued <= m_nAlloc);
|
||||
assert(m_ppHead);
|
||||
assert(m_ppTail);
|
||||
assert(!*m_ppTail);
|
||||
assert((m_nQueued == 0) == !*m_ppHead);
|
||||
assert((m_nQueued == 0) == (m_ppHead == m_ppTail));
|
||||
assert((m_nAlloc == 0) == (m_ppTail == &m_pList));
|
||||
assert((m_nAlloc == 0) == !m_pList);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_pList = 0;
|
||||
m_ppHead = m_ppTail = &m_pList;
|
||||
m_nAlloc = m_nQueued = 0;
|
||||
validate();
|
||||
}
|
||||
|
||||
Node* push_back(Node* pNode)
|
||||
{
|
||||
pNode->pNext = 0;
|
||||
|
||||
*m_ppTail = pNode;
|
||||
m_ppTail = &pNode->pNext;
|
||||
m_nAlloc++;
|
||||
m_nQueued++;
|
||||
|
||||
validate();
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
// Allocate all elements from an exclusive pool.
|
||||
// Any locking is performed by the queue, no further locking needed in allocator.
|
||||
stl::TPoolAllocator<Node, stl::PSyncNone> m_Allocator;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T, class C = std::less<T>, typename L = stl::PSyncNone>
|
||||
struct HeapPriorityQueue
|
||||
: public HeapQueue<T, L>
|
||||
{
|
||||
// Hand-holding for brain-dead template compiler.
|
||||
typedef HeapQueue<T, L> super;
|
||||
typedef typename super::Node Node;
|
||||
using super::empty;
|
||||
using super::validate;
|
||||
using super::m_ppHead;
|
||||
using super::m_ppTail;
|
||||
using super::m_nQueued;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename super::Lock Lock;
|
||||
|
||||
// Pop the "largest" element, using class C.
|
||||
T* pop_largest()
|
||||
{
|
||||
Lock lock(*this);
|
||||
|
||||
if (!empty())
|
||||
{
|
||||
C comp;
|
||||
|
||||
// Find highest-valued item.
|
||||
// To do: improve linear search! Use priority queue.
|
||||
Node** ppTop = m_ppHead;
|
||||
for (Node** ppNode = &(*m_ppHead)->pNext; *ppNode; ppNode = &(*ppNode)->pNext)
|
||||
{
|
||||
if (comp(**ppTop, **ppNode))
|
||||
{
|
||||
ppTop = ppNode;
|
||||
}
|
||||
}
|
||||
Node* pTop = *ppTop;
|
||||
|
||||
// Move link to head.
|
||||
if (ppTop != m_ppHead)
|
||||
{
|
||||
if (!pTop->pNext)
|
||||
{
|
||||
// End of list.
|
||||
m_ppTail = ppTop;
|
||||
}
|
||||
*ppTop = pTop->pNext;
|
||||
pTop->pNext = *m_ppHead;
|
||||
*m_ppHead = pTop;
|
||||
}
|
||||
|
||||
// Pop head.
|
||||
m_ppHead = &pTop->pNext;
|
||||
m_nQueued--;
|
||||
|
||||
validate();
|
||||
return pTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GetMemoryUsage(ICrySizer* pSizer) const
|
||||
{
|
||||
HeapQueue<T, L>::GetMemoryUsage(pSizer);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryHeaders.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Description:
|
||||
// Chunked File (.cgf, .chr etc.) interface
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct IChunkFile
|
||||
: _reference_target_t
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Chunk Description.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct ChunkDesc
|
||||
{
|
||||
ChunkTypes chunkType;
|
||||
int chunkVersion;
|
||||
int chunkId;
|
||||
uint32 fileOffset;
|
||||
void* data;
|
||||
uint32 size;
|
||||
bool bSwapEndian;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ChunkDesc()
|
||||
: chunkType(ChunkType_ANY)
|
||||
, chunkVersion(0)
|
||||
, chunkId(0)
|
||||
, fileOffset(0)
|
||||
, data(0)
|
||||
, size(0)
|
||||
, bSwapEndian(false)
|
||||
{
|
||||
}
|
||||
|
||||
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{ /*nothing*/}
|
||||
|
||||
static inline bool LessOffset(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.fileOffset < d2.fileOffset; }
|
||||
static inline bool LessOffsetByPtr(const ChunkDesc* d1, const ChunkDesc* d2) { return d1->fileOffset < d2->fileOffset; }
|
||||
static inline bool LessId(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.chunkId < d2.chunkId; }
|
||||
};
|
||||
|
||||
// <interfuscator:shuffle>
|
||||
|
||||
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
|
||||
|
||||
// Releases chunk file interface.
|
||||
virtual void Release() = 0;
|
||||
|
||||
virtual bool IsReadOnly() const = 0;
|
||||
virtual bool IsLoaded() const = 0;
|
||||
|
||||
virtual bool Read(const char* filename) = 0;
|
||||
virtual bool ReadFromMemory(const void* pData, int nDataSize) = 0;
|
||||
|
||||
// Writes chunks to file.
|
||||
virtual bool Write(const char* filename) = 0;
|
||||
// Writes chunks to a memory buffer (allocated inside) and returns
|
||||
// pointer to the allocated memory (pData) and its size (nSize).
|
||||
// The memory will be released on destruction of the ChunkFile object, or
|
||||
// on the next WriteToMemoryBuffer() call, or on ReleaseMemoryBuffer() call.
|
||||
virtual bool WriteToMemoryBuffer(void** pData, int* nSize) = 0;
|
||||
// Releases memory that was allocated in WriteToMemoryBuffer()
|
||||
virtual void ReleaseMemoryBuffer() = 0;
|
||||
|
||||
// Adds chunk to file, returns ChunkID of the added chunk.
|
||||
virtual int AddChunk(ChunkTypes chunkType, int chunkVersion, EEndianness eEndianness, const void* chunkData, int chunkSize) = 0;
|
||||
virtual void DeleteChunkById(int nChunkId) = 0;
|
||||
virtual void DeleteChunksByType(ChunkTypes nChunkType) = 0;
|
||||
|
||||
virtual ChunkDesc* FindChunkByType(ChunkTypes nChunkType) = 0;
|
||||
virtual ChunkDesc* FindChunkById(int nChunkId) = 0;
|
||||
|
||||
// Gets the number of chunks.
|
||||
virtual int NumChunks() const = 0;
|
||||
|
||||
// Gets chunk description at i-th index.
|
||||
virtual ChunkDesc* GetChunk(int nIndex) = 0;
|
||||
virtual const ChunkDesc* GetChunk(int nIndex) const = 0;
|
||||
|
||||
virtual const char* GetLastError() const = 0;
|
||||
|
||||
// </interfuscator:shuffle>
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
struct SColorChartLayer
|
||||
{
|
||||
int m_texID;
|
||||
float m_blendAmount;
|
||||
|
||||
SColorChartLayer()
|
||||
: m_texID(-1)
|
||||
, m_blendAmount(-1)
|
||||
{
|
||||
}
|
||||
|
||||
SColorChartLayer(int texID, float blendAmount)
|
||||
: m_texID(texID)
|
||||
, m_blendAmount(blendAmount)
|
||||
{
|
||||
}
|
||||
|
||||
SColorChartLayer(const SColorChartLayer& rhs)
|
||||
: m_texID(rhs.m_texID)
|
||||
, m_blendAmount(rhs.m_blendAmount)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct IColorGradingController
|
||||
{
|
||||
public:
|
||||
// <interfuscator:shuffle>
|
||||
virtual ~IColorGradingController(){}
|
||||
virtual int LoadColorChart(const char* pChartFilePath) const = 0;
|
||||
virtual int LoadDefaultColorChart() const = 0;
|
||||
virtual void UnloadColorChart(int texID) const = 0;
|
||||
|
||||
virtual void SetLayers(const SColorChartLayer* pLayers, uint32 numLayers) = 0;
|
||||
// </interfuscator:shuffle>
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H
|
||||
@@ -27,7 +27,6 @@ namespace AZ
|
||||
struct IMaterial;
|
||||
struct IVisArea;
|
||||
struct SRenderingPassInfo;
|
||||
struct IGeomCache;
|
||||
struct SRendItemSorter;
|
||||
struct SFrameLodInfo;
|
||||
struct pe_params_area;
|
||||
@@ -259,9 +258,6 @@ struct IRenderNode
|
||||
virtual struct IStatObj* GetEntityStatObj(unsigned int nPartId = 0, unsigned int nSubPartId = 0, Matrix34A* pMatrix = NULL, bool bReturnOnlyVisible = false);
|
||||
virtual _smart_ptr<IMaterial> GetEntitySlotMaterial([[maybe_unused]] unsigned int nPartId, [[maybe_unused]] bool bReturnOnlyVisible = false, [[maybe_unused]] bool* pbDrawNear = NULL) { return NULL; }
|
||||
virtual void SetEntityStatObj([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] IStatObj* pStatObj, [[maybe_unused]] const Matrix34A* pMatrix = NULL) {};
|
||||
#if defined(USE_GEOM_CACHES)
|
||||
virtual struct IGeomCacheRenderNode* GetGeomCacheRenderNode([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] Matrix34A* pMatrix = NULL, [[maybe_unused]] bool bReturnOnlyVisible = false) { return NULL; }
|
||||
#endif
|
||||
virtual int GetSlotCount() const { return 1; }
|
||||
|
||||
// Summary:
|
||||
@@ -793,81 +789,4 @@ struct IPrismRenderNode
|
||||
};
|
||||
#endif // EXCLUDE_DOCUMENTATION_PURPOSE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(USE_GEOM_CACHES)
|
||||
struct IGeomCacheRenderNode
|
||||
: public IRenderNode
|
||||
{
|
||||
virtual bool LoadGeomCache(const char* sGeomCacheFileName) = 0;
|
||||
|
||||
virtual void SetGeomCache(_smart_ptr<IGeomCache> geomCache) = 0;
|
||||
|
||||
// Gets the geometry cache that is rendered
|
||||
virtual IGeomCache* GetGeomCache() const = 0;
|
||||
|
||||
// Sets the time in the animation for the current frame.
|
||||
// Note that you should start streaming before calling this.
|
||||
virtual void SetPlaybackTime(const float time) = 0;
|
||||
|
||||
// Get the current playback time
|
||||
virtual float GetPlaybackTime() const = 0;
|
||||
|
||||
// Check if cache is streaming.
|
||||
virtual bool IsStreaming() const = 0;
|
||||
|
||||
// Need to start streaming before playback, otherwise there will be stalls.
|
||||
virtual void StartStreaming(const float time = 0.0f) = 0;
|
||||
|
||||
// Stops streaming and trashes the buffers
|
||||
virtual void StopStreaming() = 0;
|
||||
|
||||
// Checks if looping is enabled
|
||||
virtual bool IsLooping() const = 0;
|
||||
|
||||
// Enable/disable looping playback
|
||||
virtual void SetLooping(const bool bEnable) = 0;
|
||||
|
||||
// Gets time delta from current playback position to last ready to play frame
|
||||
virtual float GetPrecachedTime() const = 0;
|
||||
|
||||
// Check if bounds changed since last call to this function
|
||||
virtual bool DidBoundsChange() = 0;
|
||||
|
||||
// Set stand in CGFs and distance
|
||||
virtual void SetStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetStandIn() = 0;
|
||||
virtual void SetFirstFrameStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetFirstFrameStandIn() = 0;
|
||||
virtual void SetLastFrameStandIn(const char* pFilePath, const char* pMaterial) = 0;
|
||||
virtual IStatObj* GetLastFrameStandIn() = 0;
|
||||
virtual void SetStandInDistance(const float distance) = 0;
|
||||
virtual float GetStandInDistance() = 0;
|
||||
|
||||
// Set distance at which cache will start streaming automatically (0 means no auto streaming)
|
||||
virtual void SetStreamInDistance(const float distance) = 0;
|
||||
virtual float GetStreamInDistance() = 0;
|
||||
|
||||
// Start/Stop drawing the cache
|
||||
virtual void SetDrawing(bool bDrawing) = 0;
|
||||
|
||||
// Debug draw geometry
|
||||
virtual void DebugDraw(const struct SGeometryDebugDrawInfo& info, float fExtrudeScale = 0.01f, uint nodeIndex = 0) const = 0;
|
||||
|
||||
// Ray intersection against cache
|
||||
virtual bool RayIntersection(struct SRayHitInfo& hitInfo, _smart_ptr<IMaterial> pCustomMtl = NULL, uint* pHitNodeIndex = NULL) const = 0;
|
||||
|
||||
// Set max view distance
|
||||
virtual void SetBaseMaxViewDistance(float maxViewDistance) = 0;
|
||||
|
||||
// Get node information
|
||||
virtual uint GetNodeCount() const = 0;
|
||||
virtual Matrix34 GetNodeTransform(const uint nodeIndex) const = 0;
|
||||
virtual const char* GetNodeName(const uint nodeIndex) const = 0; // Node name is only stored in editor
|
||||
virtual uint32 GetNodeNameHash(const uint nodeIndex) const = 0;
|
||||
virtual bool IsNodeDataValid(const uint nodeIndex) const = 0; // Returns false if cache isn't loaded yet or index is out of range
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IENTITYRENDERSTATE_H
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
#pragma once
|
||||
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
class ITexture;
|
||||
|
||||
enum FuncParamType
|
||||
{
|
||||
e_FLOAT, e_INT, e_BOOL, e_VEC2, e_VEC3, e_VEC4, e_COLOR, e_MATRIX33,
|
||||
// Though all types of textures are using the same class, it's important for editor to differentiate between them:
|
||||
e_TEXTURE2D, e_TEXTURE3D, e_TEXTURE_CUBE
|
||||
};
|
||||
|
||||
class IFuncVariable
|
||||
: public _reference_target_t
|
||||
{
|
||||
public:
|
||||
// <interfuscator:shuffle>
|
||||
virtual ~IFuncVariable(){};
|
||||
|
||||
virtual float GetMin() const = 0;
|
||||
virtual float GetMax() const = 0;
|
||||
|
||||
virtual void InvokeSetter(void* param) = 0;
|
||||
|
||||
virtual int GetInt() const = 0;
|
||||
virtual float GetFloat() const = 0;
|
||||
virtual bool GetBool() const = 0;
|
||||
virtual Vec2 GetVec2() const = 0;
|
||||
virtual Vec3 GetVec3() const = 0;
|
||||
virtual Vec4 GetVec4() const = 0;
|
||||
virtual ColorF GetColorF() const = 0;
|
||||
virtual Matrix33 GetMatrix33() const = 0;
|
||||
virtual ITexture* GetTexture() const = 0;
|
||||
// </interfuscator:shuffle>
|
||||
|
||||
enum FuncParamType paramType; // float, string, int, vec3 etc
|
||||
string name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
string humanName;
|
||||
string description;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class MFPVariable
|
||||
: public IFuncVariable
|
||||
{
|
||||
public:
|
||||
typedef void (T::* OpticsBase_MFPtr)();
|
||||
OpticsBase_MFPtr pSetter;
|
||||
OpticsBase_MFPtr pGetter;
|
||||
T* pObj;
|
||||
std::pair<float, float> range;
|
||||
|
||||
private:
|
||||
MFPVariable ()
|
||||
{
|
||||
Set(e_INT, "", "", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
float GetMin() const override { return range.first; }
|
||||
float GetMax() const override { return range.second; }
|
||||
|
||||
MFPVariable(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f)
|
||||
{
|
||||
Set(type, _humanname, _description, obj, setter, getter, fMin, fMax);
|
||||
}
|
||||
|
||||
void Set(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f)
|
||||
{
|
||||
paramType = type;
|
||||
|
||||
char _nameNoSpace[50];
|
||||
cry_strcpy(_nameNoSpace, _humanname);
|
||||
char* p1 = _nameNoSpace;
|
||||
char* p2 = p1;
|
||||
while (*p1 != 0)
|
||||
{
|
||||
if ((*p1) == ' ')
|
||||
{
|
||||
++p1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p2++ = *p1++;
|
||||
}
|
||||
}
|
||||
|
||||
*p2 = 0;
|
||||
name = _nameNoSpace;
|
||||
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
humanName = _humanname;
|
||||
description = _description;
|
||||
#endif
|
||||
|
||||
pObj = obj;
|
||||
pSetter = setter;
|
||||
pGetter = getter;
|
||||
range.first = fMin;
|
||||
range.second = fMax;
|
||||
}
|
||||
|
||||
#define INVOKE_SETTER(PARAM_TYPE, param) (pObj->*(reinterpret_cast<void (T::*)(PARAM_TYPE)>(pSetter)))(*(PARAM_TYPE*)param)
|
||||
#define INVOKE_SETTER_P(PARAM_TYPE, param) (pObj->*(reinterpret_cast<void (T::*)(PARAM_TYPE)>(pSetter)))((PARAM_TYPE)param)
|
||||
|
||||
void InvokeSetter(void* param) override
|
||||
{
|
||||
switch (paramType)
|
||||
{
|
||||
case e_FLOAT:
|
||||
INVOKE_SETTER(float, param);
|
||||
break;
|
||||
case e_INT:
|
||||
INVOKE_SETTER(int, param);
|
||||
break;
|
||||
case e_VEC2:
|
||||
INVOKE_SETTER(Vec2, param);
|
||||
break;
|
||||
case e_VEC3:
|
||||
INVOKE_SETTER(Vec3, param);
|
||||
break;
|
||||
case e_VEC4:
|
||||
INVOKE_SETTER(Vec4, param);
|
||||
break;
|
||||
case e_BOOL:
|
||||
INVOKE_SETTER(bool, param);
|
||||
break;
|
||||
case e_COLOR:
|
||||
INVOKE_SETTER(ColorF, param);
|
||||
break;
|
||||
case e_MATRIX33:
|
||||
INVOKE_SETTER(Matrix33, param);
|
||||
break;
|
||||
case e_TEXTURE2D:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
case e_TEXTURE3D:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
case e_TEXTURE_CUBE:
|
||||
INVOKE_SETTER_P(ITexture*, param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INVOKE_GETTER(PARAM_TYPE) ((pObj->*reinterpret_cast<PARAM_TYPE (T::*)()>(pGetter))())
|
||||
|
||||
int GetInt() const override {return INVOKE_GETTER(int); }
|
||||
float GetFloat() const override {return INVOKE_GETTER(float); }
|
||||
bool GetBool() const override {return INVOKE_GETTER(bool); }
|
||||
Vec2 GetVec2() const override {return INVOKE_GETTER(Vec2); }
|
||||
Vec3 GetVec3() const override {return INVOKE_GETTER(Vec3); }
|
||||
Vec4 GetVec4() const override {return INVOKE_GETTER(Vec4); }
|
||||
ColorF GetColorF() const override {return INVOKE_GETTER(ColorF); }
|
||||
Matrix33 GetMatrix33() const override {return INVOKE_GETTER(Matrix33); }
|
||||
ITexture* GetTexture() const override {return INVOKE_GETTER(ITexture*); }
|
||||
};
|
||||
|
||||
class FuncVariableGroup
|
||||
{
|
||||
private:
|
||||
AZStd::vector<_smart_ptr<IFuncVariable> > variables;
|
||||
string m_name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
string m_humanname;
|
||||
#endif
|
||||
bool bCollapse;
|
||||
|
||||
public:
|
||||
FuncVariableGroup()
|
||||
: bCollapse(false)
|
||||
{
|
||||
SetName("");
|
||||
}
|
||||
|
||||
~FuncVariableGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void SetName(const char* name, [[maybe_unused]] const char* humanname = 0)
|
||||
{
|
||||
if (!name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_name = name;
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
m_humanname = humanname ? humanname : name;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* GetName()
|
||||
{
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
#if defined(FLARES_SUPPORT_EDITING)
|
||||
const char* GetHumanName()
|
||||
{
|
||||
return m_humanname.c_str();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SetCollapse(bool _bCollapse)
|
||||
{
|
||||
bCollapse = _bCollapse;
|
||||
}
|
||||
|
||||
bool IsCollapse()
|
||||
{
|
||||
return bCollapse;
|
||||
}
|
||||
|
||||
IFuncVariable* FindVariable(const char* name)
|
||||
{
|
||||
for (int i = 0, iSize(variables.size()); i < iSize; ++i)
|
||||
{
|
||||
if (variables[i] == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(variables[i]->name.c_str(), name))
|
||||
{
|
||||
return variables[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetVariable(int nIndex, IFuncVariable* v){ variables[nIndex] = v; }
|
||||
|
||||
int GetVariableCount() { return variables.size(); }
|
||||
|
||||
IFuncVariable* GetVariable(int nIndex)
|
||||
{
|
||||
return variables[nIndex];
|
||||
}
|
||||
|
||||
void AddVariable(IFuncVariable* var)
|
||||
{
|
||||
variables.push_back(var);
|
||||
}
|
||||
};
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Interface for CGeomCache class
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "smartptr.h" // TYPEDEF_AUTOPTR
|
||||
|
||||
// Summary:
|
||||
// Interface to hold geom cache data
|
||||
struct IGeomCache
|
||||
: public IStreamable
|
||||
{
|
||||
// Description:
|
||||
// Increase the reference count of the object.
|
||||
// Summary:
|
||||
// Notifies that the object is being used
|
||||
virtual int AddRef() = 0;
|
||||
|
||||
// Description:
|
||||
// Decrease the reference count of the object. If the reference count
|
||||
// reaches zero, the object will be deleted from memory.
|
||||
// Summary:
|
||||
// Notifies that the object is no longer needed
|
||||
virtual int Release() = 0;
|
||||
|
||||
// Description:
|
||||
// Checks if the geometry cache was successfully loaded from disk
|
||||
// Return Value:
|
||||
// True if valid, otherwise false
|
||||
virtual bool IsValid() const = 0;
|
||||
|
||||
// Description:
|
||||
// Set default material for the geometry.
|
||||
// Arguments:
|
||||
// pMaterial - A valid pointer to the material.
|
||||
virtual void SetMaterial(_smart_ptr<IMaterial> pMaterial) = 0;
|
||||
|
||||
// Description:
|
||||
// Returns default material of the geometry.
|
||||
// Arguments:
|
||||
// nType - Pass 0 to get the physic geometry or pass 1 to get the obstruct geometry
|
||||
// Return Value:
|
||||
// A pointer to a phys_geometry class.
|
||||
virtual _smart_ptr<IMaterial> GetMaterial() = 0;
|
||||
virtual const _smart_ptr<IMaterial> GetMaterial() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the filename of the object
|
||||
// Return Value:
|
||||
// A null terminated string which contain the filename of the object.
|
||||
virtual const char* GetFilePath() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the duration of the geom cache animation
|
||||
// Return value:
|
||||
// float value in seconds
|
||||
virtual float GetDuration() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Reloads the cache. Need to call this when cache file changed.
|
||||
virtual void Reload() = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns the max AABB of the geom cache through the whole animation
|
||||
// Return value:
|
||||
// The geom cache's max axis aligned bounding box
|
||||
virtual const AABB& GetAABB() const = 0;
|
||||
|
||||
/**
|
||||
* Tells the GeomCache whether or not it can release its static mesh data
|
||||
*
|
||||
* For the new AZ Geom Cache asset we have to be able
|
||||
* to tell the Geom Cache not to release loaded data.
|
||||
* This only matters when Geom Caches are not streamed.
|
||||
*
|
||||
* The legacy system works like this (if e_streamCGF is 0):
|
||||
* Load a geom cache entity.
|
||||
* Entity creates a geom cache render node.
|
||||
* Node loads geom cache, cache is marked as loaded.
|
||||
* Render node immediately initializes with the Geom Cache data.
|
||||
* Because the Geom Cache is not streamed, it releases unneeded data next tick
|
||||
*
|
||||
* The AZ system works like this:
|
||||
* Geom Cache component is created
|
||||
* Asset is requested
|
||||
* Asset loads Geom Cache
|
||||
* Geom Cache loads data and is marked as loaded
|
||||
* Asset calls AllowReleaseLoadedData(false) and locks loaded state
|
||||
* Tick happens and data is not freed (this is good, we need that data)
|
||||
* OnAssetReady event fires and is picked up by Geom Cache Component
|
||||
* Data is fed from the asset to the Geom Cache Render Node
|
||||
* Component calls AllowReleaseLoadedData(true)
|
||||
* Next tick the Geom Cache cleans up unneeded data
|
||||
*/
|
||||
virtual void SetProcessedByRenderNode(bool) = 0;
|
||||
|
||||
// Summary:
|
||||
// Returns statistics
|
||||
// Return value:
|
||||
// SStatistics struct
|
||||
struct SStatistics
|
||||
{
|
||||
bool m_bPlaybackFromMemory;
|
||||
float m_averageAnimationDataRate;
|
||||
uint m_numStaticMeshes;
|
||||
uint m_numStaticVertices;
|
||||
uint m_numStaticTriangles;
|
||||
uint m_numAnimatedMeshes;
|
||||
uint m_numAnimatedVertices;
|
||||
uint m_numAnimatedTriangles;
|
||||
uint m_numMaterials;
|
||||
uint m_staticDataSize;
|
||||
uint m_diskAnimationDataSize;
|
||||
uint m_memoryAnimationDataSize;
|
||||
};
|
||||
|
||||
virtual SStatistics GetStatistics() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IGeomCache() {}; // should be never called, use Release() instead
|
||||
};
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Possible errors for IImageFile::mfGet_error.
|
||||
*/
|
||||
enum EImFileError
|
||||
{
|
||||
eIFE_OK = 0, eIFE_IOerror, eIFE_OutOfMemory, eIFE_BadFormat, eIFE_ChunkNotFound
|
||||
};
|
||||
|
||||
// here are all of the flags that can be passed into the image load flags
|
||||
#define FIM_NORMALMAP 0x0001
|
||||
#define FIM_NOTSUPPORTS_MIPS 0x0004
|
||||
#define FIM_ALPHA 0x0008 // request attached alpha image
|
||||
#define FIM_DECAL 0x0010
|
||||
#define FIM_GREYSCALE 0x0020 // hint this texture is greyscale (could be DXT1 with colored artifacts)
|
||||
#define FIM_STREAM_PREPARE 0x0080
|
||||
#define FIM_UNUSED_BIT 0x0100 // Free to use
|
||||
#define FIM_BIG_ENDIANNESS 0x0400 // for textures converted to big endianness format
|
||||
#define FIM_SPLITTED 0x0800 // for dds textures stored in splitted files
|
||||
#define FIM_SRGB_READ 0x1000
|
||||
#define FIM_X360_NOT_PRETILED 0x2000 // for dds textures that cannot be pretiled
|
||||
#define FIM_UNUSED_BIT_1 0x4000 // Free to use
|
||||
#define FIM_RENORMALIZED_TEXTURE 0x8000 // for dds textures with EIF_RenormalizedTexture set in the dds header (not currently supported in the engine at runtime)
|
||||
#define FIM_HAS_ATTACHED_ALPHA 0x10000 // image has an attached alpha image
|
||||
#define FIM_SUPPRESS_DOWNSCALING 0x20000 // don't allow to drop mips when texture is non-streamable
|
||||
#define FIM_DX10IO 0x40000 // for dds textures with extended DX10+ header
|
||||
#define FIM_NOFALLBACKS 0x80000 // if the texture can't be loaded or is not found, do not replace it with a default 'not found' texture.
|
||||
|
||||
class IImageFile
|
||||
{
|
||||
public:
|
||||
virtual int AddRef() = 0;
|
||||
virtual int Release() = 0;
|
||||
|
||||
virtual const string& mfGet_filename () const = 0;
|
||||
|
||||
virtual int mfGet_width () const = 0;
|
||||
virtual int mfGet_height () const = 0;
|
||||
virtual int mfGet_depth () const = 0;
|
||||
virtual int mfGet_NumSides () const = 0;
|
||||
|
||||
virtual EImFileError mfGet_error () const = 0;
|
||||
|
||||
virtual byte* mfGet_image (const int nSide) = 0;
|
||||
virtual bool mfIs_image (const int nSide) const = 0;
|
||||
|
||||
virtual ETEX_Format mfGetFormat() const = 0;
|
||||
virtual ETEX_TileMode mfGetTileMode() const = 0;
|
||||
virtual int mfGet_numMips () const = 0;
|
||||
virtual int mfGet_numPersistentMips () const = 0;
|
||||
virtual int mfGet_Flags () const = 0;
|
||||
virtual const ColorF& mfGet_minColor () const = 0;
|
||||
virtual const ColorF& mfGet_maxColor () const = 0;
|
||||
virtual int mfGet_ImageSize() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~IImageFile() {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IIMAGE_H
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
#pragma once
|
||||
|
||||
|
||||
struct SMeshBakingMaterialParams
|
||||
{
|
||||
float rayLength;
|
||||
float rayIndent;
|
||||
bool bAlphaCutout;
|
||||
bool bIgnore;
|
||||
};
|
||||
|
||||
struct SMeshBakingInputParams
|
||||
{
|
||||
IStatObj* pCageMesh;
|
||||
IStatObj* pInputMesh;
|
||||
const SMeshBakingMaterialParams* pMaterialParams;
|
||||
ColorF defaultBackgroundColour;
|
||||
ColorF dilateMagicColour;
|
||||
int outputTextureWidth;
|
||||
int outputTextureHeight;
|
||||
int numMaterialParams;
|
||||
int nLodId;
|
||||
bool bDoDilationPass;
|
||||
bool bSmoothNormals;
|
||||
bool bSaveSpecular;
|
||||
_smart_ptr<IMaterial> pMaterial;
|
||||
};
|
||||
|
||||
struct SMeshBakingOutput
|
||||
{
|
||||
ITexture* ppOuputTexture[3];
|
||||
ITexture* ppIntermediateTexture[3];
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IMESHBAKING_H
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
struct IStreamable;
|
||||
struct SCheckOcclusionJobData;
|
||||
struct SCheckOcclusionOutput;
|
||||
class COctreeNode;
|
||||
struct IStatInstGroup;
|
||||
|
||||
namespace NAsyncCull
|
||||
{
|
||||
class CCullThread;
|
||||
}
|
||||
|
||||
// Inplace object for IStreamable* to cache StreamableMemoryContentSize
|
||||
struct SStreamAbleObject
|
||||
{
|
||||
explicit SStreamAbleObject(IStreamable* pObj, bool bUpdateMemUsage = true)
|
||||
: m_pObj(pObj)
|
||||
, fCurImportance(-1000.f)
|
||||
{
|
||||
if (pObj && bUpdateMemUsage)
|
||||
{
|
||||
m_nStreamableContentMemoryUsage = pObj->GetStreamableContentMemoryUsage();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nStreamableContentMemoryUsage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const SStreamAbleObject& rOther) const
|
||||
{
|
||||
return m_pObj == rOther.m_pObj;
|
||||
}
|
||||
|
||||
int GetStreamableContentMemoryUsage() const { return m_nStreamableContentMemoryUsage; }
|
||||
IStreamable* GetStreamAbleObject() const { return m_pObj; }
|
||||
uint32 GetLastDrawMainFrameId() const
|
||||
{
|
||||
return m_pObj->GetLastDrawMainFrameId();
|
||||
}
|
||||
float fCurImportance;
|
||||
private:
|
||||
IStreamable* m_pObj;
|
||||
int m_nStreamableContentMemoryUsage;
|
||||
};
|
||||
|
||||
struct SObjManPrecacheCamera
|
||||
{
|
||||
SObjManPrecacheCamera()
|
||||
: vPosition(ZERO)
|
||||
, vDirection(ZERO)
|
||||
, bbox(AABB::RESET)
|
||||
, fImportanceFactor(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Vec3 vPosition;
|
||||
Vec3 vDirection;
|
||||
AABB bbox;
|
||||
float fImportanceFactor;
|
||||
};
|
||||
|
||||
struct SObjManPrecachePoint
|
||||
{
|
||||
SObjManPrecachePoint()
|
||||
: nId(0)
|
||||
{
|
||||
}
|
||||
|
||||
int nId;
|
||||
CTimeValue expireTime;
|
||||
};
|
||||
|
||||
struct IObjManager
|
||||
{
|
||||
virtual ~IObjManager() {}
|
||||
|
||||
virtual void PreloadLevelObjects() = 0;
|
||||
virtual void UnloadObjects(bool bDeleteAll) = 0;
|
||||
virtual void CheckTextureReadyFlag() = 0;
|
||||
virtual void FreeStatObj(IStatObj* pObj) = 0;
|
||||
virtual _smart_ptr<IStatObj> GetDefaultCGF() = 0;
|
||||
|
||||
typedef std::vector< IDecalRenderNode* > DecalsToPrecreate;
|
||||
virtual DecalsToPrecreate& GetDecalsToPrecreate() = 0;
|
||||
virtual PodArray<SStreamAbleObject>& GetArrStreamableObjects() = 0;
|
||||
virtual PodArray<SObjManPrecacheCamera>& GetStreamPreCacheCameras() = 0;
|
||||
virtual PodArray<COctreeNode*>& GetArrStreamingNodeStack() = 0;
|
||||
virtual PodArray<SObjManPrecachePoint>& GetStreamPreCachePointDefs() = 0;
|
||||
|
||||
typedef std::map<string, IStatObj*, stl::less_stricmp<string> > ObjectsMap;
|
||||
virtual ObjectsMap& GetNameToObjectMap() = 0;
|
||||
|
||||
typedef std::set<IStatObj*> LoadedObjects;
|
||||
virtual LoadedObjects& GetLoadedObjects() = 0;
|
||||
|
||||
virtual Vec3 GetSunColor() = 0;
|
||||
virtual void SetSunColor(const Vec3& color) = 0;
|
||||
|
||||
virtual Vec3 GetSunAnimColor() = 0;
|
||||
virtual void SetSunAnimColor(const Vec3& color) = 0;
|
||||
|
||||
virtual float GetSunAnimSpeed() = 0;
|
||||
virtual void SetSunAnimSpeed(float sunAnimSpeed) = 0;
|
||||
|
||||
virtual AZ::u8 GetSunAnimPhase() = 0;
|
||||
virtual void SetSunAnimPhase(AZ::u8 sunAnimPhase) = 0;
|
||||
|
||||
virtual AZ::u8 GetSunAnimIndex() = 0;
|
||||
virtual void SetSunAnimIndex(AZ::u8 sunAnimIndex) = 0;
|
||||
|
||||
virtual float GetSSAOAmount() = 0;
|
||||
virtual void SetSSAOAmount(float amount) = 0;
|
||||
|
||||
virtual float GetSSAOContrast() = 0;
|
||||
virtual void SetSSAOContrast(float amount) = 0;
|
||||
|
||||
virtual SRainParams& GetRainParams() = 0;
|
||||
virtual SSnowParams& GetSnowParams() = 0;
|
||||
|
||||
virtual bool IsCameraPrecacheOverridden() = 0;
|
||||
virtual void SetCameraPrecacheOverridden(bool state) = 0;
|
||||
|
||||
virtual IStatObj* LoadNewCGF(IStatObj* pObject, int flagCloth, bool bUseStreaming, bool bForceBreakable, unsigned long nLoadingFlags, const char* normalizedFilename, const void* pData, int nDataSize, const char* originalFilename, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0;
|
||||
virtual IStatObj* LoadFromCacheNoRef(IStatObj* pObject, bool bUseStreaming, unsigned long nLoadingFlags, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0;
|
||||
|
||||
virtual IStatObj* AllocateStatObj() = 0;
|
||||
virtual IStatObj* LoadStatObjUnsafeManualRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0;
|
||||
virtual _smart_ptr<IStatObj> LoadStatObjAutoRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0;
|
||||
virtual void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount) = 0;
|
||||
virtual bool InternalDeleteObject(IStatObj* pObject) = 0;
|
||||
virtual void MakeShadowCastersList(CVisArea* pReceiverArea, const AABB& aabbReceiver, int dwAllowedTypes, int32 nRenderNodeFlags, Vec3 vLightPos, CDLight* pLight, ShadowMapFrustum* pFr, PodArray<struct SPlaneObject>* pShadowHull, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual int MakeStaticShadowCastersList(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int nMaxNodes, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void MakeDepthCubemapRenderItemList(CVisArea* pReceiverArea, const AABB& cubemapAABB, int renderNodeFlags, PodArray<struct IShadowCaster*>* objectsList, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void PrecacheStatObjMaterial(_smart_ptr<IMaterial> pMaterial, const float fEntDistance, IStatObj* pStatObj, bool bFullUpdate, bool bDrawNear) = 0;
|
||||
virtual void PrecacheStatObj(IStatObj* pStatObj, int nLod, const Matrix34A& statObjMatrix, _smart_ptr<IMaterial> pMaterial, float fImportance, float fEntDistance, bool bFullUpdate, bool bHighPriority) = 0;
|
||||
|
||||
virtual int GetLoadedObjectCount() = 0;
|
||||
|
||||
virtual uint16 CheckCachedNearestCubeProbe(IRenderNode* pEnt) = 0;
|
||||
virtual int16 GetNearestCubeProbe(IVisArea* pVisArea, const AABB& objBox, bool bSpecular = true) = 0;
|
||||
|
||||
virtual void RenderObject(IRenderNode* o, const AABB& objBox, float fEntDistance, EERType eERType, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
virtual void RenderDecalAndRoad(IRenderNode* pEnt, const AABB& objBox, float fEntDistance, bool nCheckOcclusion, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
virtual void RenderObjectDebugInfo(IRenderNode* pEnt, float fEntDistance, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void RenderAllObjectDebugInfo() = 0;
|
||||
virtual void RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance) = 0;
|
||||
virtual void RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt) = 0;
|
||||
|
||||
virtual float GetXYRadius(int nType, int nSID = DEFAULT_SID) = 0;
|
||||
virtual bool GetStaticObjectBBox(int nType, Vec3& vBoxMin, Vec3& vBoxMax, int nSID = DEFAULT_SID) = 0;
|
||||
|
||||
virtual IStatObj* GetStaticObjectByTypeID(int nTypeID, int nSID = DEFAULT_SID) = 0;
|
||||
virtual IStatObj* FindStaticObjectByFilename(const char* filename) = 0;
|
||||
|
||||
//virtual float GetBendingRandomFactor() = 0;
|
||||
virtual float GetGSMMaxDistance() const = 0;
|
||||
virtual void SetGSMMaxDistance(float value) = 0;
|
||||
|
||||
virtual int GetUpdateStreamingPrioriryRoundIdFast() = 0;
|
||||
virtual int GetUpdateStreamingPrioriryRoundId() = 0;
|
||||
virtual void IncrementUpdateStreamingPrioriryRoundIdFast(int amount) = 0;
|
||||
virtual void IncrementUpdateStreamingPrioriryRoundId(int amount) = 0;
|
||||
|
||||
virtual NAsyncCull::CCullThread& GetCullThread() = 0;
|
||||
|
||||
virtual void SetLockCGFResources(bool state) = 0;
|
||||
virtual bool IsLockCGFResources() = 0;
|
||||
|
||||
virtual bool IsBoxOccluded(const AABB& objBox, float fDistance, OcclusionTestClient* const __restrict pOcclTestVars, bool bIndoorOccludersOnly, EOcclusionObjectType eOcclusionObjectType, const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void AddDecalToRenderer(float fDistance, _smart_ptr<IMaterial> pMat, const uint8 sortPrio, Vec3 right, Vec3 up, const UCol& ucResCol, const uint8 uBlendType, const Vec3& vAmbientColor, Vec3 vPos, const int nAfterWater, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
|
||||
|
||||
virtual void RegisterForStreaming(IStreamable* pObj) = 0;
|
||||
virtual void UnregisterForStreaming(IStreamable* pObj) = 0;
|
||||
virtual void UpdateRenderNodeStreamingPriority(IRenderNode* pObj, float fEntDistance, float fImportanceFactor, bool bFullUpdate, const SRenderingPassInfo& passInfo, bool bHighPriority = false) = 0;
|
||||
|
||||
virtual void GetMemoryUsage(class ICrySizer* pSizer) const = 0;
|
||||
virtual void GetBandwidthStats(float* fBandwidthRequested) = 0;
|
||||
|
||||
virtual void ReregisterEntitiesInArea(Vec3 vBoxMin, Vec3 vBoxMax) = 0;
|
||||
virtual void UpdateObjectsStreamingPriority(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming(const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void ProcessObjectsStreaming_Impl(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming_Sort(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void ProcessObjectsStreaming_Release() = 0;
|
||||
virtual void ProcessObjectsStreaming_InitLoad(bool bSyncLoad) = 0;
|
||||
virtual void ProcessObjectsStreaming_Finish() = 0;
|
||||
|
||||
// time counters
|
||||
virtual bool IsAfterWater(const Vec3& vPos, const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void FreeNotUsedCGFs() = 0;
|
||||
virtual void MakeUnitCube() = 0;
|
||||
|
||||
virtual bool CheckOcclusion_TestAABB(const AABB& rAABB, float fEntDistance) = 0;
|
||||
virtual bool CheckOcclusion_TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) = 0;
|
||||
|
||||
virtual void PushIntoCullQueue(const SCheckOcclusionJobData& rCheckOcclusionData) = 0;
|
||||
virtual void PopFromCullQueue(SCheckOcclusionJobData* pCheckOcclusionData) = 0;
|
||||
|
||||
virtual void PushIntoCullOutputQueue(const SCheckOcclusionOutput& rCheckOcclusionOutput) = 0;
|
||||
virtual bool PopFromCullOutputQueue(SCheckOcclusionOutput* pCheckOcclusionOutput) = 0;
|
||||
|
||||
virtual void BeginCulling() = 0;
|
||||
virtual void RemoveCullJobProducer() = 0;
|
||||
virtual void AddCullJobProducer() = 0;
|
||||
|
||||
#ifndef _RELEASE
|
||||
virtual void CoverageBufferDebugDraw() = 0;
|
||||
#endif
|
||||
|
||||
virtual bool LoadOcclusionMesh(const char* pFileName) = 0;
|
||||
|
||||
virtual void ClearStatObjGarbage() = 0;
|
||||
virtual void CheckForGarbage(IStatObj* pObject) = 0;
|
||||
virtual void UnregisterForGarbage(IStatObj* pObject) = 0;
|
||||
|
||||
virtual int GetObjectLOD(const IRenderNode* pObj, float fDistance) = 0;
|
||||
virtual bool RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMat, _smart_ptr<IMaterial> pMat, Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest) = 0;
|
||||
virtual bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, _smart_ptr<IMaterial> pMat) = 0;
|
||||
virtual bool SphereRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const float fRadius, _smart_ptr<IMaterial> pMat) = 0;
|
||||
|
||||
virtual uint8 GetDissolveRef(float fDist, float fMaxViewDist) = 0;
|
||||
virtual float GetLodDistDissolveRef(SLodDistDissolveTransitionState* pState, float curDist, int nNewLod, const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual void CleanStreamingData() = 0;
|
||||
virtual IRenderMesh* GetRenderMeshBox() = 0;
|
||||
|
||||
virtual void PrepareCullbufferAsync(const CCamera& rCamera) = 0;
|
||||
virtual void BeginOcclusionCulling(const SRenderingPassInfo& passInfo) = 0;
|
||||
virtual void EndOcclusionCulling(bool waitForOcclusionJobCompletion = false) = 0;
|
||||
virtual void RenderBufferedRenderMeshes(const SRenderingPassInfo& passInfo) = 0;
|
||||
|
||||
virtual int GetListStaticTypesCount() = 0;
|
||||
virtual int GetListStaticTypesGroupCount(int typeId) = 0;
|
||||
virtual IStatInstGroup* GetIStatInstGroup(int typeId, int groupId) = 0;
|
||||
|
||||
virtual int IncrementNextPrecachePointId() = 0;
|
||||
};
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <Cry_Geo.h> // AABB
|
||||
|
||||
|
||||
/**
|
||||
* Represents a registered proximity trigger.
|
||||
*
|
||||
* Contains the id of the trigger, its bounds, and whether or not it's active.
|
||||
*/
|
||||
struct SProximityElement
|
||||
{
|
||||
AZ::EntityId id;
|
||||
AABB aabb;
|
||||
uint32 bActivated : 1;
|
||||
std::vector<SProximityElement*> inside;
|
||||
|
||||
using NarrowPassCheckFunction = AZStd::function<bool(const AZ::Vector3&)>;
|
||||
|
||||
// Can be used to do an optional narrow pass check on this proximity element
|
||||
NarrowPassCheckFunction m_narrowPassChecker;
|
||||
|
||||
SProximityElement()
|
||||
{
|
||||
id = AZ::EntityId(0);
|
||||
bActivated = 0;
|
||||
}
|
||||
~SProximityElement()
|
||||
{
|
||||
}
|
||||
bool AddInside(SProximityElement* elem)
|
||||
{
|
||||
// Sorted add.
|
||||
return stl::binary_insert_unique(inside, elem);
|
||||
}
|
||||
bool RemoveInside(SProximityElement* elem)
|
||||
{
|
||||
// sorted remove.
|
||||
return stl::binary_erase(inside, elem);
|
||||
}
|
||||
bool IsInside(SProximityElement* elem)
|
||||
{
|
||||
return std::binary_search(inside.begin(), inside.end(), elem);
|
||||
}
|
||||
|
||||
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bus for events dispatched by the proximity trigger system as triggered are
|
||||
* entered and exited by entities in the world.
|
||||
*/
|
||||
class ProximityTriggerEvents
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ebus Traits
|
||||
// ID'd on trigger entity Id
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::EntityId;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~ProximityTriggerEvents() {}
|
||||
|
||||
/// Dispatched when an entity enters a trigger. The bus message is ID'd on the triggers entity Id.
|
||||
virtual void OnTriggerEnter(AZ::EntityId /*entityEntering*/) {};
|
||||
|
||||
/// Dispatched when an entity exits a trigger. The bus message is ID'd on the triggers entity Id.
|
||||
virtual void OnTriggerExit(AZ::EntityId /*entityExiting*/) {};
|
||||
};
|
||||
|
||||
using ProximityTriggerEventBus = AZ::EBus<ProximityTriggerEvents>;
|
||||
|
||||
/**
|
||||
* Bus for requests sent by components or game code to the proximity trigger system.
|
||||
*/
|
||||
class ProximityTriggerSystemRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides - proximity trigger system is a singleton
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual ~ProximityTriggerSystemRequests() {}
|
||||
|
||||
/// Creates a new trigger instance.
|
||||
virtual SProximityElement* CreateTrigger(SProximityElement::NarrowPassCheckFunction narrowPassChecker = nullptr) = 0;
|
||||
|
||||
/// Removes a trigger and queues it for deletion.
|
||||
virtual void RemoveTrigger(SProximityElement* pTrigger) = 0;
|
||||
|
||||
/// Moves a trigger in the world or redefines its dimensions.
|
||||
virtual void MoveTrigger(SProximityElement* pTrigger, const AABB& aabb, bool invalidateCachedAABB = false) = 0;
|
||||
|
||||
/// Creates a proxy in the world associated with an entity (Component or Legacy) for interacting with proximity trigger instances.
|
||||
virtual SProximityElement* CreateEntity(AZ::EntityId id) = 0;
|
||||
|
||||
/**
|
||||
* Set the entity's AABB to a unit AABB at the entity's world position if \aabb is empty, otherwise set the entity's AABB to \aabb
|
||||
* @param pEntity The pointer to a SProximityElment whose AABB needs to be updated
|
||||
* @param pos World position of the entity
|
||||
* @param aabb The new AABB in world space to set
|
||||
*/
|
||||
virtual void MoveEntity(SProximityElement* pEntity, const Vec3& pos, const AABB& aabb) = 0;
|
||||
|
||||
/// Removes an entity's proximity trigger proxy.
|
||||
virtual void RemoveEntity(SProximityElement* pEntity, bool instantEvent = false) = 0;
|
||||
};
|
||||
|
||||
using ProximityTriggerSystemRequestBus = AZ::EBus<ProximityTriggerSystemRequests>;
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H
|
||||
@@ -16,7 +16,12 @@
|
||||
#include "Cry_Geo.h"
|
||||
#include "Cry_Camera.h"
|
||||
#include "ITexture.h"
|
||||
#include <IFuncVariable.h> // <> required for Interfuscator
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
#include <IXml.h> // <> required for Interfuscator
|
||||
#include "smartptr.h"
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
@@ -99,7 +104,6 @@ struct ShadowFrustumMGPUCache;
|
||||
struct IAsyncTextureCompileListener;
|
||||
struct IClipVolume;
|
||||
struct SClipVolumeBlendInfo;
|
||||
class IImageFile;
|
||||
class CRenderView;
|
||||
struct SDynTexture2;
|
||||
class CTexture;
|
||||
@@ -693,7 +697,6 @@ public:
|
||||
#include <IShader.h> // <> required for Interfuscator
|
||||
//DOC-IGNORE-END
|
||||
#include <IRenderMesh.h>
|
||||
#include "IMeshBaking.h"
|
||||
|
||||
// Flags passed in function FreeResources.
|
||||
#define FRR_SHADERS 1
|
||||
@@ -1051,11 +1054,6 @@ namespace AZ {
|
||||
namespace Vertex {
|
||||
class Format;
|
||||
}
|
||||
namespace VideoRenderer
|
||||
{
|
||||
struct IVideoRenderer;
|
||||
struct DrawArguments;
|
||||
}
|
||||
}
|
||||
enum eRenderPrimitiveType : int8;
|
||||
enum RenderIndexType : int;
|
||||
@@ -1464,7 +1462,6 @@ struct IRenderer
|
||||
// Is threadsafe
|
||||
virtual bool EF_ReloadFile_Request (const char* szFileName) = 0;
|
||||
|
||||
virtual _smart_ptr<IImageFile> EF_LoadImage(const char* szFileName, uint32 nFlags) = 0;
|
||||
// Summary:
|
||||
// Remaps shader gen mask to common global mask.
|
||||
virtual uint64 EF_GetRemapedShaderMaskGen(const char* name, uint64 nMaskGen = 0, bool bFixup = 0) = 0;
|
||||
@@ -1739,8 +1736,6 @@ struct IRenderer
|
||||
virtual void RemoveTexture(unsigned int TextureId) = 0;
|
||||
virtual void DeleteFont(IFFont* font) = 0;
|
||||
|
||||
virtual bool BakeMesh(const SMeshBakingInputParams* pInputParams, SMeshBakingOutput* pReturnValues) = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This routines uses 2 destination surfaces. It triggers a backbuffer copy to one of its surfaces,
|
||||
// and then copies the other surface to system memory. This hopefully will remove any
|
||||
@@ -2346,11 +2341,6 @@ struct IRenderer
|
||||
virtual void EndProfilerSection(const char* name) = 0;
|
||||
virtual void AddProfilerLabel(const char* name) = 0;
|
||||
|
||||
// Video Renderer interface
|
||||
virtual void InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0;
|
||||
virtual void CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0;
|
||||
virtual void DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) = 0;
|
||||
|
||||
private:
|
||||
// use private for EF_Query to prevent client code to submit arbitrary combinations of output data/size
|
||||
virtual void EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1) = 0;
|
||||
|
||||
@@ -24,7 +24,12 @@
|
||||
#endif
|
||||
|
||||
#include "smartptr.h"
|
||||
#include <IFuncVariable.h> // <> required for Interfuscator
|
||||
#include "Cry_Vector2.h"
|
||||
#include "Cry_Vector3.h"
|
||||
#include "Cry_Matrix33.h"
|
||||
#include "Cry_Color.h"
|
||||
#include "smartptr.h"
|
||||
#include "StringUtils.h"
|
||||
#include <IXml.h> // <> required for Interfuscator
|
||||
#include "smartptr.h"
|
||||
#include "VertexFormats.h"
|
||||
@@ -767,7 +772,6 @@ _MS_ALIGN(16) struct SSkinningData
|
||||
void* pCharInstCB; // used if per char instance cbs are available in renderdll (d3d11+);
|
||||
// members below are for Software Skinning
|
||||
void* pCustomData; // client specific data, used for example for sw-skinning on animation side
|
||||
SSkinningData** pMasterSkinningDataList; // used by the SkinningData for a Character Instance, contains a list of all Skin Instances which need SW-Skinning
|
||||
SSkinningData* pNextSkinningData; // List to the next element which needs SW-Skinning
|
||||
} _ALIGN(16);
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <IShader.h> // <> required for Interfuscator
|
||||
|
||||
// Traits
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(IShader_info_h)
|
||||
#elif !defined(LINUX) && !defined(APPLE)
|
||||
#define ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO 1
|
||||
#endif
|
||||
|
||||
#if ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO
|
||||
ENUM_INFO_BEGIN(ETEX_Format)
|
||||
ENUM_ELEM_INFO(, eTF_Unknown)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8B8A8S)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8B8A8)
|
||||
ENUM_ELEM_INFO(, eTF_A8)
|
||||
ENUM_ELEM_INFO(, eTF_R8)
|
||||
ENUM_ELEM_INFO(, eTF_R8S)
|
||||
ENUM_ELEM_INFO(, eTF_R16)
|
||||
ENUM_ELEM_INFO(, eTF_R16F)
|
||||
ENUM_ELEM_INFO(, eTF_R32F)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8)
|
||||
ENUM_ELEM_INFO(, eTF_R8G8S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16F)
|
||||
ENUM_ELEM_INFO(, eTF_R11G11B10F)
|
||||
ENUM_ELEM_INFO(, eTF_R10G10B10A2)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16S)
|
||||
ENUM_ELEM_INFO(, eTF_R16G16B16A16F)
|
||||
ENUM_ELEM_INFO(, eTF_R32G32B32A32F)
|
||||
ENUM_ELEM_INFO(, eTF_CTX1)
|
||||
ENUM_ELEM_INFO(, eTF_BC1)
|
||||
ENUM_ELEM_INFO(, eTF_BC2)
|
||||
ENUM_ELEM_INFO(, eTF_BC3)
|
||||
ENUM_ELEM_INFO(, eTF_BC4U)
|
||||
ENUM_ELEM_INFO(, eTF_BC4S)
|
||||
ENUM_ELEM_INFO(, eTF_BC5U)
|
||||
ENUM_ELEM_INFO(, eTF_BC5S)
|
||||
ENUM_ELEM_INFO(, eTF_BC6UH)
|
||||
ENUM_ELEM_INFO(, eTF_BC6SH)
|
||||
ENUM_ELEM_INFO(, eTF_BC7)
|
||||
ENUM_ELEM_INFO(, eTF_R9G9B9E5)
|
||||
ENUM_ELEM_INFO(, eTF_D16)
|
||||
ENUM_ELEM_INFO(, eTF_D24S8)
|
||||
ENUM_ELEM_INFO(, eTF_D32F)
|
||||
ENUM_ELEM_INFO(, eTF_D32FS8)
|
||||
ENUM_ELEM_INFO(, eTF_B5G6R5)
|
||||
ENUM_ELEM_INFO(, eTF_B5G5R5)
|
||||
ENUM_ELEM_INFO(, eTF_B4G4R4A4)
|
||||
ENUM_ELEM_INFO(, eTF_EAC_R11)
|
||||
ENUM_ELEM_INFO(, eTF_EAC_RG11)
|
||||
ENUM_ELEM_INFO(, eTF_ETC2)
|
||||
ENUM_ELEM_INFO(, eTF_ETC2A)
|
||||
ENUM_ELEM_INFO(, eTF_A8L8)
|
||||
ENUM_ELEM_INFO(, eTF_L8)
|
||||
ENUM_ELEM_INFO(, eTF_L8V8U8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8)
|
||||
ENUM_ELEM_INFO(, eTF_L8V8U8X8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8X8)
|
||||
ENUM_ELEM_INFO(, eTF_B8G8R8A8)
|
||||
ENUM_INFO_END(ETEX_Format)
|
||||
#endif
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ITexture.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
// General purpose video 'rendering' solution that abstracts video data into textures
|
||||
// and data to update those textures with.
|
||||
namespace VideoRenderer
|
||||
{
|
||||
enum Constants
|
||||
{
|
||||
MaxInputTextureCount = 4,
|
||||
};
|
||||
|
||||
struct VideoTextureDesc
|
||||
{
|
||||
CryFixedStringT<64> m_name; // fixed string to avoid dll string copying issues
|
||||
uint32 m_width{ 4 };
|
||||
uint32 m_height{ 4 };
|
||||
ETEX_Format m_format{ eTF_Unknown };
|
||||
uint32 m_used{ 0 };
|
||||
};
|
||||
|
||||
// Full description of video texture resources for the renderer to create.
|
||||
struct VideoTexturesDesc
|
||||
{
|
||||
VideoTextureDesc m_outputTextureDesc;
|
||||
VideoTextureDesc m_inputTextureDescs[MaxInputTextureCount];
|
||||
};
|
||||
|
||||
// Full set of textures created from the VideoTexturesDesc provided to the renderer.
|
||||
struct VideoTextures
|
||||
{
|
||||
uint32 m_outputTextureId{ 0 };
|
||||
uint32 m_inputTextureIds[MaxInputTextureCount]{ 0 };
|
||||
};
|
||||
|
||||
struct VideoUpdateData
|
||||
{
|
||||
struct VideoTextureUpdateData
|
||||
{
|
||||
// Data to update the texture with, can be null.
|
||||
const void* m_data{ nullptr };
|
||||
|
||||
// Format of above data, required for format conversions if needed.
|
||||
ETEX_Format m_dataFormat{ eTF_Unknown };
|
||||
}
|
||||
m_inputTextureData[MaxInputTextureCount];
|
||||
};
|
||||
|
||||
// Set of data to update and render a frame of video textures.
|
||||
// Everything should be passed through by value except for the update data, which should be double buffered at the source.
|
||||
struct DrawArguments
|
||||
{
|
||||
// Set of textures to draw with.
|
||||
VideoTextures m_textures;
|
||||
|
||||
// Set of data to update the above textures with if set.
|
||||
VideoUpdateData m_updateData;
|
||||
|
||||
// Flag to indicate that we want to draw to the backbuffer.
|
||||
uint32 m_drawingToBackbuffer{ 0 };
|
||||
|
||||
// Payload information for reference. Useful for debugging.
|
||||
uint32 m_frameReference{ 0 };
|
||||
|
||||
// Scale applied to each texture.
|
||||
Vec4 m_textureScales[MaxInputTextureCount]{};
|
||||
|
||||
// Value added to final composited texture.
|
||||
Vec4 m_colorAdjustment{ ZERO };
|
||||
};
|
||||
|
||||
// Video Rendering interface to provide callbacks from the Render Thread
|
||||
struct IVideoRenderer
|
||||
{
|
||||
// Called from the Render Thread to request the description of the video textures.
|
||||
virtual bool GetVideoTexturesDesc(AZ::VideoRenderer::VideoTexturesDesc& videoTexturesDesc) const = 0;
|
||||
// Called from the Render Thread to get the set of video textures that were previously created. Used at cleanup time.
|
||||
virtual bool GetVideoTextures(AZ::VideoRenderer::VideoTextures& videoTextures) const = 0;
|
||||
|
||||
// Called from the Render Thread to provide the video textures it created from the VideoTexturesDesc.
|
||||
virtual bool NotifyTexturesCreated(const AZ::VideoRenderer::VideoTextures& videoTextures) = 0;
|
||||
// CAlled from the Render Thread to notify the video manager that its textures were destroyed.
|
||||
virtual bool NotifyTexturesDestroyed() = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Helper to enable inplace construction and destruction of objects
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
// Inspired by the boost inplace/typed_inplace factory, written by
|
||||
// Fernando Luis Cacciola Carballal and Tobias Schwinger
|
||||
//
|
||||
// See
|
||||
// http://www.boost.org/doc/libs/1_42_0/libs/utility/in_place_factories.html
|
||||
// for a detailed description
|
||||
//
|
||||
|
||||
class CInplaceFactory0
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory0()
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template < typename Arg0 >
|
||||
class CInplaceFactory1
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory1(Arg0& arg)
|
||||
: m_Arg0(arg)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(m_Arg0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1
|
||||
>
|
||||
class CInplaceFactory2
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory2(Arg0& arg0, Arg1& arg1)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2
|
||||
>
|
||||
class CInplaceFactory3
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory3(Arg0& arg0, Arg1& arg1, Arg2& arg2)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3
|
||||
>
|
||||
class CInplaceFactory4
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
Arg3& m_Arg3;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory4(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
, m_Arg3(arg3)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2,
|
||||
m_Arg3);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3,
|
||||
typename Arg4
|
||||
>
|
||||
class CInplaceFactory5
|
||||
{
|
||||
Arg0& m_Arg0;
|
||||
Arg1& m_Arg1;
|
||||
Arg2& m_Arg2;
|
||||
Arg3& m_Arg3;
|
||||
Arg4& m_Arg4;
|
||||
|
||||
public:
|
||||
|
||||
explicit CInplaceFactory5(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4)
|
||||
: m_Arg0(arg0)
|
||||
, m_Arg1(arg1)
|
||||
, m_Arg2(arg2)
|
||||
, m_Arg3(arg3)
|
||||
, m_Arg4(arg4)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address) const
|
||||
{
|
||||
return new(address) T(
|
||||
m_Arg0,
|
||||
m_Arg1,
|
||||
m_Arg2,
|
||||
m_Arg3,
|
||||
m_Arg4);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void* apply(void* address, std::size_t n) const
|
||||
{
|
||||
for (char* next = address = this->template apply<T>(address); !!--n; )
|
||||
{
|
||||
this->template apply<T>(next = next + sizeof(T));
|
||||
}
|
||||
return address;
|
||||
}
|
||||
};
|
||||
|
||||
inline CInplaceFactory0 InplaceFactory()
|
||||
{
|
||||
return CInplaceFactory0();
|
||||
}
|
||||
|
||||
template < typename Arg0 >
|
||||
inline CInplaceFactory1<Arg0> InplaceFactory(Arg0& arg0)
|
||||
{
|
||||
return CInplaceFactory1<Arg0>(arg0);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1
|
||||
|
||||
>
|
||||
inline CInplaceFactory2<Arg0, Arg1> InplaceFactory(Arg0& arg0, Arg1& arg1)
|
||||
{
|
||||
return CInplaceFactory2<Arg0, Arg1>(arg0, arg1);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2
|
||||
>
|
||||
inline CInplaceFactory3<Arg0, Arg1, Arg2> InplaceFactory(Arg0& arg0, Arg1& arg1, Arg2& arg2)
|
||||
{
|
||||
return CInplaceFactory3<Arg0, Arg1, Arg2> (arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3
|
||||
>
|
||||
inline CInplaceFactory4<Arg0, Arg1, Arg2, Arg3> InplaceFactory(
|
||||
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3)
|
||||
{
|
||||
return CInplaceFactory4<Arg0, Arg1, Arg2, Arg3>(arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Arg0,
|
||||
typename Arg1,
|
||||
typename Arg2,
|
||||
typename Arg3,
|
||||
typename Arg4
|
||||
>
|
||||
inline CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4> InplaceFactory(
|
||||
Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4)
|
||||
{
|
||||
return CInplaceFactory5<Arg0, Arg1, Arg2, Arg3, Arg4>(arg0, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
#define CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h> // for max path len
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
namespace MaterialUtils
|
||||
{
|
||||
//! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes
|
||||
//! and fix up any legacy naming issues so that the material name can be used in a hash map
|
||||
//! and will work each lookup.
|
||||
inline void UnifyMaterialName(char* inputOutputBuffer)
|
||||
{
|
||||
if (!inputOutputBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// convert slashes and remove extensions:
|
||||
size_t inputLength = strlen(inputOutputBuffer);
|
||||
if (inputLength == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// this must be done first, so that the extension cutting function below does not mistakenly destroy this when it finds the .
|
||||
if ((azstrnicmp(inputOutputBuffer, "./", 2) == 0) || (azstrnicmp(inputOutputBuffer, ".\\", 2) == 0))
|
||||
{
|
||||
memmove(inputOutputBuffer, inputOutputBuffer + 2, inputLength - 2);
|
||||
inputOutputBuffer[inputLength - 2] = 0;
|
||||
inputLength -= 2;
|
||||
}
|
||||
|
||||
for (size_t pos = 0; pos < inputLength; ++pos)
|
||||
{
|
||||
if (inputOutputBuffer[pos] == '\\')
|
||||
{
|
||||
inputOutputBuffer[pos] = '/'; // unify slashes
|
||||
}
|
||||
else
|
||||
{
|
||||
inputOutputBuffer[pos] = tolower(inputOutputBuffer[pos]);
|
||||
}
|
||||
}
|
||||
AZStd::string tempString(inputOutputBuffer);
|
||||
AzFramework::StringFunc::Path::StripExtension(tempString);
|
||||
|
||||
AZ_Assert(tempString.length() <= inputLength, "Extension stripped string has to be smaller than/same size as original string!");
|
||||
// real size of inputOutputBuffer is inputLength + 1 with Null character
|
||||
azstrcpy(inputOutputBuffer, inputLength + 1, tempString.c_str());
|
||||
#if defined(SUPPORT_LEGACY_MATERIAL_NAMES)
|
||||
|
||||
// LEGACY support Some files may start with ./ in front of them. This is not required anymore.
|
||||
static const char* removals[2] = {
|
||||
"engine/",
|
||||
nullptr // reserved for game name
|
||||
};
|
||||
static size_t removalSize = sizeof(removals) / sizeof(removals[0]);
|
||||
|
||||
// LEGACY support. Some files may start with gamename in front of them. This is not required anymore.
|
||||
static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 };
|
||||
if (!removals[removalSize - 1])
|
||||
{
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
if (!projectName.empty())
|
||||
{
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str());
|
||||
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
|
||||
}
|
||||
|
||||
if (cachedGameName[0] == 0)
|
||||
{
|
||||
// at least substitute something so that unit tests can make this assumption:
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "AutomatedTesting/");
|
||||
}
|
||||
|
||||
removals[removalSize - 1] = cachedGameName;
|
||||
}
|
||||
|
||||
for (size_t pos = 0; pos < removalSize; ++pos)
|
||||
{
|
||||
if (removals[pos])
|
||||
{
|
||||
size_t removalLength = strlen(removals[pos]);
|
||||
if (removalLength >= inputLength)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (azstrnicmp(inputOutputBuffer, removals[pos], removalLength) == 0)
|
||||
{
|
||||
memmove(inputOutputBuffer, inputOutputBuffer + removalLength, inputLength - removalLength);
|
||||
inputOutputBuffer[inputLength - removalLength] = 0;
|
||||
inputLength -= removalLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// legacy: Files were saved into a mtl with many leading forward or back slashes, we eat them all here. We want it to start with a rel path.
|
||||
const char* actualFileName = inputOutputBuffer;
|
||||
size_t finalLength = inputLength;
|
||||
while ((actualFileName[0]) && ((actualFileName[0] == '\\') || (actualFileName[0] == '/')))
|
||||
{
|
||||
++actualFileName;
|
||||
--finalLength;
|
||||
}
|
||||
if (finalLength != inputLength)
|
||||
{
|
||||
memmove(inputOutputBuffer, actualFileName, finalLength);
|
||||
inputOutputBuffer[finalLength] = 0;
|
||||
inputLength = finalLength;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H
|
||||
@@ -12,8 +12,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <IRenderer.h>
|
||||
#include <IVideoRenderer.h>
|
||||
#include <IImage.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
struct SRendItemSorter {};
|
||||
@@ -294,8 +292,6 @@ public:
|
||||
bool(const char* szFileName));
|
||||
MOCK_METHOD1(EF_ReloadFile_Request,
|
||||
bool(const char* szFileName));
|
||||
MOCK_METHOD2(EF_LoadImage,
|
||||
_smart_ptr<IImageFile>(const char* szFileName, uint32 nFlags));
|
||||
MOCK_METHOD3(EF_GetRemapedShaderMaskGen,
|
||||
uint64(const char*, uint64, bool));
|
||||
MOCK_METHOD3(EF_GetShaderGlobalMaskGenFromString,
|
||||
@@ -533,8 +529,6 @@ public:
|
||||
void(unsigned int TextureId));
|
||||
MOCK_METHOD1(DeleteFont,
|
||||
void(IFFont * font));
|
||||
MOCK_METHOD2(BakeMesh,
|
||||
bool(const SMeshBakingInputParams * pInputParams, SMeshBakingOutput * pReturnValues));
|
||||
MOCK_METHOD3(CaptureFrameBufferFast,
|
||||
bool(unsigned char* pDstRGBA8, int destinationWidth, int destinationHeight));
|
||||
MOCK_METHOD3(CopyFrameBufferFast,
|
||||
@@ -857,13 +851,6 @@ public:
|
||||
MOCK_METHOD1(AddProfilerLabel,
|
||||
void(const char*));
|
||||
|
||||
MOCK_METHOD1(InitializeVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer));
|
||||
MOCK_METHOD1(CleanupVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer));
|
||||
MOCK_METHOD2(DrawVideoRenderer,
|
||||
void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments));
|
||||
|
||||
MOCK_METHOD5(EF_QueryImpl,
|
||||
void(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1));
|
||||
};
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
#define CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
#pragma once
|
||||
|
||||
#include "CryName.h"
|
||||
|
||||
// CCryName TypeInfo
|
||||
|
||||
TYPE_INFO_BASIC(CCryName)
|
||||
|
||||
string ToString(CCryName const& val)
|
||||
{
|
||||
return string(val.c_str());
|
||||
}
|
||||
bool FromString(CCryName& val, const char* s)
|
||||
{
|
||||
val = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
|
||||
// Water level unknown.
|
||||
#define WATER_LEVEL_UNKNOWN -1000000.f
|
||||
#define BOTTOM_LEVEL_UNKNOWN -1000000.f
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
/**
|
||||
* Numeric constants that the editors should use for the ocean properties
|
||||
*/
|
||||
namespace OceanConstants
|
||||
{
|
||||
// Ocean Height consts are maintained for backwards compatibility
|
||||
// @TODO: Remove height / depth related consts when feature toggle is removed.
|
||||
static const float s_HeightMin = -AZ::Constants::MaxFloatBeforePrecisionLoss;
|
||||
static const float s_HeightMax = AZ::Constants::MaxFloatBeforePrecisionLoss;
|
||||
static const float s_HeightUnknown = WATER_LEVEL_UNKNOWN;
|
||||
static const float s_BottomUnknown = BOTTOM_LEVEL_UNKNOWN;
|
||||
static const float s_DefaultHeight = 16.0f;
|
||||
|
||||
static const float s_CausticsDistanceAttenMin = 0.0f;
|
||||
static const float s_CausticsDistanceAttenDefault = 10.0f;
|
||||
static const float s_CausticsDistanceAttenMax = 100.0f;
|
||||
static const float s_CausticsDepthMin = 0.0f;
|
||||
static const float s_CausticsDepthDefault = 8.0f;
|
||||
static const float s_CausticsDepthMax = 100.0f;
|
||||
static const float s_CausticsIntensityMin = 0.0f;
|
||||
static const float s_CausticsIntensityDefault = 1.0f;
|
||||
static const float s_CausticsIntensityMax = 10.0f;
|
||||
static const float s_CausticsTilingMin = 0.10f;
|
||||
static const float s_CausticsTilingDefault = 2.0f;
|
||||
static const float s_CausticsTilingMax = 10.0f;
|
||||
|
||||
static const float s_animationWavesAmountMin = 0.2f;
|
||||
static const float s_animationWavesAmountMax = 5.0f;
|
||||
static const float s_animationWavesAmountDefault = 0.75f;
|
||||
static const float s_animationWavesSizeMin = 0.0f;
|
||||
static const float s_animationWavesSizeMax = 3.0f;
|
||||
static const float s_animationWavesSizeDefault = 1.25f;
|
||||
static const float s_animationWavesSpeedMin = 0.0f;
|
||||
static const float s_animationWavesSpeedMax = 5.0f;
|
||||
static const float s_animationWavesSpeedDefault = 1.0f;
|
||||
static const float s_animationWindDirectionMin = 0.0f;
|
||||
static const float s_animationWindDirectionMax = 6.2832f;
|
||||
static const float s_animationWindDirectionDefault = 1;
|
||||
static const float s_animationWindSpeedMin = 0.0f;
|
||||
static const float s_animationWindSpeedMax = 1000.0f;
|
||||
static const float s_animationWindSpeedDefault = 40.0f;
|
||||
|
||||
static const AZ::Color s_oceanFogColorDefault((AZ::u8)5, (AZ::u8)36, (AZ::u8)32, (AZ::u8)255);
|
||||
static const AZ::Color s_oceanNearFogColorDefault((AZ::u8)1, (AZ::u8)7, (AZ::u8)5, (AZ::u8)255);
|
||||
static const float s_oceanFogColorMultiplierDefault = 0.15f;
|
||||
static const float s_oceanFogDensityDefault = 0.07f;
|
||||
static const float s_OceanFogColorMultiplierMin = 0.0f;
|
||||
static const float s_OceanFogColorMultiplierMax = 1.0f;
|
||||
static const float s_OceanFogDensityMin = 0.0f;
|
||||
static const float s_OceanFogDensityMax = 1.0f;
|
||||
|
||||
static const int s_waterTessellationAmountMin = 10;
|
||||
static const int s_waterTessellationAmountMax = 500;
|
||||
static const int s_waterTessellationDefault = 85;
|
||||
|
||||
static const bool s_UseOceanBottom = true;
|
||||
|
||||
static const bool s_GodRaysEnabled = true;
|
||||
static const float s_UnderwaterDistortion = 1.0f;
|
||||
|
||||
static const float s_oceanIsVeryFarAway = 1000000.f;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,363 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
//! Everybody should use fxopen instead of fopen so it opens on all platforms
|
||||
inline AZ::IO::HandleType fxopen(const char* file, const char* mode, bool bGameRelativePath = false)
|
||||
{
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
gEnv->pCryPak->CheckFileAccessDisabled(file, mode);
|
||||
}
|
||||
bool bWriteAccess = false;
|
||||
for (const char* s = mode; *s; s++)
|
||||
{
|
||||
if (*s == 'w' || *s == 'W' || *s == 'a' || *s == 'A' || *s == '+')
|
||||
{
|
||||
bWriteAccess = true;
|
||||
break;
|
||||
}
|
||||
;
|
||||
}
|
||||
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
int nAdjustFlags = 0;
|
||||
if (!bGameRelativePath)
|
||||
{
|
||||
nAdjustFlags |= AZ::IO::IArchive::FLAGS_PATH_REAL;
|
||||
}
|
||||
if (bWriteAccess)
|
||||
{
|
||||
nAdjustFlags |= AZ::IO::IArchive::FLAGS_FOR_WRITING;
|
||||
}
|
||||
char path[_MAX_PATH];
|
||||
const char* szAdjustedPath = gEnv->pCryPak->AdjustFileName(file, path, AZ_ARRAY_SIZE(path), nAdjustFlags);
|
||||
|
||||
#if !AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM
|
||||
if (bWriteAccess)
|
||||
{
|
||||
// Make sure folder is created.
|
||||
gEnv->pCryPak->MakeDir(szAdjustedPath);
|
||||
}
|
||||
#endif
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
AZ::IO::FileIOBase::GetInstance()->Open(szAdjustedPath, AZ::IO::GetOpenModeFromStringMode(mode), fileHandle);
|
||||
return fileHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::IO::InvalidHandle;
|
||||
}
|
||||
}
|
||||
|
||||
class CDebugAllowFileAccess
|
||||
{
|
||||
public:
|
||||
#if defined(_RELEASE)
|
||||
ILINE CDebugAllowFileAccess() { }
|
||||
ILINE void End() { }
|
||||
#else
|
||||
CDebugAllowFileAccess()
|
||||
{
|
||||
m_threadId = AZStd::this_thread::get_id();
|
||||
m_oldDisable = gEnv->pCryPak ? gEnv->pCryPak->DisableRuntimeFileAccess(false, m_threadId) : false;
|
||||
m_active = true;
|
||||
}
|
||||
~CDebugAllowFileAccess()
|
||||
{
|
||||
End();
|
||||
}
|
||||
void End()
|
||||
{
|
||||
if (m_active)
|
||||
{
|
||||
if (gEnv && gEnv->pCryPak)
|
||||
{
|
||||
gEnv->pCryPak->DisableRuntimeFileAccess(m_oldDisable, m_threadId);
|
||||
}
|
||||
m_active = false;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
AZStd::thread_id m_threadId;
|
||||
bool m_oldDisable;
|
||||
bool m_active;
|
||||
#endif
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class CInMemoryFileLoader
|
||||
{
|
||||
public:
|
||||
CInMemoryFileLoader(AZ::IO::IArchive* pCryPak)
|
||||
: m_pPak(pCryPak)
|
||||
, m_fileHandle(AZ::IO::InvalidHandle)
|
||||
, m_pBuffer(0)
|
||||
, m_pCursor(0)
|
||||
, m_nFileSize(0) {}
|
||||
~CInMemoryFileLoader()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool IsFileExists() const
|
||||
{
|
||||
return m_fileHandle != AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
AZ::IO::HandleType GetFileHandle() const
|
||||
{
|
||||
return m_fileHandle;
|
||||
}
|
||||
|
||||
bool FOpen(const char* name, const char* mode, bool bImmediateCloseFile = false)
|
||||
{
|
||||
if (m_pPak)
|
||||
{
|
||||
assert(m_fileHandle == AZ::IO::InvalidHandle);
|
||||
m_fileHandle = m_pPak->FOpen(name, mode);
|
||||
if (m_fileHandle == AZ::IO::InvalidHandle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_nFileSize = m_pPak->FGetSize(m_fileHandle);
|
||||
if (m_nFileSize == 0)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pCursor = m_pBuffer = (char*)m_pPak->PoolMalloc(m_nFileSize);
|
||||
|
||||
size_t nReaded = m_pPak->FReadRawAll(m_pBuffer, m_nFileSize, m_fileHandle);
|
||||
if (nReaded != m_nFileSize)
|
||||
{
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bImmediateCloseFile)
|
||||
{
|
||||
m_pPak->FClose(m_fileHandle);
|
||||
m_fileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FClose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
size_t FReadRaw(void* data, size_t length, size_t elems)
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
|
||||
size_t count = length;
|
||||
if (dist + count * elems > m_nFileSize)
|
||||
{
|
||||
count = (m_nFileSize - dist) / elems;
|
||||
}
|
||||
|
||||
memmove(data, m_pCursor, count * elems);
|
||||
m_pCursor += count * elems;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
size_t FRead(T* data, size_t elems, bool bSwapEndian = eLittleEndian)
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
|
||||
size_t count = elems;
|
||||
if (dist + count * sizeof(T) > m_nFileSize)
|
||||
{
|
||||
count = (m_nFileSize - dist) / sizeof(T);
|
||||
}
|
||||
|
||||
memmove(data, m_pCursor, count * sizeof(T));
|
||||
m_pCursor += count * sizeof(T);
|
||||
|
||||
SwapEndian(data, count, bSwapEndian);
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t FTell()
|
||||
{
|
||||
ptrdiff_t dist = m_pCursor - m_pBuffer;
|
||||
return dist;
|
||||
}
|
||||
|
||||
int FSeek(int64_t origin, int command)
|
||||
{
|
||||
int retCode = -1;
|
||||
int64_t newPos;
|
||||
char* newPosBuf;
|
||||
switch (command)
|
||||
{
|
||||
case SEEK_SET:
|
||||
newPos = origin;
|
||||
if (newPos <= (int64_t)m_nFileSize)
|
||||
{
|
||||
m_pCursor = m_pBuffer + newPos;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
newPosBuf = m_pCursor + origin;
|
||||
if (newPosBuf <= m_pBuffer + m_nFileSize)
|
||||
{
|
||||
m_pCursor = newPosBuf;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
case SEEK_END:
|
||||
newPos = m_nFileSize - origin;
|
||||
if (newPos <= (int64_t)m_nFileSize)
|
||||
{
|
||||
m_pCursor = m_pBuffer + newPos;
|
||||
retCode = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Not valid disk operation!
|
||||
AZ_Assert(false, "Invalid disk operation");
|
||||
}
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void Close()
|
||||
{
|
||||
if (m_fileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
m_pPak->FClose(m_fileHandle);
|
||||
}
|
||||
|
||||
if (m_pBuffer)
|
||||
{
|
||||
m_pPak->PoolFree(m_pBuffer);
|
||||
}
|
||||
|
||||
m_pBuffer = m_pCursor = 0;
|
||||
m_nFileSize = 0;
|
||||
m_fileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::IO::HandleType m_fileHandle;
|
||||
char* m_pBuffer;
|
||||
AZ::IO::IArchive* m_pPak;
|
||||
char* m_pCursor;
|
||||
size_t m_nFileSize;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Helper class that can be used to recursively scan the directory.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct SDirectoryEnumeratorHelper
|
||||
{
|
||||
public:
|
||||
void ScanDirectoryRecursive(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& pathIn, const AZStd::string& fileSpec, AZStd::vector<AZStd::string>& files)
|
||||
{
|
||||
auto AddSlash = [](AZStd::string_view path) -> AZStd::string
|
||||
{
|
||||
if (path.ends_with(AZ_CORRECT_DATABASE_SEPARATOR))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
else if (path.ends_with(AZ_WRONG_DATABASE_SEPARATOR))
|
||||
{
|
||||
return AZStd::string{ path.substr(0, path.size() - 1) } + AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
}
|
||||
return path.empty() ? AZStd::string(path) : AZStd::string(path) + AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
};
|
||||
AZStd::string dir;
|
||||
AZ::StringFunc::Path::Join(root.c_str(), pathIn.c_str(), dir);
|
||||
dir = AddSlash(dir);
|
||||
|
||||
ScanDirectoryFiles(pIPak, "", dir, fileSpec, files);
|
||||
|
||||
AZStd::string findFilter;
|
||||
AZ::StringFunc::Path::Join(dir.c_str(), "*", findFilter);
|
||||
|
||||
// Add all directories.
|
||||
|
||||
AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str());
|
||||
if (pakFileIterator)
|
||||
{
|
||||
do
|
||||
{
|
||||
// Skip back folders.
|
||||
if (pakFileIterator.m_filename[0] == '.')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pakFileIterator.m_filename.empty())
|
||||
{
|
||||
AZ_Fatal("Archive", "IArchive FindFirst/FindNext returned empty name while looking for '%s'", findFilter.c_str());
|
||||
continue;
|
||||
}
|
||||
if ((pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) // skip sub directories.
|
||||
{
|
||||
AZStd::string scanDir = AZStd::string::format("%s%.*s/", AddSlash(pathIn).c_str(), aznumeric_cast<int>(pakFileIterator.m_filename.size()), pakFileIterator.m_filename.data());
|
||||
scanDir += AZ_CORRECT_DATABASE_SEPARATOR;
|
||||
ScanDirectoryRecursive(pIPak, root, scanDir, fileSpec, files);
|
||||
continue;
|
||||
}
|
||||
} while (pakFileIterator = pIPak->FindNext(pakFileIterator));
|
||||
pIPak->FindClose(pakFileIterator);
|
||||
}
|
||||
}
|
||||
private:
|
||||
void ScanDirectoryFiles(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& path, const AZStd::string& fileSpec, AZStd::vector<AZStd::string>& files)
|
||||
{
|
||||
AZStd::string dir;
|
||||
AZ::StringFunc::Path::Join(root.c_str(), path.c_str(), dir);
|
||||
|
||||
AZStd::string findFilter;
|
||||
AZ::StringFunc::Path::Join(dir.c_str(), fileSpec.c_str(), findFilter);
|
||||
|
||||
AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str());
|
||||
if (pakFileIterator)
|
||||
{
|
||||
do
|
||||
{
|
||||
// Skip back folders and subdirectories.
|
||||
if (pakFileIterator.m_filename[0] == '.' || (pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
AZStd::string fullPath;
|
||||
AZ::StringFunc::Path::Join(path.c_str(), AZStd::string(pakFileIterator.m_filename).c_str(), fullPath);
|
||||
files.push_back(fullPath);
|
||||
} while (pakFileIterator = pIPak->FindNext(pakFileIterator));
|
||||
pIPak->FindClose(pakFileIterator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <CryCommon/PakLoadDataUtils.h>
|
||||
|
||||
namespace PakLoadDataUtils
|
||||
{
|
||||
bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian)
|
||||
{
|
||||
GetISystem()->GetIPak()->FSeek(fileHandle, elems, SEEK_CUR);
|
||||
nDataSize -= elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return (nDataSize >= 0);
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian)
|
||||
{
|
||||
nDataSize -= elems;
|
||||
f += elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize)
|
||||
{
|
||||
while (nDataSize & 3)
|
||||
{
|
||||
[[maybe_unused]] size_t nRes = GetISystem()->GetIPak()->FSeek(fileHandle, 1, SEEK_CUR);
|
||||
AZ_Assert(nRes == 0, "FSeek failed for 1 byte");
|
||||
AZ_Assert(nDataSize, "nDataSize reached zero" );
|
||||
nDataSize--;
|
||||
}
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
}
|
||||
|
||||
void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize)
|
||||
{
|
||||
while (nDataSize & 3)
|
||||
{
|
||||
AZ_Assert(*f == 222, "Found invalid data in buffer.");
|
||||
f++;
|
||||
AZ_Assert(nDataSize, "nDataSize reached zero");
|
||||
nDataSize--;
|
||||
}
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
}
|
||||
|
||||
} //namespace PakLoadDataUtils
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <ISystem.h>
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
namespace PakLoadDataUtils
|
||||
{
|
||||
template <class T>
|
||||
static bool LoadDataFromFile(T* data, size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, EEndian eEndian, int* pSeek = 0)
|
||||
{
|
||||
auto ipak = GetISystem()->GetIPak();
|
||||
if (pSeek)
|
||||
{
|
||||
*pSeek = aznumeric_cast<int>(ipak->FTell(fileHandle));
|
||||
}
|
||||
|
||||
if (ipak->FRead(data, elems, fileHandle, eEndian) != elems)
|
||||
{
|
||||
AZ_Assert(false, "Failed to read %zu elements", elems);
|
||||
return false;
|
||||
}
|
||||
nDataSize -= sizeof(T) * elems;
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian);
|
||||
|
||||
template <class T>
|
||||
static bool LoadDataFromFile(T* data, size_t elems, uint8*& f, int& nDataSize, EEndian eEndian, [[maybe_unused]] int* pSeek = 0)
|
||||
{
|
||||
StepDataCopy(data, f, elems, eEndian);
|
||||
nDataSize -= elems * sizeof(T);
|
||||
AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0");
|
||||
return (nDataSize >= 0);
|
||||
}
|
||||
|
||||
bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian);
|
||||
|
||||
void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize);
|
||||
|
||||
void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize);
|
||||
|
||||
} //namespace PakLoadDataUtils
|
||||
@@ -242,9 +242,6 @@ typedef uint32 vtx_idx;
|
||||
#endif // TESSELLATION
|
||||
#endif // !defined(MOBILE)
|
||||
|
||||
|
||||
#define USE_GEOM_CACHES
|
||||
|
||||
//------------------------------------------------------
|
||||
// SVO GI
|
||||
//------------------------------------------------------
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
#define CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
#pragma once
|
||||
|
||||
namespace QTangent {
|
||||
// Computes a QTangent from a frame and reflection scalar representing the
|
||||
// tangent space.
|
||||
// Will also ensure the resulting QTangent is suitable for 16bit quantization.
|
||||
ILINE Quat FromFrameReflection(Quat frame, const float reflection)
|
||||
{
|
||||
frame.v = -frame.v;
|
||||
if (frame.w < 0.0f)
|
||||
{
|
||||
frame = -frame;
|
||||
}
|
||||
|
||||
// Make sure w is never 0 by applying the smallest possible bias.
|
||||
// This is needed in order to have sign() never return 0 in the shaders.
|
||||
static const float BIAS_16BIT = 1.0f / 32767.0f;
|
||||
static const float BIAS_SCALE_16BIT = sqrtf(1.0f - BIAS_16BIT * BIAS_16BIT);
|
||||
if (frame.w < BIAS_16BIT && frame.w > -BIAS_16BIT)
|
||||
{
|
||||
frame *= BIAS_SCALE_16BIT;
|
||||
frame.w = BIAS_16BIT;
|
||||
}
|
||||
|
||||
if (reflection < 0.0f)
|
||||
{
|
||||
frame = -frame;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
ILINE Quat FromFrameReflection(const Matrix33& frame, const float reflection)
|
||||
{
|
||||
Quat quat(frame);
|
||||
quat.Normalize();
|
||||
return FromFrameReflection(quat, reflection);
|
||||
}
|
||||
|
||||
ILINE Quat FromFrameReflection16Safe(Matrix33 frame, const float reflection)
|
||||
{
|
||||
frame.OrthonormalizeFast();
|
||||
if (!frame.IsOrthonormalRH(0.1f))
|
||||
{
|
||||
frame.SetIdentity();
|
||||
}
|
||||
|
||||
return FromFrameReflection(frame, reflection);
|
||||
}
|
||||
|
||||
ILINE void ToTangentBitangentReflection(const Quat& qtangent, Vec3& tangent, Vec3& bitangent, float& reflection)
|
||||
{
|
||||
tangent = qtangent.GetColumn0();
|
||||
bitangent = qtangent.GetColumn1();
|
||||
reflection = qtangent.w < 0.0f ? -1.0f : +1.0f;
|
||||
}
|
||||
} // namespace QTangent
|
||||
|
||||
// Auxiliary helper functions
|
||||
|
||||
#include <IIndexedMesh.h> // <> required for Interfuscator
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const SMeshTangents& tangents)
|
||||
{
|
||||
SMeshTangents tb = tangents;
|
||||
Vec3 tangent32, bitangent32;
|
||||
int16 reflection;
|
||||
|
||||
tb.GetTB(tangent32, bitangent32);
|
||||
tb.GetR(reflection);
|
||||
|
||||
Matrix33 frame;
|
||||
|
||||
frame.SetRow(0, tangent32);
|
||||
frame.SetRow(1, bitangent32);
|
||||
frame.SetRow(2, tangent32.Cross(bitangent32).GetNormalized());
|
||||
|
||||
return QTangent::FromFrameReflection16Safe(frame, reflection);
|
||||
}
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const Vec4sf& tangent, const Vec4sf& bitangent)
|
||||
{
|
||||
return MeshTangentFrameToQTangent(SMeshTangents(tangent, bitangent));
|
||||
}
|
||||
|
||||
ILINE Quat MeshTangentFrameToQTangent(const SPipTangents& tangents)
|
||||
{
|
||||
return MeshTangentFrameToQTangent(SMeshTangents(tangents));
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const Vec4sf* pTangent, const uint tangentStride,
|
||||
const Vec4sf* pBitangent, const uint bitangentStride, const uint count,
|
||||
SPipQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangent, *pBitangent);
|
||||
SMeshQTangents(qtangent).ExportTo(*pQTangents);
|
||||
|
||||
pTangent = (const Vec4sf*)(((const uint8*)pTangent) + tangentStride);
|
||||
pBitangent = (const Vec4sf*)(((const uint8*)pBitangent) + bitangentStride);
|
||||
pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const SPipTangents* pTangents, const uint tangentStride, const uint count,
|
||||
SPipQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangents);
|
||||
SMeshQTangents(qtangent).ExportTo(*pQTangents);
|
||||
|
||||
pTangents = (const SPipTangents*)(((const uint8*)pTangents) + tangentStride);
|
||||
pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ILINE bool MeshTangentsFrameToQTangents(
|
||||
const SMeshTangents* pTangents, const uint tangentStride, const uint count,
|
||||
SMeshQTangents* pQTangents, const uint qtangentStride)
|
||||
{
|
||||
Quat qtangent;
|
||||
for (uint i = 0; i < count; ++i)
|
||||
{
|
||||
qtangent = MeshTangentFrameToQTangent(*pTangents);
|
||||
*pQTangents = SMeshQTangents(qtangent);
|
||||
|
||||
pTangents = (const SMeshTangents*)(((const uint8*)pTangents) + tangentStride);
|
||||
pQTangents = (SMeshQTangents*)(((uint8*)pQTangents) + qtangentStride);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_QTANGENT_H
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectContext;
|
||||
}
|
||||
|
||||
namespace AzRTT
|
||||
{
|
||||
typedef AZ::Uuid RenderContextId;
|
||||
|
||||
// various post screen effects will fail if we attempt to render the scene to very
|
||||
// small render target sizes so provide a reasonable minimum (tile/icon size)
|
||||
constexpr uint32_t MinRenderTargetWidth = 32;
|
||||
constexpr uint32_t MinRenderTargetHeight = 32;
|
||||
|
||||
// this maximum recommended texture size applies to width and height
|
||||
// using sizes larger than this can lead to performance issues and instability
|
||||
constexpr uint32_t MaxRecommendedRenderTargetSize = 2048;
|
||||
|
||||
enum class AlphaMode {
|
||||
ALPHA_DISABLED = 0,
|
||||
ALPHA_OPAQUE,
|
||||
ALPHA_DEPTH_BASED
|
||||
};
|
||||
|
||||
// RenderContextConfig stores the render settings to use when rendering to texture.
|
||||
// It also provides a more developer-friendly interface to deal with by exposing
|
||||
// the most commonly used properties in one place.
|
||||
struct RenderContextConfig
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR(RenderContextConfig, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(RenderContextConfig, "{6114F930-CBE4-4373-AF9D-3B5319471C8F}");
|
||||
virtual ~RenderContextConfig() = default;
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
//! render target width
|
||||
uint32_t m_width = 256;
|
||||
|
||||
//! render target height
|
||||
uint32_t m_height = 256;
|
||||
|
||||
//! write srgb or linear output
|
||||
bool m_sRGBWrite = false;
|
||||
|
||||
//! alpha mode to use for the render target
|
||||
AlphaMode m_alphaMode = AlphaMode::ALPHA_OPAQUE;
|
||||
|
||||
//! scene settings
|
||||
bool m_oceanEnabled = true;
|
||||
bool m_terrainEnabled = true;
|
||||
bool m_vegetationEnabled = true;
|
||||
|
||||
//! shadow settings
|
||||
bool m_shadowsEnabled = true;
|
||||
int32_t m_shadowsNumCascades = -1;
|
||||
float m_shadowsGSMRange = -1.f;
|
||||
float m_shadowsGSMRangeStep = -1.f;
|
||||
|
||||
//! post-effects settings
|
||||
bool m_depthOfFieldEnabled = false;
|
||||
bool m_motionBlurEnabled = false;
|
||||
int m_aaMode = 0;
|
||||
|
||||
//! visiblity for shadow settings
|
||||
AZ::Crc32 GetShadowSettingsVisible();
|
||||
|
||||
//! confirm if user wants to use texture size larger than MaxRecommendedRenderTargetSize
|
||||
bool ValidateTextureSize(void* newValue, const AZ::Uuid& valueType);
|
||||
};
|
||||
}
|
||||
@@ -1,273 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright (C), Crytek, 1999-2015.
|
||||
#pragma once
|
||||
|
||||
// A fixed-size type-safe ring buffer (ie, fixed-size double-ended queue).
|
||||
// Note: It's possible to add support for iterators, indexing if needed.
|
||||
template<typename T, size_t N, typename I = uint32>
|
||||
class CRingBuffer
|
||||
{
|
||||
static_assert(std::is_integral<I>::value && std::is_unsigned<I>::value, "I is not unsigned integral type");
|
||||
static_assert(N != 0 && N <= I(-1), "N is not a valid value (or I is too small)");
|
||||
enum : I
|
||||
{
|
||||
kPowerOf2 = (N & (N - 1)) == 0,
|
||||
kMaxSize = static_cast<I>(N),
|
||||
};
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef I size_type;
|
||||
|
||||
// Constructs an empty ring buffer.
|
||||
CRingBuffer()
|
||||
: m_begin(0)
|
||||
, m_count(0)
|
||||
{}
|
||||
|
||||
// Destroy a ring buffer.
|
||||
~CRingBuffer()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// Retrieve the size of the collection.
|
||||
size_type size() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
// Retrieve the maximum size of the collection.
|
||||
size_type max_size() const
|
||||
{
|
||||
return kMaxSize;
|
||||
}
|
||||
|
||||
// Test if the collection is empty.
|
||||
bool empty() const
|
||||
{
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
// Test if the collection is full.
|
||||
bool full() const
|
||||
{
|
||||
return m_count == kMaxSize;
|
||||
}
|
||||
|
||||
// Get the front-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
reference front()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(m_begin);
|
||||
}
|
||||
|
||||
// Get the front-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
const_reference front() const
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(m_begin);
|
||||
}
|
||||
|
||||
// Get the back-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
reference back()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(wrap(m_begin + m_count - 1));
|
||||
}
|
||||
|
||||
// Get the back-most item of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
const_reference back() const
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
return *ptr(wrap(m_begin + m_count - 1));
|
||||
}
|
||||
|
||||
// Adds an item to the front of the collection.
|
||||
// In case the collection is full, the function returns false and the collection remains unmodified.
|
||||
template<typename X>
|
||||
bool push_front(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
if (full())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const I index = decrement(m_begin);
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
m_begin = index;
|
||||
++m_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds an item to the front of the collection.
|
||||
// In case the collection is full, the function overwrites the last item in the collection.
|
||||
template<typename X>
|
||||
void push_front_overwrite(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
const I index = decrement(m_begin);
|
||||
if (full())
|
||||
{
|
||||
ptr(index)->~T();
|
||||
--m_count;
|
||||
}
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
m_begin = index;
|
||||
++m_count;
|
||||
}
|
||||
|
||||
// Removes an item from the front of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
void pop_front()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
ptr(m_begin)->~T();
|
||||
m_begin = increment(m_begin);
|
||||
--m_count;
|
||||
}
|
||||
|
||||
// Attempts to remove an item from the front of the collection, and assigns it to 'value'.
|
||||
// Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified).
|
||||
bool try_pop_front(T& value)
|
||||
{
|
||||
if (m_count != 0)
|
||||
{
|
||||
T* const pItem = ptr(m_begin);
|
||||
value = std::move(*pItem);
|
||||
pItem->~T();
|
||||
m_begin = increment(m_begin);
|
||||
--m_count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adds an item to the back of the collection.
|
||||
// In case the collection is full, the function returns false and the collection remains unmodified.
|
||||
template<typename X>
|
||||
bool push_back(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
if (full())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const I index = wrap(m_begin + m_count);
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
++m_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds an item to the back of the collection.
|
||||
// In case the collection is full, the function overwrites the first item in the collection.
|
||||
template<typename X>
|
||||
void push_back_overwrite(X&& value)
|
||||
{
|
||||
static_assert(std::is_constructible<T, X&&>::value, "T cannot be constructed from the given type");
|
||||
const I index = wrap(m_begin + m_count);
|
||||
if (full())
|
||||
{
|
||||
ptr(index)->~T();
|
||||
m_begin = increment(index);
|
||||
--m_count;
|
||||
}
|
||||
::new(static_cast<void*>(ptr(index)))T(std::forward<X>(value));
|
||||
++m_count;
|
||||
}
|
||||
|
||||
// Removes an item from the back of the collection.
|
||||
// If the collection is empty, the behavior is undefined.
|
||||
void pop_back()
|
||||
{
|
||||
CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty");
|
||||
const I index = wrap(m_begin + m_count - 1);
|
||||
ptr(index)->~T();
|
||||
--m_count;
|
||||
}
|
||||
|
||||
// Attempts to remove an item from the back of the collection, and assigns it to 'value'.
|
||||
// Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified).
|
||||
bool try_pop_back(T& value)
|
||||
{
|
||||
if (m_count != 0)
|
||||
{
|
||||
const I index = wrap(m_begin + m_count - 1);
|
||||
T* const pItem = ptr(index);
|
||||
value = std::move(*pItem);
|
||||
pItem->~T();
|
||||
--m_count;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Destroy all items in a ring buffer.
|
||||
void clear()
|
||||
{
|
||||
size_type index = m_begin;
|
||||
for (size_type i = 0; i < m_count; ++i, index = increment(index))
|
||||
{
|
||||
ptr(index)->~T();
|
||||
}
|
||||
m_begin = 0;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Decrements a given index, wrapping it around N.
|
||||
static size_type decrement(size_type index)
|
||||
{
|
||||
return kPowerOf2 ? ((index - 1) & (kMaxSize - 1)) : index ? index - 1 : kMaxSize - 1;
|
||||
}
|
||||
|
||||
// Increments a given index, wrapping it around N.
|
||||
static size_type increment(size_type index)
|
||||
{
|
||||
++index;
|
||||
return kPowerOf2 ? index & (kMaxSize - 1) : index == kMaxSize ? 0 : index;
|
||||
}
|
||||
|
||||
// Wraps an index, which has a maximum value of 2N-1.
|
||||
static size_type wrap(size_type index)
|
||||
{
|
||||
return kPowerOf2 ? index & (kMaxSize - 1) : index >= kMaxSize ? index - kMaxSize : index;
|
||||
}
|
||||
|
||||
// Obtain pointer to raw storage at given index.
|
||||
pointer ptr(size_type index)
|
||||
{
|
||||
return reinterpret_cast<pointer>(&m_storage) + index;
|
||||
}
|
||||
|
||||
// Obtain pointer to raw storage at given index.
|
||||
const_pointer ptr(size_type index) const
|
||||
{
|
||||
return reinterpret_cast<const_pointer>(&m_storage) + index;
|
||||
}
|
||||
|
||||
// No copy/assign supported.
|
||||
CRingBuffer(const CRingBuffer&);
|
||||
void operator=(const CRingBuffer&);
|
||||
|
||||
size_type m_begin, m_count;
|
||||
typename std::aligned_storage<sizeof(T)* N, std::alignment_of<T>::value>::type m_storage;
|
||||
};
|
||||
@@ -1,188 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#undef AZ_RESTRICTED_SECTION
|
||||
#define SCOPEGUARD_H_SECTION_1 1
|
||||
#define SCOPEGUARD_H_SECTION_2 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
This is from the c++17 working draft paper N3949 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3949.pdf
|
||||
It is a new library addition targeted for c++17. I didn't feel like waiting. Only modification is as required to get the
|
||||
code compiling in the yet to be c++11 compliant visual studio. It is similar to boost scope exit, but in a modern and
|
||||
more feature rich form. scope_guard just executes a lambda when it goes out of scope. unique_resource is a more complete
|
||||
RAII wrapper. Its stands in for a resource (i.e. overloads cast operator to the wrapped resource) and frees it when it
|
||||
goes out of scope. see the paper for more examples and a better description. Get rid of this once c++17 is available.
|
||||
*/
|
||||
namespace std17
|
||||
{
|
||||
template <typename D>
|
||||
struct scope_guard_t
|
||||
{
|
||||
// construction
|
||||
explicit scope_guard_t(D&& f)
|
||||
: deleter(std::move(f))
|
||||
, execute_on_destruction(true)
|
||||
{
|
||||
}
|
||||
// move
|
||||
scope_guard_t(scope_guard_t&& rhs)
|
||||
: deleter(std::move(rhs.deleter))
|
||||
, execute_on_destruction(rhs.execute_on_destruction)
|
||||
{
|
||||
rhs.release();
|
||||
}
|
||||
// release
|
||||
~scope_guard_t()
|
||||
{
|
||||
if (execute_on_destruction)
|
||||
{
|
||||
deleter();
|
||||
}
|
||||
}
|
||||
void release() { execute_on_destruction = false; }
|
||||
private:
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE(ScopeGuard_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
scope_guard_t(scope_guard_t const&) = delete;
|
||||
void operator=(scope_guard_t const&) = delete;
|
||||
scope_guard_t& operator=(scope_guard_t&&) = delete;
|
||||
#endif
|
||||
D deleter;
|
||||
bool execute_on_destruction;
|
||||
// exposition only
|
||||
};
|
||||
|
||||
template <typename D>
|
||||
scope_guard_t<D> scope_guard(D&& deleter)
|
||||
{
|
||||
return scope_guard_t<D>(std::move(deleter));
|
||||
// fails with curlies
|
||||
}
|
||||
|
||||
enum class invoke_it
|
||||
{
|
||||
once, again
|
||||
};
|
||||
template<typename R, typename D>
|
||||
class unique_resource_t
|
||||
{
|
||||
R resource;
|
||||
D deleter;
|
||||
bool execute_on_destruction;
|
||||
// exposition only
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE(ScopeGuard_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
unique_resource_t& operator=(unique_resource_t const&) = delete;
|
||||
unique_resource_t(unique_resource_t const&) = delete;
|
||||
#endif
|
||||
// no copies!
|
||||
public:
|
||||
// construction
|
||||
explicit unique_resource_t(R&& _resource, D&& _deleter, bool _shouldrun = true)
|
||||
: resource(std::move(_resource))
|
||||
, deleter(std::move(_deleter))
|
||||
, execute_on_destruction(_shouldrun)
|
||||
{
|
||||
}
|
||||
// move
|
||||
unique_resource_t(unique_resource_t&& other)
|
||||
: resource(std::move(other.resource))
|
||||
, deleter(std::move(other.deleter))
|
||||
, execute_on_destruction(other.execute_on_destruction)
|
||||
{
|
||||
other.release();
|
||||
}
|
||||
unique_resource_t& operator=(unique_resource_t&& other)
|
||||
{
|
||||
this->invoke(invoke_it::once);
|
||||
deleter = std::move(other.deleter);
|
||||
resource = std::move(other.resource);
|
||||
execute_on_destruction = other.execute_on_destruction;
|
||||
other.release();
|
||||
return *this;
|
||||
}
|
||||
// resource release
|
||||
~unique_resource_t()
|
||||
{
|
||||
this->invoke(invoke_it::once);
|
||||
}
|
||||
void invoke(invoke_it const strategy = invoke_it::once)
|
||||
{
|
||||
if (execute_on_destruction)
|
||||
{
|
||||
get_deleter()(resource);
|
||||
}
|
||||
execute_on_destruction = strategy == invoke_it::again;
|
||||
}
|
||||
R const& release()
|
||||
{
|
||||
execute_on_destruction = false;
|
||||
return this->get();
|
||||
}
|
||||
void reset(R&& newresource)
|
||||
{
|
||||
invoke(invoke_it::again);
|
||||
resource = std::move(newresource);
|
||||
}
|
||||
// resource access
|
||||
R const& get() const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
operator R const& () const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
R operator->() const
|
||||
{
|
||||
return resource;
|
||||
}
|
||||
typename std::add_lvalue_reference<typename std::remove_pointer<R>::type>::type operator*() const
|
||||
{
|
||||
return *resource;
|
||||
}
|
||||
// deleter access
|
||||
const D& get_deleter() const
|
||||
{
|
||||
return deleter;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R, typename D>
|
||||
unique_resource_t<R, D> unique_resource(R&& r, D t)
|
||||
{
|
||||
return unique_resource_t<R, D>(std::move(r), std::move(t), true);
|
||||
}
|
||||
|
||||
template<typename R, typename D>
|
||||
unique_resource_t<R, D> unique_resource_checked(R r, R invalid, D t)
|
||||
{
|
||||
bool shouldrun = (r != invalid);
|
||||
return unique_resource_t<R, D>(std::move(r), std::move(t), shouldrun);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// This header is provided for backwards compatibility. Avoid including this header, instead
|
||||
// include the needed smart ptr headers
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/smart_ptr/weak_ptr.h>
|
||||
|
||||
#define DECLARE_SMART_POINTERS(name) \
|
||||
typedef AZStd::shared_ptr<name> name##Ptr; \
|
||||
typedef AZStd::shared_ptr<const name> name##ConstPtr; \
|
||||
typedef AZStd::weak_ptr<name> name##WeakPtr; \
|
||||
typedef AZStd::weak_ptr<const name> name##ConstWeakPtr;
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Helper to enable inplace construction and destruction of objects
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
#pragma once
|
||||
|
||||
#include <InplaceFactory.h>
|
||||
|
||||
// Class that contains a non-pod data type allocated on the stack via placement
|
||||
// new. Constructor parameters up to an arity of 5 are forwarded over an
|
||||
// inplace factory expression.
|
||||
template<typename T>
|
||||
class CStackContainer
|
||||
{
|
||||
// The backing storage
|
||||
uint8 m_Storage[ sizeof (T) ];
|
||||
|
||||
// Constructs the object via an inplace factory
|
||||
template<class Factory>
|
||||
void construct (const Factory& factory)
|
||||
{
|
||||
factory.template apply<T>(m_Storage);
|
||||
}
|
||||
|
||||
// Destructs the object. The destructor of the contained object is called
|
||||
void destruct ()
|
||||
{
|
||||
reinterpret_cast<T*>(m_Storage)->~T();
|
||||
}
|
||||
|
||||
// Prevent the object to be placed on the heap
|
||||
// (.... it simply wouldn't make much sense)
|
||||
void* operator new(size_t);
|
||||
void operator delete(void*);
|
||||
|
||||
public:
|
||||
|
||||
// Constructs inside the object
|
||||
template<class Expr>
|
||||
CStackContainer (const Expr& expr)
|
||||
{ construct(expr); }
|
||||
|
||||
// Destructs the object contained
|
||||
~CStackContainer() { destruct(); }
|
||||
|
||||
// Accessor methods
|
||||
T* get() { return reinterpret_cast<T*>(m_Storage); }
|
||||
const T* get() const { return reinterpret_cast<const T*>(m_Storage); }
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <CrySizer.h>
|
||||
#include <CryPodArray.h>
|
||||
|
||||
template <class T>
|
||||
class TPool
|
||||
{
|
||||
public:
|
||||
|
||||
TPool(int nPoolSize)
|
||||
{
|
||||
m_nPoolSize = nPoolSize;
|
||||
m_pPool = new T[nPoolSize];
|
||||
m_lstFree.PreAllocate(nPoolSize, 0);
|
||||
m_lstUsed.PreAllocate(nPoolSize, 0);
|
||||
for (int i = 0; i < nPoolSize; i++)
|
||||
{
|
||||
m_lstFree.Add(&m_pPool[i]);
|
||||
}
|
||||
}
|
||||
|
||||
~TPool()
|
||||
{
|
||||
delete[] m_pPool;
|
||||
}
|
||||
|
||||
void ReleaseObject(T* pInst)
|
||||
{
|
||||
if (m_lstUsed.Delete(pInst))
|
||||
{
|
||||
m_lstFree.Add(pInst);
|
||||
}
|
||||
}
|
||||
|
||||
int GetUsedInstancesCount(int& nAll)
|
||||
{
|
||||
nAll = m_nPoolSize;
|
||||
return m_lstUsed.Count();
|
||||
}
|
||||
|
||||
T* GetObject()
|
||||
{
|
||||
T* pInst = NULL;
|
||||
if (m_lstFree.Count())
|
||||
{
|
||||
pInst = m_lstFree.Last();
|
||||
m_lstFree.DeleteLast();
|
||||
m_lstUsed.Add(pInst);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!"TPool::GetObject: Out of free elements error");
|
||||
}
|
||||
|
||||
return pInst;
|
||||
}
|
||||
|
||||
void GetMemoryUsage(class ICrySizer* pSizer) const
|
||||
{
|
||||
pSizer->AddObject(m_lstFree);
|
||||
pSizer->AddObject(m_lstUsed);
|
||||
|
||||
if (m_pPool)
|
||||
{
|
||||
for (int i = 0; i < m_nPoolSize; i++)
|
||||
{
|
||||
m_pPool[i].GetMemoryUsage(pSizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PodArray<T*> m_lstFree;
|
||||
PodArray<T*> m_lstUsed;
|
||||
T* m_pPool;
|
||||
int m_nPoolSize;
|
||||
};
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Generic unaligned memory access helpers.
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
template<typename RealType, typename BlittedElement>
|
||||
struct Blitter
|
||||
{
|
||||
static_assert(std::is_trivial<BlittedElement>::value, "Blittable elements should be trivial (ie, integral types)");
|
||||
static_assert((std::alignment_of<BlittedElement>::value < std::alignment_of<RealType>::value), "Blittable memory has sufficient alignment, do not use unaligned store or load");
|
||||
static_assert(sizeof(RealType) > sizeof(BlittedElement), "Blittable element is larger than real type");
|
||||
static_assert((sizeof(RealType) % sizeof(BlittedElement)) == 0, "Blitted element has the wrong size for the real type");
|
||||
typedef std::integral_constant<size_t, sizeof(RealType) / sizeof(BlittedElement)> NumElements;
|
||||
|
||||
static void BlitLoad(const BlittedElement* pSource, RealType& target)
|
||||
{
|
||||
BlittedElement* pTarget = alias_cast<BlittedElement*>(&target);
|
||||
for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget)
|
||||
{
|
||||
* pTarget = *pSource;
|
||||
}
|
||||
}
|
||||
|
||||
static void BlitStore(const RealType& source, BlittedElement* pTarget)
|
||||
{
|
||||
const BlittedElement* pSource = alias_cast<const BlittedElement*>(&source);
|
||||
for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget)
|
||||
{
|
||||
* pTarget = *pSource;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Load RealType from unaligned memory using some blittable type.
|
||||
// The source memory must be suitably aligned for accessing BlittedElement.
|
||||
// If no memory alignment can be guaranteed, use char for BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value > std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
Detail::Blitter<RealType, BlittedElement>::BlitLoad(pMemory, value);
|
||||
}
|
||||
|
||||
// Load RealType from aligned memory (fallback overload).
|
||||
// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value <= std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
value = *alias_cast<RealType*>(pMemory);
|
||||
}
|
||||
|
||||
// Store to unaligned memory using some blittable type.
|
||||
// The target memory must be suitably aligned for accessing BlittedElement.
|
||||
// If no memory alignment can be guaranteed, use char for BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value > std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
Detail::Blitter<RealType, BlittedElement>::BlitStore(value, pMemory);
|
||||
}
|
||||
|
||||
// Store to aligned memory (fallback overload).
|
||||
// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement.
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value <= std::alignment_of<BlittedElement>::value)>::type* = nullptr)
|
||||
{
|
||||
*alias_cast<RealType*>(pMemory) = value;
|
||||
}
|
||||
|
||||
// Pads the given pointer to the next possible aligned location for RealType
|
||||
// Use this to ensure RealType can be referenced in some buffer of BlittedElement's, without using LoadUnaligned/StoreUnaligned
|
||||
template<typename RealType, typename BlittedElement>
|
||||
inline BlittedElement* AlignPointer(BlittedElement* pMemory,
|
||||
typename std::enable_if<(std::alignment_of<RealType>::value % std::alignment_of<BlittedElement>::value) == 0>::type* = nullptr)
|
||||
{
|
||||
const size_t align = std::alignment_of<RealType>::value;
|
||||
const size_t mask = align - 1;
|
||||
const size_t address = reinterpret_cast<size_t>(pMemory);
|
||||
const size_t offset = (align - (address & mask)) & mask;
|
||||
return pMemory + (offset / sizeof(BlittedElement));
|
||||
}
|
||||
|
||||
// Pads the given address to the next possible aligned location for RealType
|
||||
// Use this to ensure RealType can be referenced inside memory, without using LoadUnaligned/StoreUnaligned
|
||||
template<typename RealType>
|
||||
inline size_t AlignAddress(size_t address)
|
||||
{
|
||||
return reinterpret_cast<size_t>(AlignPointer<RealType>(reinterpret_cast<char*>(address)));
|
||||
}
|
||||
|
||||
// Provides aligned storage for T, optionally aligned at a specific boundary (default being the native alignment of T)
|
||||
// The specified T is not initialized automatically, use of placement new/delete is the user's responsibility
|
||||
template<typename T, size_t Align = std::alignment_of<T>::value>
|
||||
struct SUninitialized
|
||||
{
|
||||
typedef typename std::aligned_storage<sizeof(T), Align>::type Storage;
|
||||
Storage storage;
|
||||
|
||||
void DefaultConstruct()
|
||||
{
|
||||
new(static_cast<void*>(&storage))T();
|
||||
}
|
||||
|
||||
void CopyConstruct(const T& value)
|
||||
{
|
||||
new(static_cast<void*>(&storage))T(value);
|
||||
}
|
||||
|
||||
void MoveConstruct(T&& value)
|
||||
{
|
||||
new(static_cast<void*>(&storage))T(std::move(value));
|
||||
}
|
||||
|
||||
void Destruct()
|
||||
{
|
||||
alias_cast<T*>(&storage)->~T();
|
||||
}
|
||||
|
||||
operator T& ()
|
||||
{
|
||||
return *alias_cast<T*>(&storage);
|
||||
}
|
||||
};
|
||||
@@ -10,23 +10,16 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
QTangent.h
|
||||
CryCommon.cpp
|
||||
FinalizingSpline.h
|
||||
IAudioInterfacesCommonData.h
|
||||
IAudioSystem.h
|
||||
IChunkFile.h
|
||||
ICmdLine.h
|
||||
IColorGradingController.h
|
||||
IConsole.h
|
||||
IEntityRenderState.h
|
||||
IEntityRenderState_info.cpp
|
||||
IFont.h
|
||||
IFunctorBase.h
|
||||
IFuncVariable.h
|
||||
IGem.h
|
||||
IGeomCache.h
|
||||
IImage.h
|
||||
IIndexedMesh.h
|
||||
IIndexedMesh_info.cpp
|
||||
ILevelSystem.h
|
||||
@@ -35,11 +28,9 @@ set(FILES
|
||||
LocalizationManagerBus.inl
|
||||
ILog.h
|
||||
IMaterial.h
|
||||
IMeshBaking.h
|
||||
IMiniLog.h
|
||||
IMovieSystem.h
|
||||
IPhysics.h
|
||||
IPhysicsDebugRenderer.h
|
||||
IPostEffectGroup.h
|
||||
IProcess.h
|
||||
IReadWriteXMLSink.h
|
||||
@@ -48,7 +39,6 @@ set(FILES
|
||||
IRenderMesh.h
|
||||
ISerialize.h
|
||||
IShader.h
|
||||
IShader_info.h
|
||||
ISplines.h
|
||||
IStatObj.h
|
||||
StatObjBus.h
|
||||
@@ -58,18 +48,15 @@ set(FILES
|
||||
ITexture.h
|
||||
ITimer.h
|
||||
IValidator.h
|
||||
IVideoRenderer.h
|
||||
IViewSystem.h
|
||||
IWindowMessageHandler.h
|
||||
IXml.h
|
||||
IProximityTriggerSystem.h
|
||||
MicrophoneBus.h
|
||||
physinterface.h
|
||||
HMDBus.h
|
||||
VRCommon.h
|
||||
StereoRendererBus.h
|
||||
HeightmapUpdateNotificationBus.h
|
||||
IObjManager.h
|
||||
INavigationSystem.h
|
||||
IMNM.h
|
||||
SFunctor.h
|
||||
@@ -82,18 +69,15 @@ set(FILES
|
||||
CryRandomInternal.h
|
||||
Random.h
|
||||
LCGRandom.h
|
||||
MaterialUtils.h
|
||||
MTPseudoRandom.cpp
|
||||
CryTypeInfo.cpp
|
||||
BaseTypes.h
|
||||
CompileTimeAssert.h
|
||||
intrusive_list.hpp
|
||||
MemoryAccess.h
|
||||
AnimKey.h
|
||||
BitFiddling.h
|
||||
Common_TypeInfo.cpp
|
||||
CryArray.h
|
||||
CryArray2d.h
|
||||
CryAssert.h
|
||||
CryCrc32.h
|
||||
CryCustomTypes.h
|
||||
@@ -106,44 +90,31 @@ set(FILES
|
||||
CryName.h
|
||||
CryPath.h
|
||||
CryPodArray.h
|
||||
CryPtrArray.h
|
||||
CrySizer.h
|
||||
CryString.h
|
||||
CrySystemBus.h
|
||||
CryThread.h
|
||||
CryThreadImpl.h
|
||||
CryTypeInfo.h
|
||||
CryUtils.h
|
||||
CryVersion.h
|
||||
CryZlib.h
|
||||
FrameProfiler.h
|
||||
HashGrid.h
|
||||
HeapAllocator.h
|
||||
HeapContainer.h
|
||||
InplaceFactory.h
|
||||
LegacyAllocator.h
|
||||
MetaUtils.h
|
||||
MiniQueue.h
|
||||
MTPseudoRandom.h
|
||||
MultiThread.h
|
||||
MultiThread_Containers.h
|
||||
Name_TypeInfo.h
|
||||
NullAudioSystem.h
|
||||
PNoise3.h
|
||||
PoolAllocator.h
|
||||
primitives.h
|
||||
primitives_info.h
|
||||
ProjectDefines.h
|
||||
Range.h
|
||||
RenderContextConfig.h
|
||||
RingBuffer.h
|
||||
ScopeGuard.h
|
||||
ScopedVariableSetter.h
|
||||
SerializeFwd.h
|
||||
SimpleSerialize.h
|
||||
SmartPointersHelpers.h
|
||||
smartptr.h
|
||||
StackContainer.h
|
||||
StlUtils.h
|
||||
StringUtils.h
|
||||
Synchronization.h
|
||||
@@ -153,7 +124,6 @@ set(FILES
|
||||
TimeValue_info.h
|
||||
TypeInfo_decl.h
|
||||
TypeInfo_impl.h
|
||||
UnalignedBlit.h
|
||||
UnicodeBinding.h
|
||||
UnicodeEncoding.h
|
||||
UnicodeFunctions.h
|
||||
@@ -164,10 +134,6 @@ set(FILES
|
||||
XMLBinaryHeaders.h
|
||||
RenderBus.h
|
||||
MainThreadRenderRequestBus.h
|
||||
OceanConstants.h
|
||||
PakLoadDataUtils.cpp
|
||||
PakLoadDataUtils.h
|
||||
TPool.h
|
||||
Cry_Matrix33.h
|
||||
Cry_Matrix34.h
|
||||
Cry_Matrix44.h
|
||||
@@ -186,7 +152,6 @@ set(FILES
|
||||
Cry_Vector3.h
|
||||
Cry_XOptimise.h
|
||||
CryHalf_info.h
|
||||
GeomQuery.h
|
||||
CryHalf.inl
|
||||
MathConversion.h
|
||||
Cry_HWMatrix.h
|
||||
@@ -308,6 +273,5 @@ set(FILES
|
||||
Maestro/Types/AssetBlends.h
|
||||
Maestro/Types/SequenceType.h
|
||||
StaticInstance.h
|
||||
Pak/CryPakUtils.h
|
||||
WinBase.cpp
|
||||
)
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef _INTRUSIVE_LIST_HPP
|
||||
#define _INTRUSIVE_LIST_HPP
|
||||
#if !defined(WIN32)
|
||||
#include <stdint.h>
|
||||
#endif //!defined(WIN32)
|
||||
|
||||
|
||||
namespace util
|
||||
{
|
||||
// Simple lightweight intrusive list utility
|
||||
//
|
||||
template<typename Host>
|
||||
struct list
|
||||
{
|
||||
typedef Host value_type;
|
||||
|
||||
list* next;
|
||||
list* prev;
|
||||
|
||||
// Default (initializing) constructor
|
||||
list()
|
||||
{
|
||||
next = this;
|
||||
prev = this;
|
||||
}
|
||||
|
||||
// Inserts this list into a given list item between
|
||||
// prev and next (note: they need to be sequential!)
|
||||
void insert(list* _prev, list* _next)
|
||||
{
|
||||
_next->prev = this;
|
||||
this->next = _next;
|
||||
this->prev = _prev;
|
||||
_prev->next = this;
|
||||
}
|
||||
|
||||
// Should only be called on heads
|
||||
void clear() { next = prev = this; }
|
||||
|
||||
// Removes from a list, then inserts this list item into a given list between
|
||||
// prev and next (note: they need to be sequential!)
|
||||
void re_insert(list* _prev, list* _next)
|
||||
{
|
||||
erase();
|
||||
insert(_prev, _next);
|
||||
}
|
||||
|
||||
|
||||
// Remove this list instance from a list
|
||||
// Safe to be called even if not attached to a list
|
||||
void erase()
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
next = prev = this;
|
||||
}
|
||||
|
||||
// Predicate to determine if a list structure is linked to a list
|
||||
bool empty() const { return prev == this && next == this; }
|
||||
bool linked() const { return !empty(); }
|
||||
|
||||
// Get the host instance of the instrusive list
|
||||
template<list Host::* member>
|
||||
Host* item()
|
||||
{
|
||||
return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member))));
|
||||
}
|
||||
template<list Host::* member>
|
||||
const Host* item() const
|
||||
{
|
||||
return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member))));
|
||||
}
|
||||
template<list (Host::* Member)[2]>
|
||||
Host * item(int threadId)
|
||||
{
|
||||
uintptr_t value = (uintptr_t)this - (uintptr_t)&((((Host*)(NULL))->*Member)[threadId]);
|
||||
return alias_cast<Host*>(value);
|
||||
}
|
||||
|
||||
// Insert & relink functions
|
||||
void insert_tail(list* _list) { insert(_list->prev, _list); }
|
||||
void insert_tail(list& _list) { insert_tail(&_list); }
|
||||
void insert_head(list* _list) { insert(_list, _list->next); }
|
||||
void insert_head(list& _list) { insert_head(&_list); }
|
||||
void relink_tail(list* _list) { erase(); insert_tail(_list); }
|
||||
void relink_tail(list& _list) { relink_tail(&_list); }
|
||||
void relink_head(list* _list) { erase(); insert_head(_list); }
|
||||
void relink_head(list& _list) { relink_head(&_list); }
|
||||
|
||||
static inline void splice(const list* _list, list* prev, list* next)
|
||||
{
|
||||
list* first = _list->next;
|
||||
list* last = _list->prev;
|
||||
|
||||
first->prev = prev;
|
||||
prev->next = first;
|
||||
|
||||
last->next = next;
|
||||
next->prev = last;
|
||||
}
|
||||
|
||||
void splice_front(const list* _list)
|
||||
{
|
||||
if (!_list->empty())
|
||||
{
|
||||
splice(_list, this, this->next);
|
||||
_list->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void splice_tail(list* _list)
|
||||
{
|
||||
if (!_list->empty())
|
||||
{
|
||||
splice(_list, this->prev, this);
|
||||
_list->clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Accessors
|
||||
list<Host>* tail() { return prev; }
|
||||
const list<Host>* tail() const { return prev; }
|
||||
list<Host>* head() { return head; }
|
||||
const list<Host>* head() const { return head; }
|
||||
};
|
||||
|
||||
// utility to extract the host type of an intrusive list at compile time
|
||||
template<typename List>
|
||||
struct list_value_type
|
||||
{
|
||||
typedef typename List::value_type value_type;
|
||||
};
|
||||
|
||||
// Loops over the list in forward manner, pos will be of type list<T>*
|
||||
# define list_for_each(pos, head) \
|
||||
for (typeof(head)pos = (head)->next; pos != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
// Loops over the list in backward manner, pos will be of type list<T>*
|
||||
# define list_for_each_backwards(pos, head) \
|
||||
for (typeof(head)pos = (head)->prev; pos != (head); \
|
||||
pos = pos->prev)
|
||||
|
||||
// Loops over the list in forward manner while safeguarding
|
||||
// against list removal during iteration. pos will be of type list<T>*
|
||||
# define list_for_each_safe(pos, head) \
|
||||
for (typeof(head)pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
// Loops over the list in forward manner. pos will be of type list<T>*
|
||||
# define list_for_each_entry(pos, head, member) \
|
||||
for (util::list_value_type<typeof((head))>::value_type* pos = \
|
||||
(head)->next->item<member>(); \
|
||||
&(pos->*(member)) != &list; \
|
||||
pos = ((pos->*(member)).next->item<member>()))
|
||||
|
||||
// Loops over the list in forward manner while safeguarding against list
|
||||
// removal during iteratation. pos will be of type T*
|
||||
# define list_for_each_entry_safe(pos, head, member) \
|
||||
for (util::list_value_type<typeof((head))>::value_type* pos = \
|
||||
(head)->next->item<member>(), \
|
||||
* n = ((pos->*(member)).next->item<member>()); \
|
||||
&(pos->*(member)) != &list; \
|
||||
pos = n, n = ((n->*(member)).next->item<member>()))
|
||||
} // end namespace util
|
||||
#endif // ifndef _INTRUSIVE_LIST_HPP
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
#define CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
#pragma once
|
||||
|
||||
#include "primitives.h"
|
||||
|
||||
STRUCT_INFO_TYPE_EMPTY(primitives::primitive)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::box)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(Basis, TYPE_INFO(Matrix33))
|
||||
STRUCT_VAR_INFO(bOriented, TYPE_INFO(int))
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(size, TYPE_INFO(Vec3))
|
||||
STRUCT_INFO_END(primitives::box)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::sphere)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(r, TYPE_INFO(float))
|
||||
STRUCT_INFO_END(primitives::sphere)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::cylinder)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(center, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(axis, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(r, TYPE_INFO(float))
|
||||
STRUCT_VAR_INFO(hh, TYPE_INFO(float))
|
||||
STRUCT_INFO_END(primitives::cylinder)
|
||||
|
||||
STRUCT_INFO_BEGIN(primitives::plane)
|
||||
STRUCT_BASE_INFO(primitives::primitive)
|
||||
STRUCT_VAR_INFO(n, TYPE_INFO(Vec3))
|
||||
STRUCT_VAR_INFO(origin, TYPE_INFO(Vec3))
|
||||
STRUCT_INFO_END(primitives::plane)
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H
|
||||
@@ -0,0 +1,900 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "DebugCallStack.h"
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
|
||||
#include <IConsole.h>
|
||||
#include <CryPath.h>
|
||||
#include "System.h"
|
||||
|
||||
#include <AzCore/Debug/StackTracer.h>
|
||||
#include <AzCore/Debug/EventTraceDrillerBus.h>
|
||||
|
||||
#define VS_VERSION_INFO 1
|
||||
#define IDD_CRITICAL_ERROR 101
|
||||
#define IDB_CONFIRM_SAVE 102
|
||||
#define IDB_DONT_SAVE 103
|
||||
#define IDD_CONFIRM_SAVE_LEVEL 127
|
||||
#define IDB_CRASH_FACE 128
|
||||
#define IDD_EXCEPTION 245
|
||||
#define IDC_CALLSTACK 1001
|
||||
#define IDC_EXCEPTION_CODE 1002
|
||||
#define IDC_EXCEPTION_ADDRESS 1003
|
||||
#define IDC_EXCEPTION_MODULE 1004
|
||||
#define IDC_EXCEPTION_DESC 1005
|
||||
#define IDB_EXIT 1008
|
||||
#define IDB_IGNORE 1010
|
||||
__pragma(comment(lib, "version.lib"))
|
||||
|
||||
//! Needs one external of DLL handle.
|
||||
extern HMODULE gDLLHandle;
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#define MAX_PATH_LENGTH 1024
|
||||
#define MAX_SYMBOL_LENGTH 512
|
||||
|
||||
static HWND hwndException = 0;
|
||||
static bool g_bUserDialog = true; // true=on crash show dialog box, false=supress user interaction
|
||||
|
||||
static int PrintException(EXCEPTION_POINTERS* pex);
|
||||
|
||||
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex);
|
||||
|
||||
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
|
||||
extern LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE mdumpValue);
|
||||
|
||||
//=============================================================================
|
||||
CONTEXT CaptureCurrentContext()
|
||||
{
|
||||
CONTEXT context;
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.ContextFlags = CONTEXT_FULL;
|
||||
RtlCaptureContext(&context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
LONG __stdcall CryUnhandledExceptionHandler(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
return DebugCallStack::instance()->handleException(pex);
|
||||
}
|
||||
|
||||
|
||||
BOOL CALLBACK EnumModules(
|
||||
PCSTR ModuleName,
|
||||
DWORD64 BaseOfDll,
|
||||
PVOID UserContext)
|
||||
{
|
||||
DebugCallStack::TModules& modules = *static_cast<DebugCallStack::TModules*>(UserContext);
|
||||
modules[(void*)BaseOfDll] = ModuleName;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
//=============================================================================
|
||||
// Class Statics
|
||||
//=============================================================================
|
||||
|
||||
// Return single instance of class.
|
||||
IDebugCallStack* IDebugCallStack::instance()
|
||||
{
|
||||
static DebugCallStack sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
// Sets up the symbols for functions in the debug file.
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
DebugCallStack::DebugCallStack()
|
||||
: prevExceptionHandler(0)
|
||||
, m_pSystem(0)
|
||||
, m_nSkipNumFunctions(0)
|
||||
, m_bCrash(false)
|
||||
, m_szBugMessage(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
DebugCallStack::~DebugCallStack()
|
||||
{
|
||||
}
|
||||
|
||||
void DebugCallStack::RemoveOldFiles()
|
||||
{
|
||||
RemoveFile("error.log");
|
||||
RemoveFile("error.bmp");
|
||||
RemoveFile("error.dmp");
|
||||
}
|
||||
|
||||
void DebugCallStack::RemoveFile(const char* szFileName)
|
||||
{
|
||||
FILE* pFile = nullptr;
|
||||
azfopen(&pFile, szFileName, "r");
|
||||
const bool bFileExists = (pFile != NULL);
|
||||
|
||||
if (bFileExists)
|
||||
{
|
||||
fclose(pFile);
|
||||
|
||||
WriteLineToLog("Removing file \"%s\"...", szFileName);
|
||||
if (remove(szFileName) == 0)
|
||||
{
|
||||
WriteLineToLog("File successfully removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLineToLog("Couldn't remove file!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugCallStack::installErrorHandler(ISystem* pSystem)
|
||||
{
|
||||
m_pSystem = pSystem;
|
||||
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DebugCallStack::SetUserDialogEnable(const bool bUserDialogEnable)
|
||||
{
|
||||
g_bUserDialog = bUserDialogEnable;
|
||||
}
|
||||
|
||||
|
||||
DWORD g_idDebugThreads[10];
|
||||
const char* g_nameDebugThreads[10];
|
||||
int g_nDebugThreads = 0;
|
||||
volatile int g_lockThreadDumpList = 0;
|
||||
|
||||
void MarkThisThreadForDebugging(const char* name)
|
||||
{
|
||||
EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), name);
|
||||
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
if (g_nDebugThreads == sizeof(g_idDebugThreads) / sizeof(g_idDebugThreads[0]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] == id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_nameDebugThreads[g_nDebugThreads] = name;
|
||||
g_idDebugThreads[g_nDebugThreads++] = id;
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
|
||||
}
|
||||
|
||||
void UnmarkThisThreadFromDebugging()
|
||||
{
|
||||
WriteLock lock(g_lockThreadDumpList);
|
||||
DWORD id = GetCurrentThreadId();
|
||||
for (int i = g_nDebugThreads - 1; i >= 0; i--)
|
||||
{
|
||||
if (g_idDebugThreads[i] == id)
|
||||
{
|
||||
memmove(g_idDebugThreads + i, g_idDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_idDebugThreads[0]));
|
||||
memmove(g_nameDebugThreads + i, g_nameDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_nameDebugThreads[0]));
|
||||
--g_nDebugThreads;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int prev_sys_float_exceptions;
|
||||
void UpdateFPExceptionsMaskForThreads()
|
||||
{
|
||||
int mask = -iszero(g_cvars.sys_float_exceptions);
|
||||
CONTEXT ctx;
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
SuspendThread(hThread);
|
||||
GetThreadContext(hThread, &ctx);
|
||||
#ifndef WIN64
|
||||
(ctx.FloatSave.ControlWord |= 7) &= ~5 | mask;
|
||||
(*(WORD*)(ctx.ExtendedRegisters + 24) |= 0x280) &= ~0x280 | mask;
|
||||
#else
|
||||
(ctx.FltSave.ControlWord |= 7) &= ~5 | mask;
|
||||
(ctx.FltSave.MxCsr |= 0x280) &= ~0x280 | mask;
|
||||
#endif
|
||||
SetThreadContext(hThread, &ctx);
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
if (gEnv == NULL)
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
ResetFPU(exception_pointer);
|
||||
|
||||
prev_sys_float_exceptions = 0;
|
||||
const int cached_sys_float_exceptions = g_cvars.sys_float_exceptions;
|
||||
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(0);
|
||||
|
||||
if (g_cvars.sys_WER)
|
||||
{
|
||||
gEnv->pLog->FlushAndClose();
|
||||
return CryEngineExceptionFilterWER(exception_pointer);
|
||||
}
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog)
|
||||
{
|
||||
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
|
||||
}
|
||||
|
||||
m_bCrash = true;
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog)
|
||||
{
|
||||
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
|
||||
}
|
||||
|
||||
static bool firstTime = true;
|
||||
|
||||
if (g_cvars.sys_dump_aux_threads)
|
||||
{
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
SuspendThread(OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// uninstall our exception handler.
|
||||
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)prevExceptionHandler);
|
||||
|
||||
if (!firstTime)
|
||||
{
|
||||
WriteLineToLog("Critical Exception! Called Multiple Times!");
|
||||
gEnv->pLog->FlushAndClose();
|
||||
// Exception called more then once.
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
// Print exception info:
|
||||
{
|
||||
char excCode[80];
|
||||
char excAddr[80];
|
||||
WriteLineToLog("<CRITICAL EXCEPTION>");
|
||||
sprintf_s(excAddr, "0x%04X:0x%p", exception_pointer->ContextRecord->SegCs, exception_pointer->ExceptionRecord->ExceptionAddress);
|
||||
sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode);
|
||||
WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr);
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
|
||||
const int ret = SubmitBug(exception_pointer);
|
||||
|
||||
if (ret != IDB_IGNORE)
|
||||
{
|
||||
CryEngineExceptionFilterWER(exception_pointer);
|
||||
}
|
||||
|
||||
gEnv->pLog->FlushAndClose();
|
||||
|
||||
if (exception_pointer->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
// This is non continuable exception. abort application now.
|
||||
exit(exception_pointer->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
|
||||
//typedef long (__stdcall *ExceptionFunc)(EXCEPTION_POINTERS*);
|
||||
//ExceptionFunc prevFunc = (ExceptionFunc)prevExceptionHandler;
|
||||
//return prevFunc( (EXCEPTION_POINTERS*)exception_pointer );
|
||||
if (ret == IDB_EXIT)
|
||||
{
|
||||
// Immediate exit.
|
||||
// on windows, exit() and _exit() do all sorts of things, unfortuantely
|
||||
// TerminateProcess is the only way to die.
|
||||
TerminateProcess(GetCurrentProcess(), exception_pointer->ExceptionRecord->ExceptionCode); // we crashed, so don't return a zero exit code!
|
||||
// on linux based systems, _exit will not call ATEXIT and other things, which makes it more suitable for termination in an emergency such
|
||||
// as an unhandled exception.
|
||||
// however, this function is a windows exception handler.
|
||||
}
|
||||
else if (ret == IDB_IGNORE)
|
||||
{
|
||||
#ifndef WIN64
|
||||
exception_pointer->ContextRecord->FloatSave.StatusWord &= ~31;
|
||||
exception_pointer->ContextRecord->FloatSave.ControlWord |= 7;
|
||||
(*(WORD*)(exception_pointer->ContextRecord->ExtendedRegisters + 24) &= 31) |= 0x1F80;
|
||||
#else
|
||||
exception_pointer->ContextRecord->FltSave.StatusWord &= ~31;
|
||||
exception_pointer->ContextRecord->FltSave.ControlWord |= 7;
|
||||
(exception_pointer->ContextRecord->FltSave.MxCsr &= 31) |= 0x1F80;
|
||||
#endif
|
||||
firstTime = true;
|
||||
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
|
||||
g_cvars.sys_float_exceptions = cached_sys_float_exceptions;
|
||||
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
// Continue;
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void DebugCallStack::ReportBug(const char* szErrorMessage)
|
||||
{
|
||||
WriteLineToLog("Reporting bug: %s", szErrorMessage);
|
||||
|
||||
m_szBugMessage = szErrorMessage;
|
||||
m_context = CaptureCurrentContext();
|
||||
SubmitBug(NULL);
|
||||
m_szBugMessage = NULL;
|
||||
}
|
||||
|
||||
void DebugCallStack::dumpCallStack(std::vector<string>& funcs)
|
||||
{
|
||||
WriteLineToLog("=============================================================================");
|
||||
int len = (int)funcs.size();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
const char* str = funcs[i].c_str();
|
||||
WriteLineToLog("%2d) %s", len - i, str);
|
||||
}
|
||||
WriteLineToLog("=============================================================================");
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
string path("");
|
||||
if ((gEnv) && (gEnv->pFileIO))
|
||||
{
|
||||
const char* logAlias = gEnv->pFileIO->GetAlias("@log@");
|
||||
if (!logAlias)
|
||||
{
|
||||
logAlias = gEnv->pFileIO->GetAlias("@root@");
|
||||
}
|
||||
if (logAlias)
|
||||
{
|
||||
path = logAlias;
|
||||
path += "/";
|
||||
}
|
||||
}
|
||||
|
||||
string fileName = path;
|
||||
fileName += "error.log";
|
||||
|
||||
struct stat fileInfo;
|
||||
string timeStamp;
|
||||
string backupPath;
|
||||
if (gEnv->IsDedicated())
|
||||
{
|
||||
backupPath = PathUtil::ToUnixPath(PathUtil::AddSlash(path + "DumpBackups"));
|
||||
gEnv->pFileIO->CreatePath(backupPath.c_str());
|
||||
|
||||
if (stat(fileName.c_str(), &fileInfo) == 0)
|
||||
{
|
||||
// Backup log
|
||||
tm creationTime;
|
||||
localtime_s(&creationTime, &fileInfo.st_mtime);
|
||||
char tempBuffer[32];
|
||||
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
|
||||
timeStamp = tempBuffer;
|
||||
|
||||
string backupFileName = backupPath + timeStamp + " error.log";
|
||||
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
FILE* f = nullptr;
|
||||
azfopen(&f, fileName.c_str(), "wt");
|
||||
|
||||
static char errorString[s_iCallStackSize];
|
||||
errorString[0] = 0;
|
||||
|
||||
// Time and Version.
|
||||
char versionbuf[1024];
|
||||
azstrcpy(versionbuf, AZ_ARRAY_SIZE(versionbuf), "");
|
||||
PutVersion(versionbuf, AZ_ARRAY_SIZE(versionbuf));
|
||||
cry_strcat(errorString, versionbuf);
|
||||
cry_strcat(errorString, "\n");
|
||||
|
||||
char excCode[MAX_WARNING_LENGTH];
|
||||
char excAddr[80];
|
||||
char desc[1024];
|
||||
char excDesc[MAX_WARNING_LENGTH];
|
||||
|
||||
// make sure the mouse cursor is visible
|
||||
ShowCursor(TRUE);
|
||||
|
||||
const char* excName;
|
||||
if (m_bIsFatalError || !pex)
|
||||
{
|
||||
const char* const szMessage = m_bIsFatalError ? s_szFatalErrorCode : m_szBugMessage;
|
||||
excName = szMessage;
|
||||
cry_strcpy(excCode, szMessage);
|
||||
cry_strcpy(excAddr, "");
|
||||
cry_strcpy(desc, "");
|
||||
cry_strcpy(m_excModule, "");
|
||||
cry_strcpy(excDesc, szMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(excAddr, "0x%04X:0x%p", pex->ContextRecord->SegCs, pex->ExceptionRecord->ExceptionAddress);
|
||||
sprintf_s(excCode, "0x%08X", pex->ExceptionRecord->ExceptionCode);
|
||||
excName = TranslateExceptionCode(pex->ExceptionRecord->ExceptionCode);
|
||||
cry_strcpy(desc, "");
|
||||
sprintf_s(excDesc, "%s\r\n%s", excName, desc);
|
||||
|
||||
|
||||
if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
if (pex->ExceptionRecord->NumberParameters > 1)
|
||||
{
|
||||
ULONG_PTR iswrite = pex->ExceptionRecord->ExceptionInformation[0];
|
||||
DWORD64 accessAddr = pex->ExceptionRecord->ExceptionInformation[1];
|
||||
if (iswrite)
|
||||
{
|
||||
sprintf_s(desc, "Attempt to write data to address 0x%08llu\r\nThe memory could not be \"written\"", accessAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(desc, "Attempt to read from address 0x%08llu\r\nThe memory could not be \"read\"", accessAddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WriteLineToLog("Exception Code: %s", excCode);
|
||||
WriteLineToLog("Exception Addr: %s", excAddr);
|
||||
WriteLineToLog("Exception Module: %s", m_excModule);
|
||||
WriteLineToLog("Exception Name : %s", excName);
|
||||
WriteLineToLog("Exception Description: %s", desc);
|
||||
|
||||
|
||||
cry_strcpy(m_excDesc, excDesc);
|
||||
cry_strcpy(m_excAddr, excAddr);
|
||||
cry_strcpy(m_excCode, excCode);
|
||||
|
||||
|
||||
char errs[32768];
|
||||
sprintf_s(errs, "Exception Code: %s\nException Addr: %s\nException Module: %s\nException Description: %s, %s\n",
|
||||
excCode, excAddr, m_excModule, excName, desc);
|
||||
|
||||
|
||||
cry_strcat(errs, "\nCall Stack Trace:\n");
|
||||
|
||||
std::vector<string> funcs;
|
||||
{
|
||||
AZ::Debug::StackFrame frames[25];
|
||||
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
|
||||
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 3);
|
||||
if (numFrames)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
for (unsigned int i = 0; i < numFrames; i++)
|
||||
{
|
||||
funcs.push_back(lines[i]);
|
||||
}
|
||||
}
|
||||
dumpCallStack(funcs);
|
||||
// Fill call stack.
|
||||
char str[s_iCallStackSize];
|
||||
cry_strcpy(str, "");
|
||||
for (unsigned int i = 0; i < funcs.size(); i++)
|
||||
{
|
||||
char temp[s_iCallStackSize];
|
||||
sprintf_s(temp, "%2zd) %s", funcs.size() - i, (const char*)funcs[i].c_str());
|
||||
cry_strcat(str, temp);
|
||||
cry_strcat(str, "\r\n");
|
||||
cry_strcat(errs, temp);
|
||||
cry_strcat(errs, "\n");
|
||||
}
|
||||
cry_strcpy(m_excCallstack, str);
|
||||
}
|
||||
|
||||
cry_strcat(errorString, errs);
|
||||
|
||||
if (f)
|
||||
{
|
||||
fwrite(errorString, strlen(errorString), 1, f);
|
||||
{
|
||||
if (g_cvars.sys_dump_aux_threads)
|
||||
{
|
||||
for (int i = 0; i < g_nDebugThreads; i++)
|
||||
{
|
||||
if (g_idDebugThreads[i] != GetCurrentThreadId())
|
||||
{
|
||||
fprintf(f, "\n\nSuspended thread (%s):\n", g_nameDebugThreads[i]);
|
||||
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
|
||||
|
||||
// mirrors the AZ::Debug::Trace::PrintCallstack() functionality, but prints to a file
|
||||
{
|
||||
AZ::Debug::StackFrame frames[10];
|
||||
|
||||
// Without StackFrame explicit alignment frames array is aligned to 4 bytes
|
||||
// which causes the stack tracing to fail.
|
||||
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
|
||||
|
||||
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 0, hThread);
|
||||
if (numFrames)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
for (unsigned int i2 = 0; i2 < numFrames; ++i2)
|
||||
{
|
||||
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResumeThread(hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
MINIDUMP_TYPE mdumpValue;
|
||||
bool bDump = true;
|
||||
switch (g_cvars.sys_dump_type)
|
||||
{
|
||||
case 0:
|
||||
bDump = false;
|
||||
break;
|
||||
case 1:
|
||||
mdumpValue = MiniDumpNormal;
|
||||
break;
|
||||
case 2:
|
||||
mdumpValue = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithDataSegs);
|
||||
break;
|
||||
case 3:
|
||||
mdumpValue = MiniDumpWithFullMemory;
|
||||
break;
|
||||
default:
|
||||
mdumpValue = (MINIDUMP_TYPE)g_cvars.sys_dump_type;
|
||||
break;
|
||||
}
|
||||
if (bDump)
|
||||
{
|
||||
fileName = path + "error.dmp";
|
||||
|
||||
if (gEnv->IsDedicated() && stat(fileName.c_str(), &fileInfo) == 0)
|
||||
{
|
||||
// Backup dump (use timestamp from error.log if available)
|
||||
if (timeStamp.empty())
|
||||
{
|
||||
tm creationTime;
|
||||
localtime_s(&creationTime, &fileInfo.st_mtime);
|
||||
char tempBuffer[32];
|
||||
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
|
||||
timeStamp = tempBuffer;
|
||||
}
|
||||
|
||||
string backupFileName = backupPath + timeStamp + " error.dmp";
|
||||
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
|
||||
}
|
||||
|
||||
CryEngineExceptionFilterMiniDump(pex, fileName.c_str(), mdumpValue);
|
||||
}
|
||||
}
|
||||
|
||||
//if no crash dialog don't even submit the bug
|
||||
if (m_postBackupProcess && g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog)
|
||||
{
|
||||
m_postBackupProcess();
|
||||
}
|
||||
else
|
||||
{
|
||||
// lawsonn: Disabling the JIRA-based crash reporter for now
|
||||
// we'll need to deal with it our own way, pending QA.
|
||||
// if you're customizing the engine this is also your opportunity to deal with it.
|
||||
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
|
||||
{
|
||||
// ------------ place custom crash handler here ---------------------
|
||||
// it should launch an executable!
|
||||
/// by this time, error.bmp will be in the engine root folder
|
||||
// error.log and error.dmp will also be present in the engine root folder
|
||||
// if your error dumper wants those, it should zip them up and send them or offer to do so.
|
||||
// ------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
const bool bQuitting = !gEnv || !gEnv->pSystem || gEnv->pSystem->IsQuitting();
|
||||
|
||||
//[AlexMcC|16.04.10] When the engine is shutting down, MessageBox doesn't display a box
|
||||
// and immediately returns IDYES. Avoid this by just not trying to save if we're quitting.
|
||||
// Don't ask to save if this isn't a real crash (a real crash has exception pointers)
|
||||
if (g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog && gEnv->IsEditor() && !bQuitting && pex)
|
||||
{
|
||||
BackupCurrentLevel();
|
||||
|
||||
const INT_PTR res = DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CONFIRM_SAVE_LEVEL), NULL, DebugCallStack::ConfirmSaveDialogProc, NULL);
|
||||
if (res == IDB_CONFIRM_SAVE)
|
||||
{
|
||||
if (SaveCurrentLevel())
|
||||
{
|
||||
MessageBox(NULL, "Level has been successfully saved!\r\nPress Ok to terminate Editor.", "Save", MB_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox(NULL, "Error saving level.\r\nPress Ok to terminate Editor.", "Save", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
|
||||
{
|
||||
// terminate immediately - since we're in a crash, there is no point unwinding stack, we've already done access violation or worse.
|
||||
// calling exit will only cause further death down the line...
|
||||
TerminateProcess(GetCurrentProcess(), pex->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INT_PTR CALLBACK DebugCallStack::ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static EXCEPTION_POINTERS* pex;
|
||||
|
||||
static char errorString[32768] = "";
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
pex = (EXCEPTION_POINTERS*)lParam;
|
||||
HWND h;
|
||||
|
||||
if (pex->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
|
||||
{
|
||||
// Disable continue button for non continuable exceptions.
|
||||
//h = GetDlgItem( hwndDlg,IDB_CONTINUE );
|
||||
//if (h) EnableWindow( h,FALSE );
|
||||
}
|
||||
|
||||
DebugCallStack* pDCS = static_cast<DebugCallStack*>(DebugCallStack::instance());
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_DESC);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excDesc);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_CODE);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excCode);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_MODULE);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excModule);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_ADDRESS);
|
||||
if (h)
|
||||
{
|
||||
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excAddr);
|
||||
}
|
||||
|
||||
// Fill call stack.
|
||||
HWND callStack = GetDlgItem(hwndDlg, IDC_CALLSTACK);
|
||||
if (callStack)
|
||||
{
|
||||
SendMessage(callStack, WM_SETTEXT, FALSE, (LPARAM)pDCS->m_excCallstack);
|
||||
}
|
||||
|
||||
if (hwndException)
|
||||
{
|
||||
DestroyWindow(hwndException);
|
||||
hwndException = 0;
|
||||
}
|
||||
|
||||
if (IsFloatingPointException(pex))
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDB_IGNORE), TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDB_EXIT:
|
||||
case IDB_IGNORE:
|
||||
// Fall through.
|
||||
|
||||
EndDialog(hwndDlg, wParam);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK DebugCallStack::ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, [[maybe_unused]] LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// The user might be holding down the spacebar while the engine crashes.
|
||||
// If we don't remove keyboard focus from this dialog, the keypress will
|
||||
// press the default button before the dialog actually appears, even if
|
||||
// the user has already released the key, which is bad.
|
||||
SetFocus(NULL);
|
||||
} break;
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDB_CONFIRM_SAVE: // Fall through
|
||||
case IDB_DONT_SAVE:
|
||||
{
|
||||
EndDialog(hwndDlg, wParam);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool DebugCallStack::BackupCurrentLevel()
|
||||
{
|
||||
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
|
||||
if (pSystem && pSystem->GetUserCallback())
|
||||
{
|
||||
return pSystem->GetUserCallback()->OnBackupDocument();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebugCallStack::SaveCurrentLevel()
|
||||
{
|
||||
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
|
||||
if (pSystem && pSystem->GetUserCallback())
|
||||
{
|
||||
return pSystem->GetUserCallback()->OnSaveDocument();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
int ret = IDB_EXIT;
|
||||
|
||||
assert(!hwndException);
|
||||
|
||||
RemoveOldFiles();
|
||||
|
||||
AZ::Debug::Trace::PrintCallstack("", 2);
|
||||
|
||||
LogExceptionInfo(exception_pointer);
|
||||
|
||||
if (IsFloatingPointException(exception_pointer))
|
||||
{
|
||||
//! Print exception dialog.
|
||||
ret = PrintException(exception_pointer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DebugCallStack::ResetFPU(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
if (IsFloatingPointException(pex))
|
||||
{
|
||||
// How to reset FPU: http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_10310953.html
|
||||
_clearfp();
|
||||
#ifndef WIN64
|
||||
pex->ContextRecord->FloatSave.ControlWord |= 0x2F;
|
||||
pex->ContextRecord->FloatSave.StatusWord &= ~0x8080;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
string DebugCallStack::GetModuleNameForAddr(void* addr)
|
||||
{
|
||||
if (m_modules.empty())
|
||||
{
|
||||
return "[unknown]";
|
||||
}
|
||||
|
||||
if (addr < m_modules.begin()->first)
|
||||
{
|
||||
return "[unknown]";
|
||||
}
|
||||
|
||||
TModules::const_iterator it = m_modules.begin();
|
||||
TModules::const_iterator end = m_modules.end();
|
||||
for (; ++it != end; )
|
||||
{
|
||||
if (addr < it->first)
|
||||
{
|
||||
return (--it)->second;
|
||||
}
|
||||
}
|
||||
|
||||
//if address is higher than the last module, we simply assume it is in the last module.
|
||||
return m_modules.rbegin()->second;
|
||||
}
|
||||
|
||||
void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
|
||||
{
|
||||
AZ::Debug::SymbolStorage::StackLine func, file, module;
|
||||
AZ::Debug::SymbolStorage::FindFunctionFromIP(addr, &func, &file, &module, line, baseAddr);
|
||||
procName = func;
|
||||
filename = file;
|
||||
}
|
||||
|
||||
string DebugCallStack::GetCurrentFilename()
|
||||
{
|
||||
char fullpath[MAX_PATH_LENGTH + 1];
|
||||
GetModuleFileName(NULL, fullpath, MAX_PATH_LENGTH);
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex)
|
||||
{
|
||||
if (!pex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD exceptionCode = pex->ExceptionRecord->ExceptionCode;
|
||||
switch (exceptionCode)
|
||||
{
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int DebugCallStack::PrintException(EXCEPTION_POINTERS* exception_pointer)
|
||||
{
|
||||
return (int)DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CRITICAL_ERROR), NULL, DebugCallStack::ExceptionDialogProc, (LPARAM)exception_pointer);
|
||||
}
|
||||
|
||||
#else
|
||||
void MarkThisThreadForDebugging(const char*) {}
|
||||
void UnmarkThisThreadFromDebugging() {}
|
||||
void UpdateFPExceptionsMaskForThreads() {}
|
||||
#endif //WIN32
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "IDebugCallStack.h"
|
||||
|
||||
#if defined (WIN32) || defined (WIN64)
|
||||
|
||||
//! Limits the maximal number of functions in call stack.
|
||||
const int MAX_DEBUG_STACK_ENTRIES_FILE_DUMP = 12;
|
||||
|
||||
struct ISystem;
|
||||
|
||||
//!============================================================================
|
||||
//!
|
||||
//! DebugCallStack class, capture call stack information from symbol files.
|
||||
//!
|
||||
//!============================================================================
|
||||
class DebugCallStack
|
||||
: public IDebugCallStack
|
||||
{
|
||||
public:
|
||||
DebugCallStack();
|
||||
virtual ~DebugCallStack();
|
||||
|
||||
ISystem* GetSystem() { return m_pSystem; };
|
||||
|
||||
virtual string GetModuleNameForAddr(void* addr);
|
||||
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line);
|
||||
virtual string GetCurrentFilename();
|
||||
|
||||
void installErrorHandler(ISystem* pSystem);
|
||||
virtual int handleException(EXCEPTION_POINTERS* exception_pointer);
|
||||
|
||||
virtual void ReportBug(const char*);
|
||||
|
||||
void dumpCallStack(std::vector<string>& functions);
|
||||
|
||||
void SetUserDialogEnable(const bool bUserDialogEnable);
|
||||
|
||||
typedef std::map<void*, string> TModules;
|
||||
protected:
|
||||
static void RemoveOldFiles();
|
||||
static void RemoveFile(const char* szFileName);
|
||||
|
||||
static int PrintException(EXCEPTION_POINTERS* exception_pointer);
|
||||
static INT_PTR CALLBACK ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR CALLBACK ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void LogExceptionInfo(EXCEPTION_POINTERS* exception_pointer);
|
||||
bool BackupCurrentLevel();
|
||||
bool SaveCurrentLevel();
|
||||
int SubmitBug(EXCEPTION_POINTERS* exception_pointer);
|
||||
void ResetFPU(EXCEPTION_POINTERS* pex);
|
||||
|
||||
static const int s_iCallStackSize = 32768;
|
||||
|
||||
char m_excLine[256];
|
||||
char m_excModule[128];
|
||||
|
||||
char m_excDesc[MAX_WARNING_LENGTH];
|
||||
char m_excCode[MAX_WARNING_LENGTH];
|
||||
char m_excAddr[80];
|
||||
char m_excCallstack[s_iCallStackSize];
|
||||
|
||||
void* prevExceptionHandler;
|
||||
|
||||
bool m_bCrash;
|
||||
const char* m_szBugMessage;
|
||||
|
||||
ISystem* m_pSystem;
|
||||
|
||||
int m_nSkipNumFunctions;
|
||||
CONTEXT m_context;
|
||||
|
||||
TModules m_modules;
|
||||
};
|
||||
|
||||
#endif //WIN32
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "System.h"
|
||||
#include <AZCrySystemInitLogSink.h>
|
||||
#include "DebugCallStack.h"
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#undef AZ_RESTRICTED_SECTION
|
||||
@@ -87,6 +88,16 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar
|
||||
startupParams.pUserCallback->OnSystemConnect(pSystem);
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
// Environment Variable to signal we don't want to override our exception handler - our crash report system will set this
|
||||
auto envVar = AZ::Environment::FindVariable<bool>("ExceptionHandlerIsSet");
|
||||
const bool handlerIsSet = (envVar && *envVar);
|
||||
if (!handlerIsSet)
|
||||
{
|
||||
((DebugCallStack*)IDebugCallStack::instance())->installErrorHandler(pSystem);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool retVal = false;
|
||||
{
|
||||
AZ::Debug::StartupLogSinkReporter<AZ::Debug::CrySystemInitLogSink> initLogSink;
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : A multiplatform base class for handling errors and collecting call stacks
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
#include "IDebugCallStack.h"
|
||||
#include "System.h"
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
//#if !defined(LINUX)
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
const char* const IDebugCallStack::s_szFatalErrorCode = "FATAL_ERROR";
|
||||
|
||||
IDebugCallStack::IDebugCallStack()
|
||||
: m_bIsFatalError(false)
|
||||
, m_postBackupProcess(0)
|
||||
, m_memAllocFileHandle(AZ::IO::InvalidHandle)
|
||||
{
|
||||
}
|
||||
|
||||
IDebugCallStack::~IDebugCallStack()
|
||||
{
|
||||
StopMemLog();
|
||||
}
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_SINGLETON
|
||||
IDebugCallStack* IDebugCallStack::instance()
|
||||
{
|
||||
static IDebugCallStack sInstance;
|
||||
return &sInstance;
|
||||
}
|
||||
#endif
|
||||
|
||||
void IDebugCallStack::FileCreationCallback(void (* postBackupProcess)())
|
||||
{
|
||||
m_postBackupProcess = postBackupProcess;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::LogCallstack()
|
||||
{
|
||||
AZ::Debug::Trace::PrintCallstack("", 2);
|
||||
}
|
||||
|
||||
const char* IDebugCallStack::TranslateExceptionCode(DWORD dwExcept)
|
||||
{
|
||||
switch (dwExcept)
|
||||
{
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_TRANSLATE
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
return "EXCEPTION_ACCESS_VIOLATION";
|
||||
break;
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT:
|
||||
return "EXCEPTION_DATATYPE_MISALIGNMENT";
|
||||
break;
|
||||
case EXCEPTION_BREAKPOINT:
|
||||
return "EXCEPTION_BREAKPOINT";
|
||||
break;
|
||||
case EXCEPTION_SINGLE_STEP:
|
||||
return "EXCEPTION_SINGLE_STEP";
|
||||
break;
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
|
||||
return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
|
||||
break;
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
return "EXCEPTION_FLT_DENORMAL_OPERAND";
|
||||
break;
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
|
||||
break;
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
return "EXCEPTION_FLT_INEXACT_RESULT";
|
||||
break;
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
return "EXCEPTION_FLT_INVALID_OPERATION";
|
||||
break;
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
return "EXCEPTION_FLT_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
return "EXCEPTION_FLT_STACK_CHECK";
|
||||
break;
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
return "EXCEPTION_FLT_UNDERFLOW";
|
||||
break;
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
||||
return "EXCEPTION_INT_DIVIDE_BY_ZERO";
|
||||
break;
|
||||
case EXCEPTION_INT_OVERFLOW:
|
||||
return "EXCEPTION_INT_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_PRIV_INSTRUCTION:
|
||||
return "EXCEPTION_PRIV_INSTRUCTION";
|
||||
break;
|
||||
case EXCEPTION_IN_PAGE_ERROR:
|
||||
return "EXCEPTION_IN_PAGE_ERROR";
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
return "EXCEPTION_ILLEGAL_INSTRUCTION";
|
||||
break;
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
|
||||
return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
return "EXCEPTION_STACK_OVERFLOW";
|
||||
break;
|
||||
case EXCEPTION_INVALID_DISPOSITION:
|
||||
return "EXCEPTION_INVALID_DISPOSITION";
|
||||
break;
|
||||
case EXCEPTION_GUARD_PAGE:
|
||||
return "EXCEPTION_GUARD_PAGE";
|
||||
break;
|
||||
case EXCEPTION_INVALID_HANDLE:
|
||||
return "EXCEPTION_INVALID_HANDLE";
|
||||
break;
|
||||
//case EXCEPTION_POSSIBLE_DEADLOCK: return "EXCEPTION_POSSIBLE_DEADLOCK"; break ;
|
||||
|
||||
case STATUS_FLOAT_MULTIPLE_FAULTS:
|
||||
return "STATUS_FLOAT_MULTIPLE_FAULTS";
|
||||
break;
|
||||
case STATUS_FLOAT_MULTIPLE_TRAPS:
|
||||
return "STATUS_FLOAT_MULTIPLE_TRAPS";
|
||||
break;
|
||||
|
||||
|
||||
#endif
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IDebugCallStack::PutVersion(char* str, size_t length)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
|
||||
|
||||
if (!gEnv || !gEnv->pSystem)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sFileVersion[128];
|
||||
gEnv->pSystem->GetFileVersion().ToString(sFileVersion, sizeof(sFileVersion));
|
||||
|
||||
char sProductVersion[128];
|
||||
gEnv->pSystem->GetProductVersion().ToString(sProductVersion, sizeof(sFileVersion));
|
||||
|
||||
|
||||
//! Get time.
|
||||
time_t ltime;
|
||||
time(<ime);
|
||||
tm* today = localtime(<ime);
|
||||
|
||||
char s[1024];
|
||||
//! Use strftime to build a customized time string.
|
||||
strftime(s, 128, "Logged at %#c\n", today);
|
||||
azstrcat(str, length, s);
|
||||
sprintf_s(s, "FileVersion: %s\n", sFileVersion);
|
||||
azstrcat(str, length, s);
|
||||
sprintf_s(s, "ProductVersion: %s\n", sProductVersion);
|
||||
azstrcat(str, length, s);
|
||||
|
||||
if (gEnv->pLog)
|
||||
{
|
||||
const char* logfile = gEnv->pLog->GetFileName();
|
||||
if (logfile)
|
||||
{
|
||||
sprintf (s, "LogFile: %s\n", logfile);
|
||||
azstrcat(str, length, s);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
azstrcat(str, length, "ProjectDir: ");
|
||||
azstrcat(str, length, projectPath.c_str());
|
||||
azstrcat(str, length, "\n");
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME
|
||||
GetModuleFileNameA(NULL, s, sizeof(s));
|
||||
|
||||
// Log EXE filename only if possible (not full EXE path which could contain sensitive info)
|
||||
AZStd::string exeName;
|
||||
if (AZ::StringFunc::Path::GetFullFileName(s, exeName))
|
||||
{
|
||||
azstrcat(str, length, "Executable: ");
|
||||
azstrcat(str, length, exeName.c_str());
|
||||
|
||||
# ifdef AZ_DEBUG_BUILD
|
||||
azstrcat(str, length, " (debug: yes");
|
||||
# else
|
||||
azstrcat(str, length, " (debug: no");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
AZ_POP_DISABLE_WARNING
|
||||
}
|
||||
|
||||
|
||||
//Crash the application, in this way the debug callstack routine will be called and it will create all the necessary files (error.log, dump, and eventually screenshot)
|
||||
void IDebugCallStack::FatalError(const char* description)
|
||||
{
|
||||
m_bIsFatalError = true;
|
||||
WriteLineToLog(description);
|
||||
|
||||
#ifndef _RELEASE
|
||||
bool bShowDebugScreen = g_cvars.sys_no_crash_dialog == 0;
|
||||
// showing the debug screen is not safe when not called from mainthread
|
||||
// it normally leads to a infinity recursion followed by a stack overflow, preventing
|
||||
// useful call stacks, thus they are disabled
|
||||
bShowDebugScreen = bShowDebugScreen && gEnv->mMainThreadId == CryGetCurrentThreadId();
|
||||
if (bShowDebugScreen)
|
||||
{
|
||||
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Open 3D Engine Fatal Error", description, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || !defined(_RELEASE)
|
||||
int* p = 0x0;
|
||||
PREFAST_SUPPRESS_WARNING(6011) * p = 1; // we're intentionally crashing here
|
||||
#endif
|
||||
}
|
||||
|
||||
void IDebugCallStack::WriteLineToLog(const char* format, ...)
|
||||
{
|
||||
va_list ArgList;
|
||||
char szBuffer[MAX_WARNING_LENGTH];
|
||||
va_start(ArgList, format);
|
||||
vsnprintf_s(szBuffer, sizeof(szBuffer), sizeof(szBuffer) - 1, format, ArgList);
|
||||
cry_strcat(szBuffer, "\n");
|
||||
szBuffer[sizeof(szBuffer) - 1] = '\0';
|
||||
va_end(ArgList);
|
||||
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\error.log", AZ::IO::GetOpenModeFromStringMode("a+t"), fileHandle);
|
||||
if (fileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Write(fileHandle, szBuffer, strlen(szBuffer));
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Flush(fileHandle);
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Close(fileHandle);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::StartMemLog()
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\memallocfile.log", AZ::IO::OpenMode::ModeWrite, m_memAllocFileHandle);
|
||||
|
||||
assert(m_memAllocFileHandle != AZ::IO::InvalidHandle);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void IDebugCallStack::StopMemLog()
|
||||
{
|
||||
if (m_memAllocFileHandle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
AZ::IO::FileIOBase::GetDirectInstance()->Close(m_memAllocFileHandle);
|
||||
m_memAllocFileHandle = AZ::IO::InvalidHandle;
|
||||
}
|
||||
}
|
||||
//#endif //!defined(LINUX)
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : A multiplatform base class for handling errors and collecting call stacks
|
||||
|
||||
#ifndef CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
#pragma once
|
||||
|
||||
#include "System.h"
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_FORWARD_EXCEPTION_POINTERS
|
||||
struct EXCEPTION_POINTERS;
|
||||
#endif
|
||||
//! Limits the maximal number of functions in call stack.
|
||||
enum
|
||||
{
|
||||
MAX_DEBUG_STACK_ENTRIES = 80
|
||||
};
|
||||
|
||||
class IDebugCallStack
|
||||
{
|
||||
public:
|
||||
// Returns single instance of DebugStack
|
||||
static IDebugCallStack* instance();
|
||||
|
||||
virtual int handleException([[maybe_unused]] EXCEPTION_POINTERS* exception_pointer){return 0; }
|
||||
|
||||
// returns the module name of a given address
|
||||
virtual string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; }
|
||||
|
||||
// returns the function name of a given address together with source file and line number (if available) of a given address
|
||||
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
|
||||
{
|
||||
filename = "[unknown]";
|
||||
line = 0;
|
||||
baseAddr = addr;
|
||||
#if defined(PLATFORM_64BIT)
|
||||
procName.Format("[%016llX]", addr);
|
||||
#else
|
||||
procName.Format("[%08X]", addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// returns current filename
|
||||
virtual string GetCurrentFilename() { return "[unknown]"; }
|
||||
|
||||
//! Dumps Current Call Stack to log.
|
||||
virtual void LogCallstack();
|
||||
//triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application
|
||||
void FatalError(const char*);
|
||||
|
||||
//Reports a bug and continues execution
|
||||
virtual void ReportBug(const char*) {}
|
||||
|
||||
virtual void FileCreationCallback(void (* postBackupProcess)());
|
||||
|
||||
static void WriteLineToLog(const char* format, ...);
|
||||
|
||||
virtual void StartMemLog();
|
||||
virtual void StopMemLog();
|
||||
|
||||
protected:
|
||||
IDebugCallStack();
|
||||
virtual ~IDebugCallStack();
|
||||
|
||||
static const char* TranslateExceptionCode(DWORD dwExcept);
|
||||
static void PutVersion(char* str, size_t length);
|
||||
|
||||
bool m_bIsFatalError;
|
||||
static const char* const s_szFatalErrorCode;
|
||||
|
||||
void (* m_postBackupProcess)();
|
||||
|
||||
AZ::IO::HandleType m_memAllocFileHandle;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "IMovieSystem.h"
|
||||
#include <ILocalizationManager.h>
|
||||
#include "CryPath.h"
|
||||
#include <Pak/CryPakUtils.h>
|
||||
|
||||
#include <LoadScreenBus.h>
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "CryZlib.h"
|
||||
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <ISystem.h>
|
||||
#include "System.h"
|
||||
#include "CryPath.h" // PathUtil::ReplaceExtension()
|
||||
#include <Pak/CryPakUtils.h>
|
||||
#include "UnicodeFunctions.h"
|
||||
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
@@ -237,7 +236,6 @@ void CLog::CloseLogFile([[maybe_unused]] bool forceClose)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode)
|
||||
{
|
||||
CDebugAllowFileAccess ignoreInvalidFileAccess;
|
||||
using namespace AZ::IO;
|
||||
|
||||
AZ_Assert(m_logFileHandle == AZ::IO::InvalidHandle, "Attempt to open log file when one is already open. This would lead to a handle leak.");
|
||||
@@ -1116,8 +1114,6 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
|
||||
|
||||
if (logToFile)
|
||||
{
|
||||
CDebugAllowFileAccess dafa;
|
||||
|
||||
if (m_logFileHandle == AZ::IO::InvalidHandle)
|
||||
{
|
||||
OpenLogFile(m_szFilename, "w+t");
|
||||
|
||||
@@ -208,6 +208,7 @@ struct SSystemCVars
|
||||
int sys_no_crash_dialog;
|
||||
int sys_no_error_report_window;
|
||||
int sys_dump_aux_threads;
|
||||
int sys_WER;
|
||||
int sys_dump_type;
|
||||
int sys_ai;
|
||||
int sys_entitysystem;
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
#include <HMDBus.h>
|
||||
|
||||
#include <AzFramework/Archive/Archive.h>
|
||||
#include <Pak/CryPakUtils.h>
|
||||
#include "XConsole.h"
|
||||
#include "Log.h"
|
||||
#include "XML/xml.h"
|
||||
@@ -122,6 +121,10 @@
|
||||
# include <AzFramework/Network/AssetProcessorConnection.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
|
||||
#endif
|
||||
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_14
|
||||
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
||||
@@ -1485,6 +1488,13 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
InlineInitializationProcessing("CSystem::Init LoadConfigurations");
|
||||
|
||||
#ifdef WIN32
|
||||
if (g_cvars.sys_WER)
|
||||
{
|
||||
SetUnhandledExceptionFilter(CryEngineExceptionFilterWER);
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Localization
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -2021,6 +2031,14 @@ void CSystem::CreateSystemVars()
|
||||
REGISTER_CVAR2("sys_update_profile_time", &g_cvars.sys_update_profile_time, 1.0f, 0, "Time to keep updates timings history for.");
|
||||
REGISTER_CVAR2("sys_no_crash_dialog", &g_cvars.sys_no_crash_dialog, m_bNoCrashDialog, VF_NULL, "Whether to disable the crash dialog window");
|
||||
REGISTER_CVAR2("sys_no_error_report_window", &g_cvars.sys_no_error_report_window, m_bNoErrorReportWindow, VF_NULL, "Whether to disable the error report list");
|
||||
#if defined(_RELEASE)
|
||||
if (!gEnv->IsDedicated())
|
||||
{
|
||||
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 1, 0, "Enables Windows Error Reporting");
|
||||
}
|
||||
#else
|
||||
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 0, 0, "Enables Windows Error Reporting");
|
||||
#endif
|
||||
|
||||
#ifdef USE_HTTP_WEBSOCKETS
|
||||
REGISTER_CVAR2("sys_simple_http_base_port", &g_cvars.sys_simple_http_base_port, 1880, VF_REQUIRE_APP_RESTART,
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
#include "IDebugCallStack.h"
|
||||
|
||||
#if defined(APPLE) || defined(LINUX)
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@@ -355,6 +357,7 @@ void CSystem::FatalError(const char* format, ...)
|
||||
}
|
||||
|
||||
// Dump callstack.
|
||||
IDebugCallStack::instance()->FatalError(szBuffer);
|
||||
#endif
|
||||
|
||||
CryDebugBreak();
|
||||
@@ -396,6 +399,8 @@ void CSystem::ReportBug([[maybe_unused]] const char* format, ...)
|
||||
va_start(ArgList, format);
|
||||
azvsnprintf(szBuffer + strlen(sPrefix), MAX_WARNING_LENGTH - strlen(sPrefix), format, ArgList);
|
||||
va_end(ArgList);
|
||||
|
||||
IDebugCallStack::instance()->ReportBug(szBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Support for Windows Error Reporting (WER)
|
||||
|
||||
|
||||
#include "CrySystem_precompiled.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include "System.h"
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include "errorrep.h"
|
||||
#include "ISystem.h"
|
||||
|
||||
#include <DbgHelp.h>
|
||||
|
||||
static WCHAR szPath[MAX_PATH + 1];
|
||||
static WCHAR szFR[] = L"\\System32\\FaultRep.dll";
|
||||
|
||||
WCHAR* GetFullPathToFaultrepDll(void)
|
||||
{
|
||||
UINT rc = GetSystemWindowsDirectoryW(szPath, ARRAYSIZE(szPath));
|
||||
if (rc == 0 || rc > ARRAYSIZE(szPath) - ARRAYSIZE(szFR) - 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wcscat_s(szPath, szFR);
|
||||
return szPath;
|
||||
}
|
||||
|
||||
|
||||
typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,
|
||||
CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
|
||||
CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE DumpType)
|
||||
{
|
||||
// note: In debug mode, this dll is loaded on startup anyway, so this should not incur an additional load unless it crashes
|
||||
// very early during startup.
|
||||
|
||||
fflush(nullptr); // according to MSDN on fflush, calling fflush on null flushes all buffers.
|
||||
HMODULE hndDBGHelpDLL = LoadLibraryA("DBGHELP.DLL");
|
||||
|
||||
if (!hndDBGHelpDLL)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: Could not open DBGHELP.DLL");
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
MINIDUMPWRITEDUMP dumpFnPtr = (MINIDUMPWRITEDUMP)::GetProcAddress(hndDBGHelpDLL, "MiniDumpWriteDump");
|
||||
if (!dumpFnPtr)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: Unable to find MiniDumpWriteDump in DBGHELP.DLL");
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: could not open file '%s' for writing - error code: %d", szDumpPath, GetLastError());
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
_MINIDUMP_EXCEPTION_INFORMATION ExInfo;
|
||||
ExInfo.ThreadId = ::GetCurrentThreadId();
|
||||
ExInfo.ExceptionPointers = pExceptionPointers;
|
||||
ExInfo.ClientPointers = NULL;
|
||||
|
||||
BOOL bOK = dumpFnPtr(GetCurrentProcess(), GetCurrentProcessId(), hFile, DumpType, &ExInfo, NULL, NULL);
|
||||
::CloseHandle(hFile);
|
||||
|
||||
if (bOK)
|
||||
{
|
||||
CryLogAlways("Successfully recorded DMP file: '%s'", szDumpPath);
|
||||
return EXCEPTION_EXECUTE_HANDLER; // SUCCESS! you can execute your handlers now
|
||||
}
|
||||
else
|
||||
{
|
||||
CryLogAlways("Failed to record DMP file: '%s' - error code: %d", szDumpPath, GetLastError());
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers)
|
||||
{
|
||||
if (g_cvars.sys_WER > 1)
|
||||
{
|
||||
char szScratch [_MAX_PATH];
|
||||
const char* szDumpPath = gEnv->pCryPak->AdjustFileName("@log@/CE2Dump.dmp", szScratch, AZ_ARRAY_SIZE(szScratch), 0);
|
||||
|
||||
MINIDUMP_TYPE mdumpValue = (MINIDUMP_TYPE)(MiniDumpNormal);
|
||||
if (g_cvars.sys_WER > 1)
|
||||
{
|
||||
mdumpValue = (MINIDUMP_TYPE)(g_cvars.sys_WER - 2);
|
||||
}
|
||||
|
||||
return CryEngineExceptionFilterMiniDump(pExceptionPointers, szDumpPath, mdumpValue);
|
||||
}
|
||||
|
||||
LONG lRet = EXCEPTION_CONTINUE_SEARCH;
|
||||
WCHAR* psz = GetFullPathToFaultrepDll();
|
||||
if (psz)
|
||||
{
|
||||
HMODULE hFaultRepDll = LoadLibraryW(psz);
|
||||
if (hFaultRepDll)
|
||||
{
|
||||
pfn_REPORTFAULT pfn = (pfn_REPORTFAULT)GetProcAddress(hFaultRepDll, "ReportFault");
|
||||
if (pfn)
|
||||
{
|
||||
pfn(pExceptionPointers, 0);
|
||||
lRet = EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
FreeLibrary(hFaultRepDll);
|
||||
}
|
||||
}
|
||||
return lRet;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
@@ -15,6 +15,8 @@ set(FILES
|
||||
CmdLineArg.cpp
|
||||
ConsoleBatchFile.cpp
|
||||
ConsoleHelpGen.cpp
|
||||
DebugCallStack.cpp
|
||||
IDebugCallStack.cpp
|
||||
Log.cpp
|
||||
System.cpp
|
||||
SystemCFG.cpp
|
||||
@@ -31,6 +33,8 @@ set(FILES
|
||||
CmdLineArg.h
|
||||
ConsoleBatchFile.h
|
||||
ConsoleHelpGen.h
|
||||
DebugCallStack.h
|
||||
IDebugCallStack.h
|
||||
Log.h
|
||||
SimpleStringPool.h
|
||||
CrySystem_precompiled.h
|
||||
@@ -72,4 +76,5 @@ set(FILES
|
||||
ViewSystem/ViewSystem.cpp
|
||||
ViewSystem/ViewSystem.h
|
||||
CrySystem_precompiled.cpp
|
||||
WindowsErrorReporting.cpp
|
||||
)
|
||||
|
||||
@@ -20,10 +20,12 @@
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
//! Simple class for verifying that no concurrent access is occuring.
|
||||
//! Simple class for verifying that no concurrent access is occurring.
|
||||
//! This is *not* a synchronization primitive, and is intended simply for checking that no concurrency issues exist.
|
||||
//! It will be compiled out in release builds.
|
||||
//! Use concurrency_checker like a mutex (i.e. call soft_lock() and soft_unlock() around all instances of your data access).
|
||||
//! Use soft_lock_shared and soft_unlock_shared around places where multiple threads are allowed to have read access
|
||||
//! at the same time as long as nothing else already has a soft lock
|
||||
//! It will assert if there are multiple threads accessing the locked code/data at the same time.
|
||||
//! Expected use case is for defensive programming: when you do not expect any concurrent access within a system,
|
||||
//! but want to verify that it stays that way in the future, without incurring the overhead of a mutex.
|
||||
@@ -34,7 +36,7 @@ namespace AZStd
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
uint32_t count = ++m_concurrencyCounter;
|
||||
AZ_Assert(count == 1, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch.");
|
||||
AZ_Assert(count == 1 && m_sharedConcurrencyCounter == 0, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch.");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,9 +48,27 @@ namespace AZStd
|
||||
#endif
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE void soft_lock_shared()
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZ_Assert(m_concurrencyCounter == 0, "Concurrency check failed. A soft_lock_shared was attempted when there was already a soft_lock.");
|
||||
++m_sharedConcurrencyCounter;
|
||||
#endif
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE void soft_unlock_shared()
|
||||
{
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZ_Assert(m_sharedConcurrencyCounter != 0, "Concurrency check failed. There is a shared_lock/shared_unlock mismatch.");
|
||||
--m_sharedConcurrencyCounter;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
#ifdef AZ_CONCURRENCY_CHECKER_ENABLED
|
||||
AZStd::atomic_uint32_t m_concurrencyCounter = 0;
|
||||
AZStd::atomic_uint32_t m_sharedConcurrencyCounter = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -293,15 +293,12 @@ namespace UnitTest
|
||||
{
|
||||
array_view<int> view({ 1,2,3,4 });
|
||||
|
||||
UnitTest::TestRunner::Instance().StartAssertTests();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
|
||||
EXPECT_EQ(0, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
view[4];
|
||||
EXPECT_EQ(1, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
view[5];
|
||||
EXPECT_EQ(2, UnitTest::TestRunner::Instance().m_numAssertsFailed);
|
||||
|
||||
UnitTest::TestRunner::Instance().StopAssertTests();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomCore/std/parallel/concurrency_checker.h>
|
||||
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
|
||||
using namespace AZStd;
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class ConcurrencyCheckerTestFixture
|
||||
: public AllocatorsTestFixture
|
||||
{
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLock_NoContention_NoAsserts)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLock_AlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftUnlock_NotAlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_unlock();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLockShared_NoContention_NoAsserts)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
// Multiple shared locks can be made at once,
|
||||
// as long as they are all unlocked before the next soft_lock
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
concurrencyChecker.soft_unlock();
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftLockShared_SharedLockAfterSoftLock_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
|
||||
concurrencyChecker.soft_lock();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AllocatorsTestFixture, SoftUnlockShared_NotAlreadyLocked_Assert)
|
||||
{
|
||||
concurrency_checker concurrencyChecker;
|
||||
concurrencyChecker.soft_lock_shared();
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
concurrencyChecker.soft_unlock_shared();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
set(FILES
|
||||
ArrayView.cpp
|
||||
ConcurrencyCheckerTests.cpp
|
||||
InstanceDatabase.cpp
|
||||
JsonSerializationUtilsTests.cpp
|
||||
lru_cache.cpp
|
||||
|
||||
@@ -307,6 +307,8 @@ namespace AZ
|
||||
Asset(AssetLoadBehavior loadBehavior = AssetLoadBehavior::Default);
|
||||
/// Create an asset from a valid asset data (created asset), might not be loaded or currently loading.
|
||||
Asset(AssetData* assetData, AssetLoadBehavior loadBehavior);
|
||||
/// Create an asset from a valid asset data (created asset) and set the asset id for both, might not be loaded or currently loading.
|
||||
Asset(const AZ::Data::AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior);
|
||||
/// Initialize asset pointer with id, type, and hint. No data construction will occur until QueueLoad is called.
|
||||
Asset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint = AZStd::string());
|
||||
|
||||
@@ -787,6 +789,18 @@ namespace AZ
|
||||
SetData(assetData);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
template<class T>
|
||||
Asset<T>::Asset(const AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior)
|
||||
: m_assetId(id)
|
||||
, m_assetType(azrtti_typeid<T>())
|
||||
, m_loadBehavior(loadBehavior)
|
||||
{
|
||||
AZ_Assert(!assetData->m_assetId.IsValid(), "Asset data already has an ID set.");
|
||||
assetData->m_assetId = id;
|
||||
SetData(assetData);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
template<class T>
|
||||
Asset<T>::Asset(const AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint)
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a pointer to the beginning of master vector of SmallAllocationGroups.
|
||||
/// Returns a pointer to the beginning of vector of SmallAllocationGroups.
|
||||
SmallAllocationGroup* ArrayHead()
|
||||
{
|
||||
return this - m_index;
|
||||
@@ -169,7 +169,7 @@ namespace AZ
|
||||
return m_marker == MARKER;
|
||||
}
|
||||
|
||||
/// Returns the master index of the SmallAllocationGroup containing this allocation
|
||||
/// Returns the index of the SmallAllocationGroup containing this allocation
|
||||
uint32_t GetSmallAllocationIndex() const
|
||||
{
|
||||
return (uint32_t)(m_data & 0xFFFFFFFF);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace AZ
|
||||
// Afterwards use the AZ::IO::Path Append function append the filename as a child
|
||||
// of the framework directory
|
||||
AZ::IO::FixedMaxPathString fileName{ fullPath.Filename().Native() };
|
||||
fullPath.ReplaceFilename(AZ::IO::PathView((fileName + ".framework").c_str()));
|
||||
fullPath.ReplaceFilename(AZ::IO::PathView(AZStd::string_view(fileName + ".framework")));
|
||||
fullPath /= fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace AZ::IO
|
||||
// If used, the source path will be treated as the destination path
|
||||
// and no transformations will be done. Pass this flag when the path is to be the actual
|
||||
// path on the disk/in the packs and doesn't need adjustment (or after it has come through adjustments already)
|
||||
// if this is set, AdjustFileName will not map the input path into the master folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
// if this is set, AdjustFileName will not map the input path into the folder (Ex: Shaders will not be converted to Game\Shaders)
|
||||
FLAGS_PATH_REAL = 1 << 16,
|
||||
|
||||
// AdjustFileName will always copy the file path to the destination path:
|
||||
@@ -318,7 +318,6 @@ namespace AZ::IO
|
||||
virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0;
|
||||
virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0;
|
||||
// virtual bool IsOutOfDate(const char * szCompiledName, const char * szMasterFile)=0;
|
||||
//returns file modification time
|
||||
virtual IArchive::FileTime GetModificationTime(AZ::IO::HandleType fileHandle) = 0;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AZ::IO
|
||||
enum EPakFlags
|
||||
{
|
||||
// support for absolute and other complex path specifications -
|
||||
// all paths will be treated relatively to the current directory (normally MasterCD)
|
||||
// all paths will be treated relatively to the current directory
|
||||
FLAGS_ABSOLUTE_PATHS = 1,
|
||||
|
||||
// if this is set, the object will only understand relative to the zip file paths,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionLayers.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsTypes.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h>
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace Physics
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
AZStd::string m_name;
|
||||
ShapeConfigurationList m_shapes;
|
||||
AzPhysics::ShapeColliderPairList m_shapes;
|
||||
};
|
||||
|
||||
class CharacterColliderConfiguration
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Physics
|
||||
classElement.RemoveElement(shapesIndex);
|
||||
|
||||
// add a new vector in the new format
|
||||
const int newShapesIndex = classElement.AddElement<ShapeConfigurationList>(context, "shapes");
|
||||
const int newShapesIndex = classElement.AddElement<AzPhysics::ShapeColliderPairList>(context, "shapes");
|
||||
if (newShapesIndex != -1)
|
||||
{
|
||||
AZ::SerializeContext::DataElementNode& newShapesElement = classElement.GetSubElement(newShapesIndex);
|
||||
@@ -65,7 +65,9 @@ namespace Physics
|
||||
// convert the old shapes into the new format and add to the vector
|
||||
for (AZ::SerializeContext::DataElementNode shape : shapesCopy)
|
||||
{
|
||||
const int pairIndex = newShapesElement.AddElementWithData<ShapeConfigurationPair>(context, "element", ShapeConfigurationPair());
|
||||
const int pairIndex = newShapesElement.AddElementWithData<AzPhysics::ShapeColliderPair>(
|
||||
context, "element", AzPhysics::ShapeColliderPair());
|
||||
|
||||
AZ::SerializeContext::DataElementNode& pairElement = newShapesElement.GetSubElement(pairIndex);
|
||||
|
||||
ColliderConfiguration colliderConfig;
|
||||
@@ -131,8 +133,8 @@ namespace Physics
|
||||
AZ::SerializeContext::DataElementNode* baseBaseClass1 = baseClass1->FindSubElement(AZ_CRC("BaseClass1", 0xd4925735));
|
||||
if (baseBaseClass1 && baseBaseClass1->FindSubElementAndGetData<AZStd::string>(AZ_CRC("name", 0x5e237e06), name))
|
||||
{
|
||||
ShapeConfigurationList shapes;
|
||||
if (nodeElement.FindSubElementAndGetData<ShapeConfigurationList>(AZ_CRC("shapes", 0x93dba512), shapes))
|
||||
AzPhysics::ShapeColliderPairList shapes;
|
||||
if (nodeElement.FindSubElementAndGetData<AzPhysics::ShapeColliderPairList>(AZ_CRC("shapes", 0x93dba512), shapes))
|
||||
{
|
||||
CharacterColliderNodeConfiguration newColliderNodeConfig;
|
||||
newColliderNodeConfig.m_name = name;
|
||||
|
||||
@@ -70,7 +70,10 @@ namespace AzPhysics
|
||||
using SimulatedBodyHandleList = AZStd::vector<SimulatedBodyHandle>;
|
||||
|
||||
//! Helper used for pairing the ShapeConfiguration and ColliderConfiguration together which is used when creating a Simulated Body.
|
||||
using ShapeColliderPair = AZStd::pair<Physics::ColliderConfiguration*, Physics::ShapeConfiguration*>;
|
||||
using ShapeColliderPair = AZStd::pair<
|
||||
AZStd::shared_ptr<Physics::ColliderConfiguration>,
|
||||
AZStd::shared_ptr<Physics::ShapeConfiguration>>;
|
||||
using ShapeColliderPairList = AZStd::vector<ShapeColliderPair>;
|
||||
|
||||
//! Flags used to specifying which properties of a body to compute.
|
||||
enum class MassComputeFlags : AZ::u8
|
||||
|
||||
@@ -80,9 +80,6 @@ namespace Physics
|
||||
void OnContactOffsetChanged();
|
||||
};
|
||||
|
||||
using ShapeConfigurationPair = AZStd::pair<AZStd::shared_ptr<ColliderConfiguration>, AZStd::shared_ptr<ShapeConfiguration>>;
|
||||
using ShapeConfigurationList = AZStd::vector<ShapeConfigurationPair>;
|
||||
|
||||
struct RayCastRequest;
|
||||
|
||||
class Shape
|
||||
|
||||
@@ -264,12 +264,12 @@ namespace AzFramework
|
||||
// SampleRPC =
|
||||
// {
|
||||
// // Two callbacks can be registered to the NetRPC
|
||||
// // A function to be invoked on the Master - OnMaster
|
||||
// // A function to be invoked on the main server - OnServer
|
||||
// // and a function to be invoked on the Proxy - OnProxy
|
||||
// //
|
||||
// // Every NetRPC needs to have a valid OnMaster function, while OnProxy is optional.
|
||||
// OnMaster = function()
|
||||
// Debug.Log("Function to be invoked on the Master.");
|
||||
// // Every NetRPC needs to have a valid OnServer function, while OnProxy is optional.
|
||||
// OnServer = function()
|
||||
// Debug.Log("Function to be invoked on the server.");
|
||||
// end
|
||||
//
|
||||
// OnProxy = function()
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace AzFramework
|
||||
};
|
||||
|
||||
using EntitySpawnCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
using EntityPreInsertionCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableEntityContainerView)>;
|
||||
using EntityDespawnCallback = AZStd::function<void(EntitySpawnTicket&)>;
|
||||
using ReloadSpawnableCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
using ListEntitiesCallback = AZStd::function<void(EntitySpawnTicket&, SpawnableConstEntityContainerView)>;
|
||||
@@ -110,7 +111,8 @@ namespace AzFramework
|
||||
//! @param completionCallback Optional callback that's called when spawning entities has completed. This can be called from
|
||||
//! a different thread than the one that made the function call. The returned list of entities contains all the newly
|
||||
//! created entities.
|
||||
virtual void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) = 0;
|
||||
virtual void SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback = {},
|
||||
EntitySpawnCallback completionCallback = {}) = 0;
|
||||
//! Spawn instances of some entities in the spawnable.
|
||||
//! @param ticket Stores the results of the call. Use this ticket to spawn additional entities or to despawn them.
|
||||
//! @param entityIndices The indices into the template entities stored in the spawnable that will be used to spawn entities from.
|
||||
@@ -118,7 +120,7 @@ namespace AzFramework
|
||||
//! a different thread than the one that made this function call. The returned list of entities contains all the newly
|
||||
//! created entities.
|
||||
virtual void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntitySpawnCallback completionCallback = {}) = 0;
|
||||
EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) = 0;
|
||||
//! Removes all entities in the provided list from the environment.
|
||||
//! @param ticket The ticket previously used to spawn entities with.
|
||||
//! @param completionCallback Optional callback that's called when despawning entities has completed. This can be called from
|
||||
|
||||
@@ -14,17 +14,20 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Components/TransformComponent.h>
|
||||
#include <AzFramework/Entity/GameEntityContextBus.h>
|
||||
#include <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzFramework/Spawnable/SpawnableEntitiesManager.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void SpawnableEntitiesManager::SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback)
|
||||
void SpawnableEntitiesManager::SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback,
|
||||
EntitySpawnCallback completionCallback)
|
||||
{
|
||||
SpawnAllEntitiesCommand queueEntry;
|
||||
queueEntry.m_ticket = &ticket;
|
||||
queueEntry.m_completionCallback = AZStd::move(completionCallback);
|
||||
queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback);
|
||||
{
|
||||
AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex);
|
||||
queueEntry.m_ticketId = GetTicketPayload<Ticket>(ticket).m_nextTicketId++;
|
||||
@@ -32,13 +35,15 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnableEntitiesManager::SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntitySpawnCallback completionCallback)
|
||||
void SpawnableEntitiesManager::SpawnEntities(
|
||||
EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
EntityPreInsertionCallback preInsertionCallback, EntitySpawnCallback completionCallback)
|
||||
{
|
||||
SpawnEntitiesCommand queueEntry;
|
||||
queueEntry.m_ticket = &ticket;
|
||||
queueEntry.m_entityIndices = AZStd::move(entityIndices);
|
||||
queueEntry.m_completionCallback = AZStd::move(completionCallback);
|
||||
queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback);
|
||||
{
|
||||
AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex);
|
||||
queueEntry.m_ticketId = GetTicketPayload<Ticket>(ticket).m_nextTicketId++;
|
||||
@@ -205,6 +210,7 @@ namespace AzFramework
|
||||
AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
clone->SetId(AZ::Entity::MakeId());
|
||||
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone);
|
||||
return clone;
|
||||
}
|
||||
@@ -214,23 +220,79 @@ namespace AzFramework
|
||||
Ticket& ticket = GetTicketPayload<Ticket>(*request.m_ticket);
|
||||
if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId)
|
||||
{
|
||||
size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size();
|
||||
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
|
||||
AZStd::vector<size_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
|
||||
const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesSize = entities.size();
|
||||
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
|
||||
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
|
||||
// Keep track how many entities there were in the array initially
|
||||
size_t spawnedEntitiesInitialCount = spawnedEntities.size();
|
||||
|
||||
for(size_t i=0; i<entitiesSize; ++i)
|
||||
// These are 'template' entities we'll be cloning from
|
||||
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesToSpawnSize = entitiesToSpawn.size();
|
||||
|
||||
// Reserve buffers
|
||||
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
|
||||
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesToSpawnSize);
|
||||
|
||||
// TEMP: To be replaced by IdUtils::Remapper
|
||||
using EntityIdMap = AZStd::unordered_map<AZ::EntityId, AZ::EntityId>;
|
||||
EntityIdMap templateToCloneIdMap;
|
||||
// \TEMP
|
||||
|
||||
// Clone the entities from Spawnable
|
||||
for (size_t i = 0; i < entitiesToSpawnSize; ++i)
|
||||
{
|
||||
ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext));
|
||||
ticket.m_spawnedEntityIndices.push_back(i);
|
||||
const AZ::Entity& entityTemplate = *entitiesToSpawn[i];
|
||||
|
||||
AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
clone->SetId(AZ::Entity::MakeId());
|
||||
|
||||
spawnedEntities.push_back(clone);
|
||||
spawnedEntityIndices.push_back(i);
|
||||
|
||||
// TEMP: To be replaced by IdUtils::Remapper
|
||||
templateToCloneIdMap[entityTemplate.GetId()] = clone->GetId();
|
||||
|
||||
// Update TransformComponent parent Id. It is guaranteed for the entities array to be sorted from parent->child here.
|
||||
auto* transformComponent = clone->FindComponent<AzFramework::TransformComponent>();
|
||||
AZ::EntityId parentId = transformComponent->GetParentId();
|
||||
if (parentId.IsValid())
|
||||
{
|
||||
auto it = templateToCloneIdMap.find(parentId);
|
||||
if (it != templateToCloneIdMap.end())
|
||||
{
|
||||
transformComponent->SetParentRelative(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(
|
||||
"SpawnableEntitiesManager", false, "Entity %s doesn't have the parent entity %s present in the spawnable",
|
||||
clone->GetName().c_str(), parentId.ToString().data());
|
||||
}
|
||||
}
|
||||
// \TEMP
|
||||
}
|
||||
|
||||
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
|
||||
if (request.m_preInsertionCallback)
|
||||
{
|
||||
request.m_preInsertionCallback(*request.m_ticket, SpawnableEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
// Add to the game context, now the entities are active
|
||||
AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(),
|
||||
[](AZ::Entity* entity)
|
||||
{
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity);
|
||||
});
|
||||
|
||||
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
|
||||
if (request.m_completionCallback)
|
||||
{
|
||||
request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end()));
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
@@ -249,24 +311,56 @@ namespace AzFramework
|
||||
Ticket& ticket = GetTicketPayload<Ticket>(*request.m_ticket);
|
||||
if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId)
|
||||
{
|
||||
size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size();
|
||||
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
|
||||
AZStd::vector<size_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
|
||||
const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesSize = entities.size();
|
||||
ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize);
|
||||
ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize);
|
||||
// Keep track how many entities there were in the array initially
|
||||
size_t spawnedEntitiesInitialCount = spawnedEntities.size();
|
||||
|
||||
// These are 'template' entities we'll be cloning from
|
||||
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
|
||||
size_t entitiesToSpawnSize = request.m_entityIndices.size();
|
||||
|
||||
spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize);
|
||||
spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize);
|
||||
|
||||
for (size_t index : request.m_entityIndices)
|
||||
{
|
||||
ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[index], serializeContext));
|
||||
ticket.m_spawnedEntityIndices.push_back(index);
|
||||
if (index < entitiesToSpawn.size())
|
||||
{
|
||||
const AZ::Entity& entityTemplate = *entitiesToSpawn[index];
|
||||
|
||||
AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
clone->SetId(AZ::Entity::MakeId());
|
||||
|
||||
spawnedEntities.push_back(clone);
|
||||
spawnedEntityIndices.push_back(index);
|
||||
|
||||
}
|
||||
}
|
||||
ticket.m_loadAll = false;
|
||||
|
||||
// Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context.
|
||||
if (request.m_preInsertionCallback)
|
||||
{
|
||||
request.m_preInsertionCallback(
|
||||
*request.m_ticket,
|
||||
SpawnableEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
// Add to the game context, now the entities are active
|
||||
AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(),
|
||||
[](AZ::Entity* entity)
|
||||
{
|
||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity);
|
||||
});
|
||||
|
||||
if (request.m_completionCallback)
|
||||
{
|
||||
request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView(
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end()));
|
||||
ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end()));
|
||||
}
|
||||
|
||||
m_onSpawnedEvent.Signal(ticket.m_spawnable);
|
||||
|
||||
@@ -47,8 +47,8 @@ namespace AzFramework
|
||||
// The following functions are thread safe
|
||||
//
|
||||
|
||||
void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) override;
|
||||
void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices,
|
||||
void SpawnAllEntities(EntitySpawnTicket& ticket, EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) override;
|
||||
void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices, EntityPreInsertionCallback preInsertionCallback = {},
|
||||
EntitySpawnCallback completionCallback = {}) override;
|
||||
void DespawnAllEntities(EntitySpawnTicket& ticket, EntityDespawnCallback completionCallback = {}) override;
|
||||
|
||||
@@ -90,6 +90,7 @@ namespace AzFramework
|
||||
struct SpawnAllEntitiesCommand
|
||||
{
|
||||
EntitySpawnCallback m_completionCallback;
|
||||
EntityPreInsertionCallback m_preInsertionCallback;
|
||||
EntitySpawnTicket* m_ticket;
|
||||
uint32_t m_ticketId;
|
||||
};
|
||||
@@ -97,6 +98,7 @@ namespace AzFramework
|
||||
{
|
||||
AZStd::vector<size_t> m_entityIndices;
|
||||
EntitySpawnCallback m_completionCallback;
|
||||
EntityPreInsertionCallback m_preInsertionCallback;
|
||||
EntitySpawnTicket* m_ticket;
|
||||
uint32_t m_ticketId;
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Neighborhood {
|
||||
//---------------------------------------------------------------------
|
||||
void NeighborReplica::OnReplicaActivate(const GridMate::ReplicaContext& /*rc*/)
|
||||
{
|
||||
// TODO: Should we send the message to ourselves as well (master)?
|
||||
// TODO: Should we send the message to ourselves as well?
|
||||
if (IsProxy())
|
||||
{
|
||||
AZ_Assert(m_persistentName.Get().c_str(), "Received NeighborReplica with missing persistent name!");
|
||||
@@ -52,7 +52,7 @@ namespace Neighborhood {
|
||||
//---------------------------------------------------------------------
|
||||
void NeighborReplica::OnReplicaDeactivate(const GridMate::ReplicaContext& /*rc*/)
|
||||
{
|
||||
// TODO: Should we send the message to ourselves as well (master)?
|
||||
// TODO: Should we send the message to ourselves as well?
|
||||
if (IsProxy())
|
||||
{
|
||||
EBUS_EVENT(NeighborhoodBus, OnNodeLeft, *this);
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace AzFramework
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 6.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
@@ -532,20 +533,39 @@ namespace AzFramework
|
||||
|
||||
if (Beginning())
|
||||
{
|
||||
float hit_distance = 0.0f;
|
||||
AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance);
|
||||
const auto hasLookAt = [&nextCamera, &targetCamera, lookAtFn = m_lookAtFn] {
|
||||
if (lookAtFn)
|
||||
{
|
||||
if (const auto lookAt = lookAtFn())
|
||||
{
|
||||
auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt);
|
||||
nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt);
|
||||
UpdateCameraFromTransform(nextCamera, transform);
|
||||
|
||||
if (hit_distance > 0.0f)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!hasLookAt)
|
||||
{
|
||||
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance;
|
||||
float hit_distance = 0.0f;
|
||||
AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance);
|
||||
|
||||
if (hit_distance > 0.0f)
|
||||
{
|
||||
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -ed_cameraSystemMinOrbitDistance;
|
||||
nextCamera.m_lookAt =
|
||||
targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMinOrbitDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ namespace AzFramework
|
||||
public:
|
||||
explicit RotateCameraInput(InputChannelId rotateChannelId);
|
||||
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
@@ -239,6 +240,7 @@ namespace AzFramework
|
||||
public:
|
||||
PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn);
|
||||
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
@@ -279,6 +281,7 @@ namespace AzFramework
|
||||
public:
|
||||
explicit TranslateCameraInput(TranslationAxesFn translationAxesFn);
|
||||
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
void ResetImpl() override;
|
||||
@@ -348,6 +351,7 @@ namespace AzFramework
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
};
|
||||
@@ -357,6 +361,7 @@ namespace AzFramework
|
||||
public:
|
||||
explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId);
|
||||
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
@@ -367,6 +372,7 @@ namespace AzFramework
|
||||
class ScrollTranslationCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
};
|
||||
@@ -374,16 +380,32 @@ namespace AzFramework
|
||||
class OrbitCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
using LookAtFn = AZStd::function<AZStd::optional<AZ::Vector3>()>;
|
||||
|
||||
// CameraInput overrides ...
|
||||
void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
bool Exclusive() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool Exclusive() const override;
|
||||
|
||||
Cameras m_orbitCameras;
|
||||
|
||||
//! Override the default behavior for how a look-at point is calculated.
|
||||
void SetLookAtFn(const LookAtFn& lookAtFn);
|
||||
|
||||
private:
|
||||
LookAtFn m_lookAtFn;
|
||||
};
|
||||
|
||||
inline void OrbitCameraInput::SetLookAtFn(const LookAtFn& lookAtFn)
|
||||
{
|
||||
m_lookAtFn = lookAtFn;
|
||||
}
|
||||
|
||||
inline bool OrbitCameraInput::Exclusive() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct WindowSize;
|
||||
|
||||
//! Map from a generic InputChannel event to a camera specific InputEvent.
|
||||
|
||||
@@ -116,8 +116,8 @@ namespace AzNetworking
|
||||
|
||||
int32_t TcpSocket::Receive(uint8_t* outData, uint32_t size) const
|
||||
{
|
||||
AZ_Assert(size > 0, "Invalid data size for send");
|
||||
AZ_Assert(outData != nullptr, "NULL data pointer passed to send");
|
||||
AZ_Assert(size > 0, "Invalid data size for receive");
|
||||
AZ_Assert(outData != nullptr, "NULL data pointer passed to receive");
|
||||
if (!IsOpen())
|
||||
{
|
||||
return SocketOpResultErrorNotOpen;
|
||||
@@ -176,7 +176,7 @@ namespace AzNetworking
|
||||
if (::bind(aznumeric_cast<int32_t>(m_socketFd), (const sockaddr*)&hints, sizeof(hints)) != 0)
|
||||
{
|
||||
const int32_t error = GetLastNetworkError();
|
||||
AZLOG_ERROR("Failed to bind socket (%d:%s)", error, GetNetworkErrorDesc(error));
|
||||
AZLOG_ERROR("Failed to bind TCP socket to port %u (%d:%s)", uint32_t(port), error, GetNetworkErrorDesc(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace AzNetworking
|
||||
const UdpReaderThread::ReceivedPackets* packets = m_readerThread.GetReceivedPackets(m_socket.get());
|
||||
if (packets == nullptr)
|
||||
{
|
||||
AZ_Assert(false, "nullptr was retrieved for the received packet buffer, check that the socket has been registered with the reader thread");
|
||||
// Socket is not yet registered with the reader thread and is likely still pending, try again later
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace AzNetworking
|
||||
if (::bind(static_cast<int32_t>(m_socketFd), (const sockaddr *)&hints, sizeof(hints)) != 0)
|
||||
{
|
||||
const int32_t error = GetLastNetworkError();
|
||||
AZLOG_ERROR("Failed to bind socket to port %u (%d:%s)", uint32_t(port), error, GetNetworkErrorDesc(error));
|
||||
AZLOG_ERROR("Failed to bind UDP socket to port %u (%d:%s)", uint32_t(port), error, GetNetworkErrorDesc(error));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzQtComponents/Utilities/SelectionProxyModel.h>
|
||||
#include <QAbstractProxyModel>
|
||||
|
||||
namespace AzQtComponents
|
||||
{
|
||||
SelectionProxyModel::SelectionProxyModel(QItemSelectionModel* sourceSelectionModel, QAbstractProxyModel* proxyModel, QObject* parent)
|
||||
: QItemSelectionModel(proxyModel, parent)
|
||||
, m_sourceSelectionModel(sourceSelectionModel)
|
||||
{
|
||||
connect(sourceSelectionModel, &QItemSelectionModel::selectionChanged, this, &SelectionProxyModel::OnSourceSelectionChanged);
|
||||
connect(sourceSelectionModel, &QItemSelectionModel::currentChanged, this, &SelectionProxyModel::OnSourceSelectionCurrentChanged);
|
||||
connect(proxyModel, &QAbstractItemModel::rowsInserted, this, &SelectionProxyModel::OnProxyModelRowsInserted);
|
||||
connect(this, &QItemSelectionModel::selectionChanged, this, &SelectionProxyModel::OnProxySelectionChanged);
|
||||
|
||||
// Find the chain of proxy models
|
||||
QAbstractProxyModel* sourceProxyModel = proxyModel;
|
||||
while (sourceProxyModel)
|
||||
{
|
||||
m_proxyModels.push_back(sourceProxyModel);
|
||||
sourceProxyModel = qobject_cast<QAbstractProxyModel*>(sourceProxyModel->sourceModel());
|
||||
}
|
||||
|
||||
const QItemSelection currentSelection = mapFromSource(m_sourceSelectionModel->selection());
|
||||
QItemSelectionModel::select(currentSelection, QItemSelectionModel::ClearAndSelect);
|
||||
|
||||
const QModelIndex currentModelIndex = mapFromSource(m_sourceSelectionModel->currentIndex());
|
||||
QItemSelectionModel::setCurrentIndex(currentModelIndex, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
const QModelIndex sourcetIndex = mapToSource(index);
|
||||
m_sourceSelectionModel->setCurrentIndex(sourcetIndex, command);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
const QModelIndex sourceIndex = mapToSource(index);
|
||||
m_sourceSelectionModel->select(sourceIndex, command);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
|
||||
{
|
||||
const QItemSelection sourceSelection = mapToSource(selection);
|
||||
m_sourceSelectionModel->select(sourceSelection, command);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::clear()
|
||||
{
|
||||
m_sourceSelectionModel->clear();
|
||||
}
|
||||
|
||||
void SelectionProxyModel::reset()
|
||||
{
|
||||
m_sourceSelectionModel->reset();
|
||||
}
|
||||
|
||||
void SelectionProxyModel::clearCurrentIndex()
|
||||
{
|
||||
m_sourceSelectionModel->clearCurrentIndex();
|
||||
}
|
||||
|
||||
void SelectionProxyModel::OnSourceSelectionCurrentChanged(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous)
|
||||
{
|
||||
QModelIndex targetCurrent = mapFromSource(current);
|
||||
QItemSelectionModel::setCurrentIndex(targetCurrent, QItemSelectionModel::NoUpdate);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::OnSourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
QItemSelection targetSelected = mapFromSource(selected);
|
||||
QItemSelection targetDeselected = mapFromSource(deselected);
|
||||
|
||||
QItemSelectionModel::select(targetSelected, QItemSelectionModel::Select);
|
||||
QItemSelectionModel::select(targetDeselected, QItemSelectionModel::Deselect);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::OnProxySelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
const QItemSelection sourceSelected = mapToSource(selected);
|
||||
const QItemSelection sourceDeselected = mapToSource(deselected);
|
||||
|
||||
// Disconnect from the selectionChanged signal in the source model to prevent recursion. We could also block the signals
|
||||
// of the source selection model, but someone else may be connected to its signals and expect to get an update.
|
||||
disconnect(m_sourceSelectionModel, &QItemSelectionModel::selectionChanged, this, &SelectionProxyModel::OnSourceSelectionChanged);
|
||||
if (selected.empty() && deselected.empty())
|
||||
{
|
||||
// Force the signal to fire
|
||||
emit m_sourceSelectionModel->selectionChanged({}, {});
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sourceSelectionModel->select(sourceSelected, QItemSelectionModel::Select);
|
||||
m_sourceSelectionModel->select(sourceDeselected, QItemSelectionModel::Deselect);
|
||||
}
|
||||
connect(m_sourceSelectionModel, &QItemSelectionModel::selectionChanged, this, &SelectionProxyModel::OnSourceSelectionChanged);
|
||||
}
|
||||
|
||||
void SelectionProxyModel::OnProxyModelRowsInserted([[maybe_unused]] const QModelIndex& parent, [[maybe_unused]] int first, [[maybe_unused]] int last)
|
||||
{
|
||||
QModelIndex sourceIndex = m_sourceSelectionModel->currentIndex();
|
||||
QModelIndex targetIndex = mapFromSource(sourceIndex);
|
||||
if (targetIndex != currentIndex())
|
||||
{
|
||||
QItemSelectionModel::setCurrentIndex(targetIndex, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
QItemSelection sourceSelection = m_sourceSelectionModel->selection();
|
||||
QItemSelection targetSelection = mapFromSource(sourceSelection);
|
||||
if (targetSelection != selection())
|
||||
{
|
||||
QItemSelectionModel::select(targetSelection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex SelectionProxyModel::mapFromSource(const QModelIndex& sourceIndex)
|
||||
{
|
||||
QModelIndex mappedIndex = sourceIndex;
|
||||
for (QVector<QAbstractProxyModel*>::const_reverse_iterator itProxy = m_proxyModels.rbegin(); itProxy != m_proxyModels.rend(); ++itProxy)
|
||||
{
|
||||
mappedIndex = (*itProxy)->mapFromSource(mappedIndex);
|
||||
}
|
||||
return mappedIndex;
|
||||
}
|
||||
|
||||
QItemSelection SelectionProxyModel::mapFromSource(const QItemSelection& sourceSelection)
|
||||
{
|
||||
QItemSelection mappedSelection = sourceSelection;
|
||||
for (QVector<QAbstractProxyModel*>::const_reverse_iterator itProxy = m_proxyModels.rbegin(); itProxy != m_proxyModels.rend(); ++itProxy)
|
||||
{
|
||||
mappedSelection = (*itProxy)->mapSelectionFromSource(mappedSelection);
|
||||
}
|
||||
return mappedSelection;
|
||||
}
|
||||
|
||||
QModelIndex SelectionProxyModel::mapToSource(const QModelIndex& targetIndex)
|
||||
{
|
||||
QModelIndex mappedIndex = targetIndex;
|
||||
for (QVector<QAbstractProxyModel*>::const_iterator itProxy = m_proxyModels.begin(); itProxy != m_proxyModels.end(); ++itProxy)
|
||||
{
|
||||
mappedIndex = (*itProxy)->mapToSource(mappedIndex);
|
||||
}
|
||||
return mappedIndex;
|
||||
}
|
||||
|
||||
QItemSelection SelectionProxyModel::mapToSource(const QItemSelection& targetSelection)
|
||||
{
|
||||
QItemSelection mappedSelection = targetSelection;
|
||||
for (QVector<QAbstractProxyModel*>::const_iterator itProxy = m_proxyModels.begin(); itProxy != m_proxyModels.end(); ++itProxy)
|
||||
{
|
||||
mappedSelection = (*itProxy)->mapSelectionToSource(mappedSelection);
|
||||
}
|
||||
return mappedSelection;
|
||||
}
|
||||
} // namespace AzQtComponents
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzQtComponents/AzQtComponentsAPI.h>
|
||||
#include <QtCore/QItemSelectionModel>
|
||||
#include <QVector>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAbstractProxyModel)
|
||||
|
||||
namespace AzQtComponents
|
||||
{
|
||||
//! This class is a QItemSelectionModel that syncs through proxy models and maintains
|
||||
//! selection. In Qt we can have a model being filtered/sorted by proxy models. If the
|
||||
//! selection model is connected to the original model, the view needs a new selection
|
||||
//! model that understands the filtering. This class does that conversion.
|
||||
//! @Note: this class does not support changing proxy models (anywhere in the chain).
|
||||
//! The class will have to be recreated with the new proxy model.
|
||||
class AZ_QT_COMPONENTS_API SelectionProxyModel
|
||||
: public QItemSelectionModel
|
||||
{
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
SelectionProxyModel(QItemSelectionModel* sourceSelectionModel, QAbstractProxyModel* proxyModel, QObject* parent = nullptr);
|
||||
|
||||
void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override;
|
||||
void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override;
|
||||
void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
|
||||
void clear() override;
|
||||
void reset() override;
|
||||
void clearCurrentIndex() override;
|
||||
|
||||
private slots:
|
||||
void OnSourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void OnSourceSelectionCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void OnProxySelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void OnProxyModelRowsInserted(const QModelIndex& parent, int first, int last);
|
||||
|
||||
private:
|
||||
QModelIndex mapFromSource(const QModelIndex& sourceIndex);
|
||||
QItemSelection mapFromSource(const QItemSelection& sourceSelection);
|
||||
|
||||
QModelIndex mapToSource(const QModelIndex& targetIndex);
|
||||
QItemSelection mapToSource(const QItemSelection& targetSelection);
|
||||
|
||||
// Contains the chain of proxy models that leads us to the real model. The outer-most proxy model
|
||||
// comes first and is followed by inner proxy models.
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QVector<QAbstractProxyModel*> m_proxyModels;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
QItemSelectionModel* m_sourceSelectionModel;
|
||||
};
|
||||
} // namespace AzQtComponents
|
||||
@@ -287,6 +287,8 @@ set(FILES
|
||||
Utilities/ScreenUtilities.cpp
|
||||
Utilities/ScreenGrabber.h
|
||||
Utilities/ScopedCleanup.h
|
||||
Utilities/SelectionProxyModel.cpp
|
||||
Utilities/SelectionProxyModel.h
|
||||
Utilities/TextUtilities.cpp
|
||||
Utilities/TextUtilities.h
|
||||
)
|
||||
|
||||
+5
@@ -12,6 +12,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
@@ -46,6 +47,10 @@ namespace AzToolsFramework
|
||||
|
||||
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
|
||||
|
||||
//! Get all Assets generated by Prefab processing when entering Play-In Editor mode (Ctrl+G)
|
||||
//! /return The vector of Assets generated by Prefab processing
|
||||
virtual const AZStd::vector<AZ::Data::Asset<AZ::Data::AssetData>>& GetPlayInEditorAssetData() = 0;
|
||||
|
||||
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
virtual bool SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user