Merge branch 'development' of https://github.com/o3de/o3de into GroupToggleSwitch
This commit is contained in:
@@ -463,7 +463,7 @@ void EditorViewportWidget::Update()
|
||||
|
||||
if (m_updateCameraPositionNextTick)
|
||||
{
|
||||
auto cameraState = m_renderViewport->GetCameraState();
|
||||
auto cameraState = GetCameraState();
|
||||
AZ::Matrix3x4 matrix;
|
||||
matrix.SetBasisAndTranslation(cameraState.m_side, cameraState.m_forward, cameraState.m_up, cameraState.m_position);
|
||||
auto m = AZMatrix3x4ToLYMatrix3x4(matrix);
|
||||
@@ -1138,6 +1138,17 @@ void EditorViewportWidget::OnMenuSelectCurrentCamera()
|
||||
|
||||
AzFramework::CameraState EditorViewportWidget::GetCameraState()
|
||||
{
|
||||
if (m_viewEntityId.IsValid())
|
||||
{
|
||||
bool cameraStateAcquired = false;
|
||||
AzFramework::CameraState cameraState;
|
||||
Camera::EditorCameraViewRequestBus::BroadcastResult(cameraStateAcquired,
|
||||
&Camera::EditorCameraViewRequestBus::Events::GetCameraState, cameraState);
|
||||
if (cameraStateAcquired)
|
||||
{
|
||||
return cameraState;
|
||||
}
|
||||
}
|
||||
return m_renderViewport->GetCameraState();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
static void Record(IUndoObject* undo);
|
||||
|
||||
private:
|
||||
static const uint32 scDescSize = 256;
|
||||
static const AZ::u32 scDescSize = 256;
|
||||
char m_description[scDescSize];
|
||||
bool m_bCancelled;
|
||||
bool m_bStartedRecord;
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace AZ
|
||||
return &out;
|
||||
}
|
||||
|
||||
Matrix4x4* MakeOrthographicMatrixRH(Matrix4x4& out, float left, float right, float bottom, float top, float nearDist, float farDist)
|
||||
Matrix4x4* MakeOrthographicMatrixRH(Matrix4x4& out, float left, float right, float bottom, float top, float nearDist, float farDist, bool reverseDepth)
|
||||
{
|
||||
AZ_Assert(right > left, "right should be greater than left");
|
||||
// valid to have matrix invert top/bottom and far/near
|
||||
@@ -83,6 +83,11 @@ namespace AZ
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (reverseDepth)
|
||||
{
|
||||
AZStd::swap(nearDist, farDist);
|
||||
}
|
||||
|
||||
out.SetRow(0, 2.f/(right - left), 0.f, 0.f, - (right + left) / (right - left) );
|
||||
out.SetRow(1, 0.f, 2.f / (top - bottom), 0.f, - (top + bottom) / (top - bottom) );
|
||||
out.SetRow(2, 0.f, 0.f, 1 / (nearDist - farDist), nearDist / (nearDist - farDist) );
|
||||
|
||||
@@ -57,8 +57,9 @@ namespace AZ
|
||||
//! @param top The y coordinate of top view-plane
|
||||
//! @param near Distance to the near view-plane. Must be no less than zero.
|
||||
//! @param far Distance to the far view-plane. Must be greater than zero.
|
||||
//! @param reverseDepth Set to true to reverse depth which means near distance maps to 1 and far distance maps to 0.
|
||||
//! @return Pointer of the output matrix
|
||||
Matrix4x4* MakeOrthographicMatrixRH(Matrix4x4& out, float left, float right, float bottom, float top, float nearDist, float farDist);
|
||||
Matrix4x4* MakeOrthographicMatrixRH(Matrix4x4& out, float left, float right, float bottom, float top, float nearDist, float farDist, bool reverseDepth = false);
|
||||
|
||||
//! Transforms a position by a matrix. This function can be used with any generic cases which include projection matrices.
|
||||
Vector3 MatrixTransformPosition(const Matrix4x4& matrix, const Vector3& inPosition);
|
||||
|
||||
@@ -120,6 +120,11 @@ namespace AZStd
|
||||
base_type::insert(*first);
|
||||
}
|
||||
}
|
||||
fixed_unordered_map(const AZStd::initializer_list<value_type>& list, const hasher& hash = hasher(),
|
||||
const key_eq& keyEqual = key_eq())
|
||||
: fixed_unordered_map(list.begin(), list.end(), hash, keyEqual)
|
||||
{
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE pair_iter_bool insert(const value_type& value)
|
||||
{
|
||||
@@ -241,6 +246,12 @@ namespace AZStd
|
||||
base_type::insert(*first);
|
||||
}
|
||||
}
|
||||
fixed_unordered_multimap(const AZStd::initializer_list<value_type>& list, const hasher& hash = hasher(),
|
||||
const key_eq& keyEqual = key_eq())
|
||||
: fixed_unordered_multimap(list.begin(), list.end(), hash, keyEqual)
|
||||
{
|
||||
}
|
||||
|
||||
AZ_FORCE_INLINE iterator insert(const value_type& value)
|
||||
{
|
||||
return base_type::insert_impl(value).first;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common)
|
||||
|
||||
if(LY_ENABLE_RAD_TELEMETRY)
|
||||
if(LY_RAD_TELEMETRY_ENABLED)
|
||||
set(AZ_CORE_RADTELEMETRY_FILES ${common_dir}/azcore_profile_telemetry_files.cmake)
|
||||
set(AZ_CORE_RADTELEMETRY_PLATFORM_INCLUDES ${pal_dir}/profile_telemetry_platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
set(AZ_CORE_RADTELEMETRY_INCLUDE_DIRECTORIES ${common_dir})
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
# is being avoided to prevent overriding functions declared in other targets platfrom
|
||||
# specific cmake files
|
||||
|
||||
if(LY_ENABLE_RAD_TELEMETRY)
|
||||
if(LY_RAD_TELEMETRY_ENABLED)
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
|
||||
endif()
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
# is being avoided to prevent overriding functions declared in other targets platfrom
|
||||
# specific cmake files
|
||||
|
||||
if(LY_ENABLE_RAD_TELEMETRY)
|
||||
if(LY_RAD_TELEMETRY_ENABLED)
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
|
||||
endif()
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
# is being avoided to prevent overriding functions declared in other targets platfrom
|
||||
# specific cmake files
|
||||
|
||||
if(LY_ENABLE_RAD_TELEMETRY)
|
||||
if(LY_RAD_TELEMETRY_ENABLED)
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
|
||||
endif()
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
#
|
||||
#
|
||||
|
||||
if(LY_ENABLE_RAD_TELEMETRY)
|
||||
if(LY_RAD_TELEMETRY_ENABLED)
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
|
||||
endif()
|
||||
|
||||
@@ -63,6 +63,13 @@ namespace Camera
|
||||
//! @return The camera frustum's height
|
||||
virtual float GetFrustumHeight() = 0;
|
||||
|
||||
//! Gets whether or not the camera is using an orthographic projection.
|
||||
//! @return True if the camera is using an orthographic projection, or false if the camera is using a perspective projection.
|
||||
virtual bool IsOrthographic() = 0;
|
||||
|
||||
//! @return The half width of the orthographic projection, @see SetOrthographicHalfWidth.
|
||||
virtual float GetOrthographicHalfWidth() = 0;
|
||||
|
||||
//! Sets the camera's field of view in degrees between 0 < fov < 180 degrees
|
||||
//! @param fov The camera frustum's new field of view in degrees
|
||||
virtual void SetFov(float fov)
|
||||
@@ -95,6 +102,15 @@ namespace Camera
|
||||
//! @param height The camera frustum's new height
|
||||
virtual void SetFrustumHeight(float height) = 0;
|
||||
|
||||
//! Sets whether or not the camera should use an orthographic projection in place of a perspective projection.
|
||||
//! @param orthographic If true, the camera will use an orthographic projection
|
||||
virtual void SetOrthographic(bool orthographic) = 0;
|
||||
|
||||
//! Sets the half-width of the orthographic projection.
|
||||
//! @params halfWidth Used to calculate the bounds of the projection while in orthographic mode.
|
||||
//! The height is calculated automatically based on the aspect ratio.
|
||||
virtual void SetOrthographicHalfWidth(float halfWidth) = 0;
|
||||
|
||||
//! Makes the camera the active view
|
||||
virtual void MakeActiveView() = 0;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common)
|
||||
|
||||
set(LY_ENABLE_STATISTICAL_PROFILING OFF CACHE BOOL "Enables statistical profiling when using AZ_PROFILE_SCOPE. If True, it takes effect only if RAD Telemetry is disabled.")
|
||||
set(LY_STATISTICAL_PROFILING_ENABLED OFF CACHE BOOL "Enables statistical profiling when using AZ_PROFILE_SCOPE. If True, it takes effect only if RAD Telemetry is disabled.")
|
||||
set(LY_TOUCHBENDING_LAYER_BIT 63 CACHE STRING "Use TouchBending as the collision layer. The TouchBending layer can be a number from 1 to 63 (Default=63).")
|
||||
|
||||
ly_add_target(
|
||||
@@ -38,7 +38,7 @@ ly_add_target(
|
||||
3rdParty::lz4
|
||||
)
|
||||
|
||||
if(LY_ENABLE_STATISTICAL_PROFILING)
|
||||
if(LY_STATISTICAL_PROFILING_ENABLED)
|
||||
ly_add_source_properties(
|
||||
SOURCES AzFramework/Debug/StatisticalProfilerProxy.h
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
|
||||
@@ -9,8 +9,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
#include <xcb/xcb.h>
|
||||
#endif // LY_COMPILE_DEFINITIONS
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class LinuxLifecycleEvents
|
||||
@@ -25,4 +30,31 @@ namespace AzFramework
|
||||
|
||||
using Bus = AZ::EBus<LinuxLifecycleEvents>;
|
||||
};
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
class LinuxXcbConnectionManager
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(LinuxXcbConnectionManager, "{649951316-3626-4C9D-9DCA-2E7ABF84C0A9}");
|
||||
|
||||
virtual ~LinuxXcbConnectionManager() = default;
|
||||
|
||||
virtual xcb_connection_t* GetXcbConnection() const = 0;
|
||||
};
|
||||
|
||||
class LinuxXcbConnectionManagerBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static constexpr AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static constexpr AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
using LinuxXcbConnectionManagerBus = AZ::EBus<LinuxXcbConnectionManager, LinuxXcbConnectionManagerBusTraits>;
|
||||
using LinuxXcbConnectionManagerInterface = AZ::Interface<LinuxXcbConnectionManager>;
|
||||
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
} // namespace AzFramework
|
||||
|
||||
+47
@@ -12,6 +12,32 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
namespace AzFramework
|
||||
{
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
class LinuxXcbConnectionManagerImpl
|
||||
: public LinuxXcbConnectionManagerBus::Handler
|
||||
{
|
||||
public:
|
||||
LinuxXcbConnectionManagerImpl()
|
||||
{
|
||||
m_xcbConnection = xcb_connect(nullptr, nullptr);
|
||||
AZ_Error("ApplicationLinux", m_xcbConnection != nullptr, "Unable to connect to X11 Server.");
|
||||
LinuxXcbConnectionManagerBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
~LinuxXcbConnectionManagerImpl()
|
||||
{
|
||||
LinuxXcbConnectionManagerBus::Handler::BusDisconnect();
|
||||
xcb_disconnect(m_xcbConnection);
|
||||
}
|
||||
xcb_connection_t* GetXcbConnection() const override
|
||||
{
|
||||
return m_xcbConnection;
|
||||
}
|
||||
private:
|
||||
xcb_connection_t* m_xcbConnection = nullptr;
|
||||
};
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class ApplicationLinux
|
||||
: public Application::Implementation
|
||||
@@ -27,6 +53,12 @@ namespace AzFramework
|
||||
// Application::Implementation
|
||||
void PumpSystemEventLoopOnce() override;
|
||||
void PumpSystemEventLoopUntilEmpty() override;
|
||||
private:
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
AZStd::unique_ptr<LinuxXcbConnectionManager> m_xcbConnectionManager;
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -39,11 +71,26 @@ namespace AzFramework
|
||||
ApplicationLinux::ApplicationLinux()
|
||||
{
|
||||
LinuxLifecycleEvents::Bus::Handler::BusConnect();
|
||||
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
m_xcbConnectionManager = AZStd::make_unique<LinuxXcbConnectionManagerImpl>();
|
||||
if (LinuxXcbConnectionManagerInterface::Get() == nullptr)
|
||||
{
|
||||
LinuxXcbConnectionManagerInterface::Register(m_xcbConnectionManager.get());
|
||||
}
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
ApplicationLinux::~ApplicationLinux()
|
||||
{
|
||||
#if PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
if (LinuxXcbConnectionManagerInterface::Get() == m_xcbConnectionManager.get())
|
||||
{
|
||||
LinuxXcbConnectionManagerInterface::Unregister(m_xcbConnectionManager.get());
|
||||
}
|
||||
m_xcbConnectionManager.reset();
|
||||
#endif // PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB
|
||||
LinuxLifecycleEvents::Bus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,3 +5,30 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
# Based on the linux window manager trait, perform the appropriate additional build configurations
|
||||
# Only 'xcb', 'wayland', and 'xlib' are recognized
|
||||
if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
|
||||
find_library(XCB_LIBRARY xcb)
|
||||
|
||||
set(LY_BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
${XCB_LIBRARY}
|
||||
)
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XCB)
|
||||
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "wayland")
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_WAYLAND)
|
||||
|
||||
elseif(PAL_TRAIT_LINUX_WINDOW_MANAGER STREQUAL "xlib")
|
||||
|
||||
set(LY_COMPILE_DEFINITIONS PUBLIC PAL_TRAIT_LINUX_WINDOW_MANAGER_XLIB)
|
||||
|
||||
else()
|
||||
|
||||
message(FATAL_ERROR, "Linux Window Manager ${PAL_TRAIT_LINUX_WINDOW_MANAGER} is not recognized")
|
||||
|
||||
endif()
|
||||
|
||||
@@ -43,19 +43,20 @@ namespace AzQtComponents
|
||||
{
|
||||
const QChar decimalPoint = locale.decimalPoint();
|
||||
const QChar zeroDigit = locale.zeroDigit();
|
||||
const int numToStringDecimals = AZStd::max(numDecimals, 20);
|
||||
|
||||
// We want to truncate, not round. toString will round, so we add an extra decimal place to the formatting
|
||||
// so we can remove the last value
|
||||
QString retValue = locale.toString(value, 'f', (numDecimals > 0) ? numDecimals + 1 : 0);
|
||||
// We want to truncate, not round. toString will round, so we add extra decimal places to the formatting
|
||||
// so we can remove the last values
|
||||
QString retValue = locale.toString(value, 'f', (numDecimals > 0) ? numToStringDecimals : 0);
|
||||
|
||||
// Handle special cases when we have decimals in our value
|
||||
if (numDecimals > 0)
|
||||
{
|
||||
// Truncate the extra digit now, if it's still there
|
||||
// Truncate the extra digits now, if they're still there
|
||||
int decimalPointIndex = retValue.lastIndexOf(decimalPoint);
|
||||
if ((decimalPointIndex > 0) && (retValue.size() - (decimalPointIndex + 1)) == (numDecimals + 1))
|
||||
if ((decimalPointIndex > 0) && (retValue.size() - (decimalPointIndex + 1)) == numToStringDecimals)
|
||||
{
|
||||
retValue.resize(retValue.size() - 1);
|
||||
retValue.resize(retValue.size() - (numToStringDecimals - numDecimals));
|
||||
}
|
||||
|
||||
// Remove trailing zeros, since the locale conversion won't do
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Camera
|
||||
using EditorCameraNotificationBus = AZ::EBus<EditorCameraNotifications>;
|
||||
|
||||
/**
|
||||
* This bus is for requesting any camera-view-related changes
|
||||
* This bus is for requesting any camera-view-related changes or information
|
||||
*/
|
||||
class EditorCameraViewRequests : public AZ::ComponentBus
|
||||
{
|
||||
@@ -115,6 +115,11 @@ namespace Camera
|
||||
* Sets this camera as the active view in the scene, otherwise restores the default editor camera if it was already active
|
||||
*/
|
||||
virtual void ToggleCameraAsActiveView() = 0;
|
||||
|
||||
/**
|
||||
* Gets the camera state associated with this view.
|
||||
*/
|
||||
virtual bool GetCameraState(AzFramework::CameraState& cameraState) = 0;
|
||||
};
|
||||
|
||||
using EditorCameraViewRequestBus = AZ::EBus<EditorCameraViewRequests>;
|
||||
|
||||
@@ -77,6 +77,19 @@ namespace UnitTest
|
||||
m_intSpinBox.reset();
|
||||
}
|
||||
|
||||
QString setupTruncationTest(QString textValue)
|
||||
{
|
||||
QString retval;
|
||||
m_doubleSpinBoxWithLineEdit->setDecimals(7);
|
||||
m_doubleSpinBoxWithLineEdit->setDisplayDecimals(3);
|
||||
m_doubleSpinBoxWithLineEdit->setFocus();
|
||||
m_doubleSpinBoxWithLineEdit->GetLineEdit()->setText(textValue);
|
||||
m_doubleSpinBoxWithLineEdit->clearFocus();
|
||||
|
||||
return m_doubleSpinBoxWithLineEdit->textFromValue(m_doubleSpinBoxWithLineEdit->value());
|
||||
}
|
||||
|
||||
|
||||
AZStd::unique_ptr<QWidget> m_dummyWidget;
|
||||
AZStd::unique_ptr<AzQtComponents::SpinBox> m_intSpinBox;
|
||||
AZStd::unique_ptr<AzQtComponents::DoubleSpinBox> m_doubleSpinBox;
|
||||
@@ -277,4 +290,34 @@ namespace UnitTest
|
||||
// test would result in a crash
|
||||
EXPECT_TRUE(m_intSpinBox.get() == nullptr);
|
||||
}
|
||||
|
||||
TEST_F(SpinBoxFixture, SpinBoxCheckHighValueTruncatesCorrectly)
|
||||
{
|
||||
QString value = setupTruncationTest("0.9999999");
|
||||
|
||||
EXPECT_TRUE(value == "0.999");
|
||||
}
|
||||
|
||||
TEST_F(SpinBoxFixture, SpinBoxCheckLowValueTruncatesCorrectly)
|
||||
{
|
||||
QString value = setupTruncationTest("0.0000001");
|
||||
|
||||
EXPECT_TRUE(value == "0.0");
|
||||
}
|
||||
|
||||
TEST_F(SpinBoxFixture, SpinBoxCheckBugValuesTruncatesCorrectly)
|
||||
{
|
||||
QString value = setupTruncationTest("0.12395");
|
||||
|
||||
EXPECT_TRUE(value == "0.123");
|
||||
|
||||
value = setupTruncationTest("0.94496");
|
||||
|
||||
EXPECT_TRUE(value == "0.944");
|
||||
|
||||
value = setupTruncationTest("0.0009999");
|
||||
|
||||
EXPECT_TRUE(value == "0.0");
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace O3DE::ProjectManager
|
||||
vsWherePath,
|
||||
QStringList{
|
||||
"-version",
|
||||
"16.0",
|
||||
"16.9.2",
|
||||
"-latest",
|
||||
"-requires",
|
||||
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
|
||||
@@ -50,10 +50,11 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
return AZ::Failure(QObject::tr("Visual Studio 2019 not found.\n\n"
|
||||
return AZ::Failure(QObject::tr("Visual Studio 2019 version 16.9.2 or higher not found.\n\n"
|
||||
"Visual Studio 2019 is required to build this project."
|
||||
" Install any edition of <a href='https://visualstudio.microsoft.com/downloads/'>Visual Studio 2019</a>"
|
||||
" before proceeding to the next step."));
|
||||
" or update to a newer version before proceeding to the next step."
|
||||
" While installing configure Visual Studio with these <a href='https://o3de.org/docs/welcome-guide/setup/requirements/#visual-studio-configuration'>workloads</a>."));
|
||||
}
|
||||
|
||||
} // namespace ProjectUtils
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace AZ
|
||||
// AssImp only has one bitangentStream per mesh.
|
||||
bitangentStream->SetBitangentSetIndex(0);
|
||||
|
||||
bitangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
bitangentStream->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
|
||||
bitangentStream->ReserveContainerSpace(vertexCount);
|
||||
for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
|
||||
{
|
||||
|
||||
@@ -41,45 +41,6 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void MakeBoneMap(const aiScene* scene, AZStd::unordered_map<AZStd::string, const aiBone*>& boneLookup)
|
||||
{
|
||||
AZStd::queue<const aiNode*> queue;
|
||||
AZStd::unordered_set<AZStd::string> nodesWithNoMesh;
|
||||
|
||||
queue.push(scene->mRootNode);
|
||||
|
||||
while (!queue.empty())
|
||||
{
|
||||
const aiNode* currentNode = queue.front();
|
||||
queue.pop();
|
||||
|
||||
if (currentNode->mNumMeshes == 0)
|
||||
{
|
||||
nodesWithNoMesh.emplace(currentNode->mName.C_Str());
|
||||
}
|
||||
|
||||
for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex)
|
||||
{
|
||||
queue.push(currentNode->mChildren[childIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
const aiMesh* mesh = scene->mMeshes[meshIndex];
|
||||
|
||||
for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
|
||||
{
|
||||
const aiBone* bone = mesh->mBones[boneIndex];
|
||||
|
||||
if (nodesWithNoMesh.contains(bone->mName.C_Str()))
|
||||
{
|
||||
boneLookup.emplace(bone->mName.C_Str(), bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiMatrix4x4 CalculateWorldTransform(const aiNode* currentNode)
|
||||
{
|
||||
aiMatrix4x4 transform = {};
|
||||
@@ -106,37 +67,39 @@ namespace AZ
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
bool isBone = false;
|
||||
|
||||
AZStd::unordered_multimap<AZStd::string, const aiBone*> boneByNameMap;
|
||||
FindAllBones(scene, boneByNameMap);
|
||||
|
||||
bool isBone = FindFirstBoneByNodeName(currentNode, boneByNameMap);
|
||||
if (!isBone)
|
||||
{
|
||||
AZStd::unordered_map<AZStd::string, const aiBone*> boneLookup;
|
||||
MakeBoneMap(scene, boneLookup);
|
||||
|
||||
isBone = boneLookup.contains(currentNode->mName.C_Str());
|
||||
|
||||
// If we have an animation, the bones will be listed in there
|
||||
if (!isBone)
|
||||
for(unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
{
|
||||
for(unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
aiAnimation* animation = scene->mAnimations[animIndex];
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < animation->mNumChannels; ++channelIndex)
|
||||
{
|
||||
aiAnimation* animation = scene->mAnimations[animIndex];
|
||||
aiNodeAnim* nodeAnim = animation->mChannels[channelIndex];
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < animation->mNumChannels; ++channelIndex)
|
||||
{
|
||||
aiNodeAnim* nodeAnim = animation->mChannels[channelIndex];
|
||||
|
||||
if (nodeAnim->mNodeName == currentNode->mName)
|
||||
{
|
||||
isBone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBone)
|
||||
if (nodeAnim->mNodeName == currentNode->mName)
|
||||
{
|
||||
isBone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// In case any of the children, or children of children is a bone, make sure to not skip this node.
|
||||
// Don't do this for the scene root itself, else wise all mesh nodes will be exported as bones and pollute the skeleton.
|
||||
if (currentNode != scene->mRootNode &&
|
||||
RecursiveHasChildBone(currentNode, boneByNameMap))
|
||||
{
|
||||
isBone = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
#include <SceneAPI/SceneBuilder/Importers/AssImpImporterUtilities.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -85,6 +86,107 @@ namespace AZ
|
||||
|
||||
return combinedTransform;
|
||||
}
|
||||
|
||||
void FindAllBones(const aiScene* scene, AZStd::unordered_multimap<AZStd::string, const aiBone*>& outBoneByNameMap)
|
||||
{
|
||||
outBoneByNameMap.clear();
|
||||
AZStd::queue<const aiNode*> queue;
|
||||
AZStd::unordered_set<AZStd::string> nodesWithNoMesh;
|
||||
|
||||
queue.push(scene->mRootNode);
|
||||
|
||||
while (!queue.empty())
|
||||
{
|
||||
const aiNode* currentNode = queue.front();
|
||||
queue.pop();
|
||||
|
||||
if (currentNode->mNumMeshes == 0)
|
||||
{
|
||||
nodesWithNoMesh.emplace(currentNode->mName.C_Str());
|
||||
}
|
||||
|
||||
for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex)
|
||||
{
|
||||
queue.push(currentNode->mChildren[childIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
const aiMesh* mesh = scene->mMeshes[meshIndex];
|
||||
|
||||
for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
|
||||
{
|
||||
const aiBone* bone = mesh->mBones[boneIndex];
|
||||
|
||||
if (nodesWithNoMesh.contains(bone->mName.C_Str()))
|
||||
{
|
||||
outBoneByNameMap.emplace(bone->mName.C_Str(), bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataTypes::MatrixType GetLocalSpaceBindPoseTransform(const aiScene* scene, const aiNode* node)
|
||||
{
|
||||
AZStd::unordered_multimap<AZStd::string, const aiBone*> boneByNameMap;
|
||||
FindAllBones(scene, boneByNameMap);
|
||||
|
||||
const aiBone* bone = FindFirstBoneByNodeName(node, boneByNameMap);
|
||||
if (bone)
|
||||
{
|
||||
const DataTypes::MatrixType inverseOffsetMatrix = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(bone->mOffsetMatrix).GetInverseFull();
|
||||
|
||||
const aiBone* parentBone = FindFirstBoneByNodeName(node->mParent, boneByNameMap);
|
||||
if (parentBone)
|
||||
{
|
||||
const DataTypes::MatrixType parentBoneOffsetMatrix = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(parentBone->mOffsetMatrix);
|
||||
return parentBoneOffsetMatrix * inverseOffsetMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
return inverseOffsetMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
return AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(node));
|
||||
}
|
||||
|
||||
const aiBone* FindFirstBoneByNodeName(const aiNode* node, AZStd::unordered_multimap<AZStd::string, const aiBone*>& boneByNameMap)
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto boneIterator = boneByNameMap.find(node->mName.C_Str());
|
||||
if (boneIterator != boneByNameMap.end())
|
||||
{
|
||||
return boneIterator->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RecursiveHasChildBone(const aiNode* node, const AZStd::unordered_multimap<AZStd::string, const aiBone*>& boneByNameMap)
|
||||
{
|
||||
const bool isBone = boneByNameMap.contains(node->mName.C_Str());
|
||||
if (isBone)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int childIndex = 0; childIndex < node->mNumChildren; ++childIndex)
|
||||
{
|
||||
const aiNode* childNode = node->mChildren[childIndex];
|
||||
if (RecursiveHasChildBone(childNode, boneByNameMap))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace SceneBuilder
|
||||
} // namespace SceneAPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -9,13 +9,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <assimp/matrix4x4.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/MatrixType.h>
|
||||
|
||||
struct aiBone;
|
||||
struct aiNode;
|
||||
struct aiScene;
|
||||
struct aiString;
|
||||
|
||||
|
||||
namespace AZ::SceneAPI::SceneBuilder
|
||||
{
|
||||
inline constexpr char PivotNodeMarker[] = "_$AssimpFbx$_";
|
||||
@@ -30,5 +32,16 @@ namespace AZ::SceneAPI::SceneBuilder
|
||||
|
||||
// Gets the entire, combined local transform for a node taking pivot nodes into account. When pivot nodes are not used, this just returns the node's transform
|
||||
aiMatrix4x4 GetConcatenatedLocalTransform(const aiNode* currentNode);
|
||||
|
||||
DataTypes::MatrixType GetLocalSpaceBindPoseTransform(const aiScene* scene, const aiNode* node);
|
||||
|
||||
// Gather all bones from the scene. (Bone in AssImp corresponds to nodes that influence any of the vertices).
|
||||
void FindAllBones(const aiScene* scene, AZStd::unordered_multimap<AZStd::string, const aiBone*>& outBoneByNameMap);
|
||||
|
||||
// Find the first bone with the name of the given node.
|
||||
const aiBone* FindFirstBoneByNodeName(const aiNode* node, AZStd::unordered_multimap<AZStd::string, const aiBone*>& boneByNameMap);
|
||||
|
||||
// Check if the given node or any of its children, or children of children, is a bone by checking if the node name is part of the given map.
|
||||
bool RecursiveHasChildBone(const aiNode* node, const AZStd::unordered_multimap<AZStd::string, const aiBone*>& boneByNameMap);
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace AZ
|
||||
// AssImp only has one tangentStream per mesh.
|
||||
tangentStream->SetTangentSetIndex(0);
|
||||
|
||||
tangentStream->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
tangentStream->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
|
||||
tangentStream->ReserveContainerSpace(vertexCount);
|
||||
for (int sdkMeshIndex = 0; sdkMeshIndex < currentNode->mNumMeshes; ++sdkMeshIndex)
|
||||
{
|
||||
|
||||
@@ -42,45 +42,6 @@ namespace AZ
|
||||
serializeContext->Class<AssImpTransformImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
}
|
||||
}
|
||||
|
||||
void GetAllBones(const aiScene* scene, AZStd::unordered_multimap<AZStd::string, const aiBone*>& boneLookup)
|
||||
{
|
||||
AZStd::queue<const aiNode*> queue;
|
||||
AZStd::unordered_set<AZStd::string> nodesWithNoMesh;
|
||||
|
||||
queue.push(scene->mRootNode);
|
||||
|
||||
while (!queue.empty())
|
||||
{
|
||||
const aiNode* currentNode = queue.front();
|
||||
queue.pop();
|
||||
|
||||
if (currentNode->mNumMeshes == 0)
|
||||
{
|
||||
nodesWithNoMesh.emplace(currentNode->mName.C_Str());
|
||||
}
|
||||
|
||||
for (int childIndex = 0; childIndex < currentNode->mNumChildren; ++childIndex)
|
||||
{
|
||||
queue.push(currentNode->mChildren[childIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
const aiMesh* mesh = scene->mMeshes[meshIndex];
|
||||
|
||||
for (unsigned boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex)
|
||||
{
|
||||
const aiBone* bone = mesh->mBones[boneIndex];
|
||||
|
||||
if (nodesWithNoMesh.contains(bone->mName.C_Str()))
|
||||
{
|
||||
boneLookup.emplace(bone->mName.C_Str(), bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Events::ProcessingResult AssImpTransformImporter::ImportTransform(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
@@ -93,54 +54,7 @@ namespace AZ
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
AZStd::unordered_multimap<AZStd::string, const aiBone*> boneLookup;
|
||||
GetAllBones(scene, boneLookup);
|
||||
|
||||
auto boneIterator = boneLookup.find(currentNode->mName.C_Str());
|
||||
const bool isBone = boneIterator != boneLookup.end();
|
||||
|
||||
DataTypes::MatrixType localTransform;
|
||||
|
||||
if (isBone)
|
||||
{
|
||||
AZStd::vector<DataTypes::MatrixType> offsets, inverseOffsets;
|
||||
auto iteratingNode = currentNode;
|
||||
|
||||
while (iteratingNode && boneLookup.count(iteratingNode->mName.C_Str()))
|
||||
{
|
||||
AZStd::string name = iteratingNode->mName.C_Str();
|
||||
|
||||
auto range = boneLookup.equal_range(name);
|
||||
|
||||
if (range.first != range.second)
|
||||
{
|
||||
// There can be multiple offsetMatrices for a given bone, we're only interested in grabbing the first one
|
||||
auto boneFirstOffsetMatrix = range.first->second->mOffsetMatrix;
|
||||
auto azMat = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(boneFirstOffsetMatrix);
|
||||
offsets.push_back(azMat);
|
||||
inverseOffsets.push_back(azMat.GetInverseFull());
|
||||
}
|
||||
|
||||
iteratingNode = iteratingNode->mParent;
|
||||
}
|
||||
|
||||
if (inverseOffsets.size() == 1)
|
||||
{
|
||||
// If this is the root bone, just use the inverseOffset, otherwise the equation below just results in the identity matrix
|
||||
localTransform = inverseOffsets[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
localTransform = offsets.at(1) // parent bone offset
|
||||
* inverseOffsets.at(inverseOffsets.size() - 1) // Inverse of root bone offset
|
||||
* offsets.at(offsets.size() - 1) // Root bone offset
|
||||
* inverseOffsets.at(0); // Inverse of current node offset
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(GetConcatenatedLocalTransform(currentNode));
|
||||
}
|
||||
DataTypes::MatrixType localTransform = GetLocalSpaceBindPoseTransform(scene, currentNode);
|
||||
|
||||
// Don't bother adding a node with the identity matrix
|
||||
if (localTransform == DataTypes::MatrixType::Identity())
|
||||
|
||||
@@ -17,32 +17,24 @@ namespace AZ
|
||||
class Vector3;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneAPI::DataTypes
|
||||
{
|
||||
namespace SceneAPI
|
||||
class IMeshVertexBitangentData
|
||||
: public IGraphObject
|
||||
{
|
||||
namespace DataTypes
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(IMeshVertexBitangentData, "{6C8F6109-B0BD-49D1-A998-4A4946557DF9}", IGraphObject);
|
||||
|
||||
class IMeshVertexBitangentData
|
||||
: public IGraphObject
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(IMeshVertexBitangentData, "{6C8F6109-B0BD-49D1-A998-4A4946557DF9}", IGraphObject);
|
||||
virtual ~IMeshVertexBitangentData() override = default;
|
||||
|
||||
virtual ~IMeshVertexBitangentData() override = default;
|
||||
void CloneAttributesFrom([[maybe_unused]] const IGraphObject* sourceObject) override {}
|
||||
|
||||
void CloneAttributesFrom([[maybe_unused]] const IGraphObject* sourceObject) override {}
|
||||
|
||||
virtual size_t GetCount() const = 0;
|
||||
virtual const AZ::Vector3& GetBitangent(size_t index) const = 0;
|
||||
virtual void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) = 0;
|
||||
virtual void SetBitangentSetIndex(size_t setIndex) = 0;
|
||||
virtual size_t GetBitangentSetIndex() const = 0;
|
||||
virtual TangentSpace GetTangentSpace() const = 0;
|
||||
virtual void SetTangentSpace(TangentSpace space) = 0;
|
||||
};
|
||||
|
||||
} // DataTypes
|
||||
} // SceneAPI
|
||||
} // AZ
|
||||
virtual size_t GetCount() const = 0;
|
||||
virtual const AZ::Vector3& GetBitangent(size_t index) const = 0;
|
||||
virtual void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) = 0;
|
||||
virtual void SetBitangentSetIndex(size_t setIndex) = 0;
|
||||
virtual size_t GetBitangentSetIndex() const = 0;
|
||||
virtual TangentGenerationMethod GetGenerationMethod() const = 0;
|
||||
virtual void SetGenerationMethod(TangentGenerationMethod method) = 0;
|
||||
};
|
||||
} // AZ::SceneAPI::DataTypes
|
||||
|
||||
@@ -16,42 +16,36 @@ namespace AZ
|
||||
class Vector4;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneAPI::DataTypes
|
||||
{
|
||||
namespace SceneAPI
|
||||
enum class TangentGenerationMethod
|
||||
{
|
||||
namespace DataTypes
|
||||
{
|
||||
enum class TangentSpace
|
||||
{
|
||||
FromSourceScene = 0,
|
||||
MikkT = 1
|
||||
};
|
||||
FromSourceScene = 0,
|
||||
MikkT = 1
|
||||
};
|
||||
|
||||
enum class BitangentMethod
|
||||
{
|
||||
UseFromTangentSpace = 0,
|
||||
Orthogonal = 1
|
||||
};
|
||||
enum class MikkTSpaceMethod
|
||||
{
|
||||
TSpace = 0,
|
||||
TSpaceBasic = 1
|
||||
};
|
||||
|
||||
class IMeshVertexTangentData
|
||||
: public IGraphObject
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(IMeshVertexTangentData, "{B24084FF-09B1-4EE5-BA5B-2D392E92ECC1}", IGraphObject);
|
||||
class IMeshVertexTangentData
|
||||
: public IGraphObject
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(IMeshVertexTangentData, "{B24084FF-09B1-4EE5-BA5B-2D392E92ECC1}", IGraphObject);
|
||||
|
||||
virtual ~IMeshVertexTangentData() override = default;
|
||||
virtual ~IMeshVertexTangentData() override = default;
|
||||
|
||||
void CloneAttributesFrom([[maybe_unused]] const IGraphObject* sourceObject) override {}
|
||||
void CloneAttributesFrom([[maybe_unused]] const IGraphObject* sourceObject) override {}
|
||||
|
||||
virtual size_t GetCount() const = 0;
|
||||
virtual const AZ::Vector4& GetTangent(size_t index) const = 0;
|
||||
virtual void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) = 0;
|
||||
virtual void SetTangentSetIndex(size_t setIndex) = 0;
|
||||
virtual size_t GetTangentSetIndex() const = 0;
|
||||
virtual TangentSpace GetTangentSpace() const = 0;
|
||||
virtual void SetTangentSpace(TangentSpace space) = 0;
|
||||
};
|
||||
} // DataTypes
|
||||
} // SceneAPI
|
||||
} // AZ
|
||||
virtual size_t GetCount() const = 0;
|
||||
virtual const AZ::Vector4& GetTangent(size_t index) const = 0;
|
||||
virtual void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) = 0;
|
||||
virtual void SetTangentSetIndex(size_t setIndex) = 0;
|
||||
virtual size_t GetTangentSetIndex() const = 0;
|
||||
virtual TangentGenerationMethod GetGenerationMethod() const = 0;
|
||||
virtual void SetGenerationMethod(TangentGenerationMethod method) = 0;
|
||||
};
|
||||
} // AZ::SceneAPI::DataTypes
|
||||
|
||||
@@ -10,110 +10,95 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
namespace SceneData
|
||||
void MeshVertexBitangentData::Reflect(ReflectContext* context)
|
||||
{
|
||||
namespace GraphData
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
void MeshVertexBitangentData::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<MeshVertexBitangentData>()->Version(2);
|
||||
}
|
||||
serializeContext->Class<MeshVertexBitangentData>()->Version(2);
|
||||
}
|
||||
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<MeshVertexBitangentData>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Method("GetCount", &MeshVertexBitangentData::GetCount)
|
||||
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
|
||||
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexBitangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<MeshVertexBitangentData>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Method("GetCount", &MeshVertexBitangentData::GetCount)
|
||||
->Method("GetBitangent", &MeshVertexBitangentData::GetBitangent)
|
||||
->Method("GetBitangentSetIndex", &MeshVertexBitangentData::GetBitangentSetIndex)
|
||||
->Method("GetGenerationMethod", &MeshVertexBitangentData::GetGenerationMethod)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
|
||||
{
|
||||
IMeshVertexBitangentData::CloneAttributesFrom(sourceObject);
|
||||
if (const auto* typedSource = azrtti_cast<const MeshVertexBitangentData*>(sourceObject))
|
||||
{
|
||||
SetTangentSpace(typedSource->GetTangentSpace());
|
||||
SetBitangentSetIndex(typedSource->GetBitangentSetIndex());
|
||||
}
|
||||
}
|
||||
void MeshVertexBitangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
|
||||
{
|
||||
IMeshVertexBitangentData::CloneAttributesFrom(sourceObject);
|
||||
if (const auto* typedSource = azrtti_cast<const MeshVertexBitangentData*>(sourceObject))
|
||||
{
|
||||
SetGenerationMethod(typedSource->GetGenerationMethod());
|
||||
SetBitangentSetIndex(typedSource->GetBitangentSetIndex());
|
||||
}
|
||||
}
|
||||
|
||||
size_t MeshVertexBitangentData::GetCount() const
|
||||
{
|
||||
return m_bitangents.size();
|
||||
}
|
||||
size_t MeshVertexBitangentData::GetCount() const
|
||||
{
|
||||
return m_bitangents.size();
|
||||
}
|
||||
|
||||
const AZ::Vector3& MeshVertexBitangentData::GetBitangent(size_t index) const
|
||||
{
|
||||
AZ_Assert(index < m_bitangents.size(), "Invalid index %i for mesh bitangents.", index);
|
||||
return m_bitangents[index];
|
||||
}
|
||||
|
||||
const AZ::Vector3& MeshVertexBitangentData::GetBitangent(size_t index) const
|
||||
{
|
||||
AZ_Assert(index < m_bitangents.size(), "Invalid index %i for mesh bitangents.", index);
|
||||
return m_bitangents[index];
|
||||
}
|
||||
void MeshVertexBitangentData::ReserveContainerSpace(size_t numVerts)
|
||||
{
|
||||
m_bitangents.reserve(numVerts);
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::Resize(size_t numVerts)
|
||||
{
|
||||
m_bitangents.resize(numVerts);
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::ReserveContainerSpace(size_t numVerts)
|
||||
{
|
||||
m_bitangents.reserve(numVerts);
|
||||
}
|
||||
void MeshVertexBitangentData::AppendBitangent(const AZ::Vector3& bitangent)
|
||||
{
|
||||
m_bitangents.push_back(bitangent);
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent)
|
||||
{
|
||||
m_bitangents[vertexIndex] = bitangent;
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::Resize(size_t numVerts)
|
||||
{
|
||||
m_bitangents.resize(numVerts);
|
||||
}
|
||||
void MeshVertexBitangentData::SetBitangentSetIndex(size_t setIndex)
|
||||
{
|
||||
m_setIndex = setIndex;
|
||||
}
|
||||
|
||||
size_t MeshVertexBitangentData::GetBitangentSetIndex() const
|
||||
{
|
||||
return m_setIndex;
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::AppendBitangent(const AZ::Vector3& bitangent)
|
||||
{
|
||||
m_bitangents.push_back(bitangent);
|
||||
}
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod MeshVertexBitangentData::GetGenerationMethod() const
|
||||
{
|
||||
return m_generationMethod;
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method)
|
||||
{
|
||||
m_generationMethod = method;
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent)
|
||||
{
|
||||
m_bitangents[vertexIndex] = bitangent;
|
||||
}
|
||||
|
||||
|
||||
void MeshVertexBitangentData::SetBitangentSetIndex(size_t setIndex)
|
||||
{
|
||||
m_setIndex = setIndex;
|
||||
}
|
||||
|
||||
|
||||
size_t MeshVertexBitangentData::GetBitangentSetIndex() const
|
||||
{
|
||||
return m_setIndex;
|
||||
}
|
||||
|
||||
|
||||
AZ::SceneAPI::DataTypes::TangentSpace MeshVertexBitangentData::GetTangentSpace() const
|
||||
{
|
||||
return m_tangentSpace;
|
||||
}
|
||||
|
||||
|
||||
void MeshVertexBitangentData::SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space)
|
||||
{
|
||||
m_tangentSpace = space;
|
||||
}
|
||||
|
||||
void MeshVertexBitangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
|
||||
{
|
||||
output.Write("Bitangents", m_bitangents);
|
||||
output.Write("TangentSpace", aznumeric_cast<int64_t>(m_tangentSpace));
|
||||
}
|
||||
} // GraphData
|
||||
} // SceneData
|
||||
} // AZ
|
||||
void MeshVertexBitangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
|
||||
{
|
||||
output.Write("Bitangents", m_bitangents);
|
||||
output.Write("GenerationMethod", aznumeric_cast<int64_t>(m_generationMethod));
|
||||
}
|
||||
} // AZ::SceneData::GraphData
|
||||
|
||||
@@ -10,51 +10,41 @@
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexBitangentData.h>
|
||||
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
namespace SceneData
|
||||
class SCENE_DATA_CLASS MeshVertexBitangentData
|
||||
: public AZ::SceneAPI::DataTypes::IMeshVertexBitangentData
|
||||
{
|
||||
namespace GraphData
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(MeshVertexBitangentData, "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", AZ::SceneAPI::DataTypes::IMeshVertexBitangentData);
|
||||
|
||||
class SCENE_DATA_CLASS MeshVertexBitangentData
|
||||
: public AZ::SceneAPI::DataTypes::IMeshVertexBitangentData
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(MeshVertexBitangentData, "{F56FB088-4C92-4453-AFE9-4E820F03FA90}", AZ::SceneAPI::DataTypes::IMeshVertexBitangentData);
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
SCENE_DATA_API ~MeshVertexBitangentData() override = default;
|
||||
|
||||
SCENE_DATA_API ~MeshVertexBitangentData() override = default;
|
||||
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
|
||||
|
||||
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
|
||||
SCENE_DATA_API size_t GetCount() const override;
|
||||
SCENE_DATA_API const AZ::Vector3& GetBitangent(size_t index) const override;
|
||||
SCENE_DATA_API void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) override;
|
||||
|
||||
SCENE_DATA_API size_t GetCount() const override;
|
||||
SCENE_DATA_API const AZ::Vector3& GetBitangent(size_t index) const override;
|
||||
SCENE_DATA_API void SetBitangent(size_t vertexIndex, const AZ::Vector3& bitangent) override;
|
||||
SCENE_DATA_API void SetBitangentSetIndex(size_t setIndex) override;
|
||||
SCENE_DATA_API size_t GetBitangentSetIndex() const override;
|
||||
|
||||
SCENE_DATA_API void SetBitangentSetIndex(size_t setIndex) override;
|
||||
SCENE_DATA_API size_t GetBitangentSetIndex() const override;
|
||||
SCENE_DATA_API void Resize(size_t numVerts);
|
||||
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
|
||||
SCENE_DATA_API void AppendBitangent(const AZ::Vector3& bitangent);
|
||||
|
||||
SCENE_DATA_API void Resize(size_t numVerts);
|
||||
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
|
||||
SCENE_DATA_API void AppendBitangent(const AZ::Vector3& bitangent);
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const override;
|
||||
SCENE_DATA_API void SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method) override;
|
||||
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const override;
|
||||
SCENE_DATA_API void SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space) override;
|
||||
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector3> m_bitangents;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
|
||||
} // GraphData
|
||||
} // SceneData
|
||||
} // AZ
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector3> m_bitangents;
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
} // AZ::SceneData::GraphData
|
||||
|
||||
@@ -10,112 +10,96 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
namespace SceneData
|
||||
void MeshVertexTangentData::Reflect(ReflectContext* context)
|
||||
{
|
||||
namespace GraphData
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
void MeshVertexTangentData::Reflect(ReflectContext* context)
|
||||
{
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<MeshVertexTangentData>()->Version(2);
|
||||
}
|
||||
serializeContext->Class<MeshVertexTangentData>()->Version(2);
|
||||
}
|
||||
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<MeshVertexTangentData>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Method("GetCount", &MeshVertexTangentData::GetCount)
|
||||
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
|
||||
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
|
||||
->Method("GetTangentSpace", &MeshVertexTangentData::GetTangentSpace)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentSpace::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
BehaviorContext* behaviorContext = azrtti_cast<BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<MeshVertexTangentData>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Module, "scene")
|
||||
->Method("GetCount", &MeshVertexTangentData::GetCount)
|
||||
->Method("GetTangent", &MeshVertexTangentData::GetTangent)
|
||||
->Method("GetTangentSetIndex", &MeshVertexTangentData::GetTangentSetIndex)
|
||||
->Method("GetGenerationMethod", &MeshVertexTangentData::GetGenerationMethod)
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene>("FromSourceScene")
|
||||
->Enum<(int)SceneAPI::DataTypes::TangentGenerationMethod::MikkT>("MikkT");
|
||||
}
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
|
||||
{
|
||||
IMeshVertexTangentData::CloneAttributesFrom(sourceObject);
|
||||
if (const auto* typedSource = azrtti_cast<const MeshVertexTangentData*>(sourceObject))
|
||||
{
|
||||
SetTangentSpace(typedSource->GetTangentSpace());
|
||||
SetTangentSetIndex(typedSource->GetTangentSetIndex());
|
||||
}
|
||||
}
|
||||
void MeshVertexTangentData::CloneAttributesFrom(const IGraphObject* sourceObject)
|
||||
{
|
||||
IMeshVertexTangentData::CloneAttributesFrom(sourceObject);
|
||||
if (const auto* typedSource = azrtti_cast<const MeshVertexTangentData*>(sourceObject))
|
||||
{
|
||||
SetGenerationMethod(typedSource->GetGenerationMethod());
|
||||
SetTangentSetIndex(typedSource->GetTangentSetIndex());
|
||||
}
|
||||
}
|
||||
|
||||
size_t MeshVertexTangentData::GetCount() const
|
||||
{
|
||||
return m_tangents.size();
|
||||
}
|
||||
size_t MeshVertexTangentData::GetCount() const
|
||||
{
|
||||
return m_tangents.size();
|
||||
}
|
||||
|
||||
const AZ::Vector4& MeshVertexTangentData::GetTangent(size_t index) const
|
||||
{
|
||||
AZ_Assert(index < m_tangents.size(), "Invalid index %i for mesh tangents.", index);
|
||||
return m_tangents[index];
|
||||
}
|
||||
|
||||
const AZ::Vector4& MeshVertexTangentData::GetTangent(size_t index) const
|
||||
{
|
||||
AZ_Assert(index < m_tangents.size(), "Invalid index %i for mesh tangents.", index);
|
||||
return m_tangents[index];
|
||||
}
|
||||
void MeshVertexTangentData::ReserveContainerSpace(size_t numVerts)
|
||||
{
|
||||
m_tangents.reserve(numVerts);
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::Resize(size_t numVerts)
|
||||
{
|
||||
m_tangents.resize(numVerts);
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::ReserveContainerSpace(size_t numVerts)
|
||||
{
|
||||
m_tangents.reserve(numVerts);
|
||||
}
|
||||
void MeshVertexTangentData::AppendTangent(const AZ::Vector4& tangent)
|
||||
{
|
||||
m_tangents.push_back(tangent);
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
|
||||
{
|
||||
output.Write("Tangents", m_tangents);
|
||||
output.Write("GenerationMethod", aznumeric_cast<int64_t>(m_generationMethod));
|
||||
output.Write("SetIndex", aznumeric_cast<uint64_t>(m_setIndex));
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::Resize(size_t numVerts)
|
||||
{
|
||||
m_tangents.resize(numVerts);
|
||||
}
|
||||
void MeshVertexTangentData::SetTangent(size_t vertexIndex, const AZ::Vector4& tangent)
|
||||
{
|
||||
m_tangents[vertexIndex] = tangent;
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::SetTangentSetIndex(size_t setIndex)
|
||||
{
|
||||
m_setIndex = setIndex;
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::AppendTangent(const AZ::Vector4& tangent)
|
||||
{
|
||||
m_tangents.push_back(tangent);
|
||||
}
|
||||
size_t MeshVertexTangentData::GetTangentSetIndex() const
|
||||
{
|
||||
return m_setIndex;
|
||||
}
|
||||
|
||||
void MeshVertexTangentData::GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const
|
||||
{
|
||||
output.Write("Tangents", m_tangents);
|
||||
output.Write("TangentSpace", aznumeric_cast<int64_t>(m_tangentSpace));
|
||||
output.Write("SetIndex", aznumeric_cast<uint64_t>(m_setIndex));
|
||||
}
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod MeshVertexTangentData::GetGenerationMethod() const
|
||||
{
|
||||
return m_generationMethod;
|
||||
}
|
||||
|
||||
|
||||
void MeshVertexTangentData::SetTangent(size_t vertexIndex, const AZ::Vector4& tangent)
|
||||
{
|
||||
m_tangents[vertexIndex] = tangent;
|
||||
}
|
||||
|
||||
|
||||
void MeshVertexTangentData::SetTangentSetIndex(size_t setIndex)
|
||||
{
|
||||
m_setIndex = setIndex;
|
||||
}
|
||||
|
||||
|
||||
size_t MeshVertexTangentData::GetTangentSetIndex() const
|
||||
{
|
||||
return m_setIndex;
|
||||
}
|
||||
|
||||
|
||||
AZ::SceneAPI::DataTypes::TangentSpace MeshVertexTangentData::GetTangentSpace() const
|
||||
{
|
||||
return m_tangentSpace;
|
||||
}
|
||||
|
||||
|
||||
void MeshVertexTangentData::SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space)
|
||||
{
|
||||
m_tangentSpace = space;
|
||||
}
|
||||
|
||||
} // GraphData
|
||||
} // SceneData
|
||||
} // AZ
|
||||
void MeshVertexTangentData::SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method)
|
||||
{
|
||||
m_generationMethod = method;
|
||||
}
|
||||
} // AZ::SceneData::GraphData
|
||||
|
||||
@@ -14,46 +14,39 @@
|
||||
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IMeshVertexTangentData.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::SceneData::GraphData
|
||||
{
|
||||
namespace SceneData
|
||||
class SCENE_DATA_CLASS MeshVertexTangentData
|
||||
: public AZ::SceneAPI::DataTypes::IMeshVertexTangentData
|
||||
{
|
||||
namespace GraphData
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(MeshVertexTangentData, "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", AZ::SceneAPI::DataTypes::IMeshVertexTangentData);
|
||||
|
||||
class SCENE_DATA_CLASS MeshVertexTangentData
|
||||
: public AZ::SceneAPI::DataTypes::IMeshVertexTangentData
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(MeshVertexTangentData, "{C16F0F38-8F8F-45A2-A33B-F2758922A7C4}", AZ::SceneAPI::DataTypes::IMeshVertexTangentData);
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
SCENE_DATA_API ~MeshVertexTangentData() override = default;
|
||||
|
||||
SCENE_DATA_API ~MeshVertexTangentData() override = default;
|
||||
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
|
||||
|
||||
SCENE_DATA_API void CloneAttributesFrom(const IGraphObject* sourceObject) override;
|
||||
SCENE_DATA_API size_t GetCount() const override;
|
||||
SCENE_DATA_API const AZ::Vector4& GetTangent(size_t index) const override;
|
||||
SCENE_DATA_API void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) override;
|
||||
|
||||
SCENE_DATA_API size_t GetCount() const override;
|
||||
SCENE_DATA_API const AZ::Vector4& GetTangent(size_t index) const override;
|
||||
SCENE_DATA_API void SetTangent(size_t vertexIndex, const AZ::Vector4& tangent) override;
|
||||
SCENE_DATA_API void SetTangentSetIndex(size_t setIndex) override;
|
||||
SCENE_DATA_API size_t GetTangentSetIndex() const override;
|
||||
|
||||
SCENE_DATA_API void SetTangentSetIndex(size_t setIndex) override;
|
||||
SCENE_DATA_API size_t GetTangentSetIndex() const override;
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const override;
|
||||
SCENE_DATA_API void SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod method) override;
|
||||
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const override;
|
||||
SCENE_DATA_API void SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace space) override;
|
||||
SCENE_DATA_API void Resize(size_t numVerts);
|
||||
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
|
||||
SCENE_DATA_API void AppendTangent(const AZ::Vector4& tangent);
|
||||
|
||||
SCENE_DATA_API void Resize(size_t numVerts);
|
||||
SCENE_DATA_API void ReserveContainerSpace(size_t numVerts);
|
||||
SCENE_DATA_API void AppendTangent(const AZ::Vector4& tangent);
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
|
||||
SCENE_DATA_API void GetDebugOutput(AZ::SceneAPI::Utilities::DebugOutput& output) const override;
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector4> m_tangents;
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace = AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
|
||||
} // GraphData
|
||||
} // SceneData
|
||||
} // AZ
|
||||
protected:
|
||||
AZStd::vector<AZ::Vector4> m_tangents;
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene;
|
||||
size_t m_setIndex = 0;
|
||||
};
|
||||
} // AZ::SceneData::GraphData
|
||||
|
||||
@@ -26,13 +26,22 @@ namespace AZ
|
||||
{
|
||||
TangentsRule::TangentsRule()
|
||||
: DataTypes::IRule()
|
||||
, m_tangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT)
|
||||
{
|
||||
}
|
||||
|
||||
AZ::SceneAPI::DataTypes::TangentSpace TangentsRule::GetTangentSpace() const
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod TangentsRule::GetGenerationMethod() const
|
||||
{
|
||||
return m_tangentSpace;
|
||||
return m_generationMethod;
|
||||
}
|
||||
|
||||
AZ::SceneAPI::DataTypes::MikkTSpaceMethod TangentsRule::GetMikkTSpaceMethod() const
|
||||
{
|
||||
return m_tSpaceMethod;
|
||||
}
|
||||
|
||||
AZ::Crc32 TangentsRule::GetSpaceMethodVisibility() const
|
||||
{
|
||||
return (m_generationMethod == AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT) ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
|
||||
}
|
||||
|
||||
void TangentsRule::Reflect(AZ::ReflectContext* context)
|
||||
@@ -43,20 +52,29 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(3)
|
||||
->Field("tangentSpace", &TangentsRule::m_tangentSpace);
|
||||
serializeContext->Class<TangentsRule, DataTypes::IRule>()->Version(4)
|
||||
->Field("tangentSpace", &TangentsRule::m_generationMethod)
|
||||
->Field("tSpaceMethod", &TangentsRule::m_tSpaceMethod);
|
||||
|
||||
AZ::EditContext* editContext = serializeContext->GetEditContext();
|
||||
if (editContext)
|
||||
{
|
||||
editContext->Class<TangentsRule>("Tangents", "Specify how tangents are imported or generated.")
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->Attribute("AutoExpand", true)
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tangentSpace, "Tangent space", "Specify the tangent space used for normal map baking. Choose 'From Fbx' to extract the tangents and bitangents directly from the Fbx file. When there is no tangents rule or the Fbx has no tangents stored inside it, the 'MikkT' option will be used with orthogonal tangents of unit length, so with the normalize option enabled, using the first UV set.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene, "From Source Scene")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentSpace::MikkT, "MikkT")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->Attribute("AutoExpand", true)
|
||||
->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_generationMethod, "Generation Method", "Specify the tangent generation method. Choose 'From Source Scene' to extract the tangents and bitangents directly from the source scene file. When there is no tangents rule or the source scene has no tangents stored inside it, the 'MikkT' option will be used.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene, "From Source Scene")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT, "MikkT")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
|
||||
->DataElement(AZ::Edit::UIHandlers::ComboBox, &AZ::SceneAPI::SceneData::TangentsRule::m_tSpaceMethod, "TSpace Method",
|
||||
"TSpace generates the tangents and bitangents with their true magnitudes which can be used for relief mapping effects. "
|
||||
" It calculates the 'real' bitangent which may not be perpendicular to the tangent. "
|
||||
"However, both, the tangent and bitangent are perpendicular to the vertex normal. "
|
||||
"TSpaceBasic calculates unit vector tangents and bitangents at pixel/vertex level which are sufficient for basic normal mapping.")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpace, "TSpace")
|
||||
->EnumAttribute(AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpaceBasic, "TSpaceBasic")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &TangentsRule::GetSpaceMethodVisibility);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,12 +45,17 @@ namespace AZ
|
||||
SCENE_DATA_API TangentsRule();
|
||||
SCENE_DATA_API ~TangentsRule() override = default;
|
||||
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentSpace GetTangentSpace() const;
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::TangentGenerationMethod GetGenerationMethod() const;
|
||||
SCENE_DATA_API AZ::SceneAPI::DataTypes::MikkTSpaceMethod GetMikkTSpaceMethod() const;
|
||||
|
||||
static void Reflect(ReflectContext* context);
|
||||
|
||||
protected:
|
||||
AZ::SceneAPI::DataTypes::TangentSpace m_tangentSpace; /**< Specifies how to handle tangents. Either generate them, or import them. */
|
||||
AZ::SceneAPI::DataTypes::TangentGenerationMethod m_generationMethod = AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT; /**< Specifies how to handle tangents. Either generate them, or import them. */
|
||||
|
||||
// MikkT specific settings
|
||||
AZ::Crc32 GetSpaceMethodVisibility() const;
|
||||
AZ::SceneAPI::DataTypes::MikkTSpaceMethod m_tSpaceMethod = AZ::SceneAPI::DataTypes::MikkTSpaceMethod::TSpace;
|
||||
};
|
||||
} // SceneData
|
||||
} // SceneAPI
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace AZ
|
||||
auto* bitangentData = AZStd::any_cast<AZ::SceneData::GraphData::MeshVertexBitangentData>(&data);
|
||||
bitangentData->AppendBitangent(AZ::Vector3{0.12f, 0.34f, 0.56f});
|
||||
bitangentData->AppendBitangent(AZ::Vector3{0.77f, 0.88f, 0.99f});
|
||||
bitangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::FromSourceScene);
|
||||
bitangentData->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::FromSourceScene);
|
||||
bitangentData->SetBitangentSetIndex(1);
|
||||
return true;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace AZ
|
||||
tangentData->AppendTangent(AZ::Vector4{0.12f, 0.34f, 0.56f, 0.78f});
|
||||
tangentData->AppendTangent(AZ::Vector4{0.18f, 0.28f, 0.19f, 0.29f});
|
||||
tangentData->AppendTangent(AZ::Vector4{0.21f, 0.43f, 0.65f, 0.87f});
|
||||
tangentData->SetTangentSpace(AZ::SceneAPI::DataTypes::TangentSpace::MikkT);
|
||||
tangentData->SetGenerationMethod(AZ::SceneAPI::DataTypes::TangentGenerationMethod::MikkT);
|
||||
tangentData->SetTangentSetIndex(2);
|
||||
return true;
|
||||
}
|
||||
@@ -318,7 +318,7 @@ namespace AZ
|
||||
ExpectExecute("TestExpectFloatEquals(bitangentData.y, 0.88)");
|
||||
ExpectExecute("TestExpectFloatEquals(bitangentData.z, 0.99)");
|
||||
ExpectExecute("TestExpectIntegerEquals(meshVertexBitangentData:GetBitangentSetIndex(), 1)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetTangentSpace(), MeshVertexBitangentData.FromSourceScene)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexBitangentData:GetGenerationMethod(), MeshVertexBitangentData.FromSourceScene)");
|
||||
}
|
||||
|
||||
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_MeshVertexTangentData_AccessWorks)
|
||||
@@ -337,7 +337,7 @@ namespace AZ
|
||||
ExpectExecute("TestExpectFloatEquals(tangentData.z, 0.19)");
|
||||
ExpectExecute("TestExpectFloatEquals(tangentData.w, 0.29)");
|
||||
ExpectExecute("TestExpectIntegerEquals(meshVertexTangentData:GetTangentSetIndex(), 2)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexTangentData:GetTangentSpace(), MeshVertexTangentData.EMotionFX)");
|
||||
ExpectExecute("TestExpectTrue(meshVertexTangentData:GetGenerationMethod(), MeshVertexTangentData.EMotionFX)");
|
||||
}
|
||||
|
||||
TEST_F(GrapDatahBehaviorScriptTest, SceneGraph_AnimationData_AccessWorks)
|
||||
|
||||
@@ -10,7 +10,9 @@ ly_get_list_relative_pal_filename(pal_source_dir ${CMAKE_CURRENT_LIST_DIR}/Platf
|
||||
|
||||
include(${pal_source_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
|
||||
if(${LY_TEST_IMPACT_ACTIVE} AND PAL_TRAIT_TEST_IMPACT_FRAMEWORK_SUPPORTED)
|
||||
add_subdirectory(Runtime)
|
||||
add_subdirectory(Frontend)
|
||||
if(PAL_TRAIT_TEST_IMPACT_FRAMEWORK_SUPPORTED)
|
||||
if(LY_TEST_IMPACT_INSTRUMENTATION_BIN)
|
||||
add_subdirectory(Runtime)
|
||||
add_subdirectory(Frontend)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user