123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <XRRPIExampleComponent.h>
- #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
- #include <Atom/RPI.Public/Scene.h>
- #include <Atom/RPI.Public/RPISystem.h>
- #include <Atom/RPI.Public/RPISystemInterface.h>
- #include <Atom/RPI.Public/Pass/PassFilter.h>
- #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
- #include <Atom/RPI.Reflect/Model/ModelAsset.h>
- #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
- #include <Automation/ScriptableImGui.h>
- #include <Automation/ScriptRunnerBus.h>
- #include <Utils/Utils.h>
- #include <SSRExampleComponent_Traits_Platform.h>
- namespace AtomSampleViewer
- {
- static const float ControllerOffsetScale = 2.0f;
- static const float ViewOrientationScale = 10.0f;
- static const float PixelToDegree = 1.0 / 360.0f;
- void XRRPIExampleComponent::Reflect(AZ::ReflectContext* context)
- {
- if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
- {
- serializeContext->Class<XRRPIExampleComponent, AZ::Component>()
- ->Version(0);
- }
- }
- void XRRPIExampleComponent::Activate()
- {
- if (m_xrSystem = AZ::RPI::RPISystemInterface::Get()->GetXRSystem();
- m_xrSystem == nullptr)
- {
- return;
- }
- AZ::TickBus::Handler::BusConnect();
- // setup the camera
- Camera::CameraRequestBus::EventResult(m_originalFarClipDistance, GetCameraEntityId(), &Camera::CameraRequestBus::Events::GetFarClipDistance);
- Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetFarClipDistance, 180.f);
- m_numXrViews = m_xrSystem->GetNumViews();
- // create scene
- CreateModels();
- CreateGroundPlane();
- InitLightingPresets(true);
- }
- void XRRPIExampleComponent::Deactivate()
- {
- if (!m_xrSystem)
- {
- return;
- }
- ShutdownLightingPresets();
- GetMeshFeatureProcessor()->ReleaseMesh(m_statueMeshHandle);
- GetMeshFeatureProcessor()->ReleaseMesh(m_boxMeshHandle);
- GetMeshFeatureProcessor()->ReleaseMesh(m_shaderBallMeshHandle);
- GetMeshFeatureProcessor()->ReleaseMesh(m_groundMeshHandle);
- GetMeshFeatureProcessor()->ReleaseMesh(m_leftControllerMeshHandle);
- GetMeshFeatureProcessor()->ReleaseMesh(m_rightControllerMeshHandle);
- Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetFarClipDistance, m_originalFarClipDistance);
- AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Disable);
- AZ::TickBus::Handler::BusDisconnect();
- }
- void XRRPIExampleComponent::CreateModels()
- {
- GetMeshFeatureProcessor();
- // statue
- {
- AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("objects/hermanubis/hermanubis_stone.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>(ATOMSAMPLEVIEWER_TRAIT_SSR_SAMPLE_HERMANUBIS_MODEL_NAME, AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Transform transform = AZ::Transform::CreateIdentity();
- transform.SetTranslation(0.0f, 0.0f, -0.05f);
- m_statueMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset)));
- GetMeshFeatureProcessor()->SetTransform(m_statueMeshHandle, transform);
- }
- // cube
- {
- AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("materials/ssrexample/cube.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/cube.fbx.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Transform transform = AZ::Transform::CreateIdentity();
- transform.SetTranslation(-4.5f, 0.0f, 0.49f);
- m_boxMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset)));
- GetMeshFeatureProcessor()->SetTransform(m_boxMeshHandle, transform);
- }
- // shader ball
- {
- AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("Materials/Presets/PBR/default_grid.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/ShaderBall_simple.fbx.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Transform transform = AZ::Transform::CreateIdentity();
- transform *= AZ::Transform::CreateRotationZ(AZ::Constants::Pi);
- transform.SetTranslation(4.5f, 0.0f, 0.89f);
- m_shaderBallMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset)));
- GetMeshFeatureProcessor()->SetTransform(m_shaderBallMeshHandle, transform);
- }
- // controller meshes
- {
- AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("Materials/XR/XR_Hand_Controller_ControlerMAT.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/left_hand_controller.fbx.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
- AZ::Transform transform = AZ::Transform::CreateIdentity();
- m_leftControllerMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset)));
- m_rightControllerMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset)));
- GetMeshFeatureProcessor()->SetTransform(m_leftControllerMeshHandle, transform);
- GetMeshFeatureProcessor()->SetTransform(m_rightControllerMeshHandle, transform);
- }
- }
- void XRRPIExampleComponent::CreateGroundPlane()
- {
- AZ::Render::MeshFeatureProcessorInterface* meshFeatureProcessor = GetMeshFeatureProcessor();
- if (m_groundMeshHandle.IsValid())
- {
- meshFeatureProcessor->ReleaseMesh(m_groundMeshHandle);
- }
- // load material
- AZStd::string materialName;
- switch (m_groundPlaneMaterial)
- {
- case 0:
- materialName = "materials/ssrexample/groundplanechrome.azmaterial";
- break;
- case 1:
- materialName = "materials/ssrexample/groundplanealuminum.azmaterial";
- break;
- case 2:
- materialName = "materials/presets/pbr/default_grid.azmaterial";
- break;
- default:
- materialName = "materials/ssrexample/groundplanemirror.azmaterial";
- break;
- }
- AZ::Data::AssetId groundMaterialAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(materialName.c_str(), AZ::RPI::AssetUtils::TraceLevel::Error);
- m_groundMaterialAsset.Create(groundMaterialAssetId);
- // load mesh
- AZ::Data::Asset<AZ::RPI::ModelAsset> planeModel = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/plane.fbx.azmodel", AZ::RPI::AssetUtils::TraceLevel::Error);
- m_groundMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(
- AZ::Render::MeshHandleDescriptor(planeModel, AZ::RPI::Material::FindOrCreate(m_groundMaterialAsset)));
- AZ::Transform transform = AZ::Transform::CreateIdentity();
- const AZ::Vector3 nonUniformScale(15.0f, 15.0f, 1.0f);
- GetMeshFeatureProcessor()->SetTransform(m_groundMeshHandle, transform, nonUniformScale);
- }
- void XRRPIExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
- {
- if (m_resetCamera)
- {
- AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Reset);
- AZ::TransformBus::Event(GetCameraEntityId(), &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(7.5f, -10.5f, 3.0f));
- AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable, azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetHeading, AZ::DegToRad(22.5f));
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetPitch, AZ::DegToRad(-10.0f));
- m_resetCamera = false;
- }
- if (m_xrSystem && m_xrSystem->ShouldRender())
- {
- AZ::RPI::PoseData frontPoseData;
- AZ::RHI::ResultCode resultCode = m_xrSystem->GetViewLocalPose(frontPoseData);
- for (AZ::u32 i = 0; i < m_numXrViews; i++)
- {
- //Pose data for the controller
- AZ::RPI::PoseData controllerPose;
- resultCode = m_xrSystem->GetControllerPose(i, controllerPose);
- if(resultCode == AZ::RHI::ResultCode::Success && !controllerPose.m_orientation.IsZero())
- {
- AZ::Vector3 camPosition;
- AZ::TransformBus::EventResult(camPosition, GetCameraEntityId(), &AZ::TransformBus::Events::GetWorldTranslation);
- AZ::Vector3 controllerPositionOffset = controllerPose.m_position * ControllerOffsetScale;
- AZ::Vector3 newControllerPos = camPosition + AZ::Vector3(controllerPositionOffset.GetX(), -controllerPositionOffset.GetZ(), controllerPositionOffset.GetY());
- // Go from y up to z up as a right handed coord system
- AZ::Quaternion controllerOrientation = controllerPose.m_orientation;
- controllerOrientation.SetX(controllerPose.m_orientation.GetX());
- controllerOrientation.SetY(-controllerPose.m_orientation.GetZ());
- controllerOrientation.SetZ(controllerPose.m_orientation.GetY());
- //Apply a Rotation of 90 deg around X axis in order to orient the model to face away from you as default pose
- AZ::Transform controllerTransform = AZ::Transform::CreateFromQuaternionAndTranslation(
- controllerOrientation * AZ::Quaternion::CreateRotationX(-AZ::Constants::Pi / 2), AZ::Vector3(newControllerPos.GetX(), newControllerPos.GetY(),newControllerPos.GetZ()));
- AZ::Render::MeshFeatureProcessorInterface::MeshHandle* controllerMeshhandle = &m_leftControllerMeshHandle;
- if (i == 1)
- {
- controllerMeshhandle = &m_rightControllerMeshHandle;
- }
- GetMeshFeatureProcessor()->SetTransform(*controllerMeshhandle, controllerTransform, AZ::Vector3(m_xrSystem->GetControllerScale(i)));
- }
- }
- //Update Camera movement (left, right forward, back) based on left JoyStick controller
- float m_xJoyStickValue = m_xrSystem->GetXJoyStickState(0);
- float m_yJoyStickValue = m_xrSystem->GetYJoyStickState(0);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateForward, m_yJoyStickValue);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateBack, m_yJoyStickValue);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateLeft, m_xJoyStickValue);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateRight, m_xJoyStickValue);
- //Update Camera movement (Up, Down) based on X,Y button presses on the left controller
- float yButtonState = m_xrSystem->GetYButtonState();
- float xButtonState = m_xrSystem->GetXButtonState();
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateUp, yButtonState);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetCameraStateDown, xButtonState);
- // Switch to updating the view using right joystick controller if the Trigger button on the right controller is pressed
- m_rightTriggerButtonPressed = (m_xrSystem->GetTriggerState(1) > 0.1f);
- if (m_rightTriggerButtonPressed)
- {
- //Update Camera view based on right JoyStick controller
- float m_xRightJoyStickValue = m_xrSystem->GetXJoyStickState(1);
- float m_yRightJoyStickValue = m_xrSystem->GetYJoyStickState(1);
- float heading, pitch = 0.0f;
- AZ::Debug::NoClipControllerRequestBus::EventResult(heading, GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::GetHeading);
- AZ::Debug::NoClipControllerRequestBus::EventResult(pitch, GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::GetPitch);
- heading -= m_xRightJoyStickValue * PixelToDegree * ViewOrientationScale;
- pitch += m_yRightJoyStickValue * PixelToDegree * ViewOrientationScale;
- pitch = AZStd::max(pitch, -AZ::Constants::HalfPi);
- pitch = AZStd::min(pitch, AZ::Constants::HalfPi);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetHeading, heading);
- AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetPitch, pitch);
- }
- else
- {
- //Convert to O3de's coordinate system and update the camera orientation for the correct eye view
- AZ::Quaternion viewLocalPoseOrientation = frontPoseData.m_orientation;
- viewLocalPoseOrientation.SetX(-frontPoseData.m_orientation.GetX());
- viewLocalPoseOrientation.SetY(frontPoseData.m_orientation.GetZ());
- viewLocalPoseOrientation.SetZ(-frontPoseData.m_orientation.GetY());
- for (AZ::u32 i = 0; i < m_numXrViews; i++)
- {
- Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetXRViewQuaternion, viewLocalPoseOrientation, i);
- }
- }
- // Switch to the next lighting preset using the B-button
- if (m_xrSystem->GetBButtonState() > 0.0f)
- {
- if (!m_bButtonPressed)
- {
- m_bButtonPressed = true;
- IterateToNextLightingPreset();
- }
- }
- else
- {
- m_bButtonPressed = false;
- }
- // Switch to the next ground floor using the A-button
- if (m_xrSystem->GetAButtonState() > 0.0f)
- {
- if (!m_aButtonPressed)
- {
- m_aButtonPressed = true;
- m_groundPlaneMaterial = (m_groundPlaneMaterial + 1) % 4;
- CreateGroundPlane();
- }
- }
- else
- {
- m_aButtonPressed = false;
- }
- }
- }
- }
|