Support mesh intersection for camera orbit (#982)
* wip support for mesh intersection with intersector bus * WIP camera mesh intersection orbit logic * remove unneeded template argument * add bus connect/disconnect * fix intersection logic * small updates, additional comments, some tidy-up * update formatting options slightly * use aznumeric_cast * temp workaround for negative distances with RayIntersection
This commit is contained in:
committed by
GitHub
parent
c9f7cd03bb
commit
36ceff84c9
+56
-17
@@ -177,28 +177,33 @@ namespace AZ
|
||||
FixUpModelAsset(m_configuration.m_modelAsset);
|
||||
}
|
||||
|
||||
void MeshComponentController::Activate(AZ::EntityId entityId)
|
||||
void MeshComponentController::Activate(const AZ::EntityComponentIdPair& entityComponentIdPair)
|
||||
{
|
||||
FixUpModelAsset(m_configuration.m_modelAsset);
|
||||
|
||||
m_entityId = entityId;
|
||||
const AZ::EntityId entityId = entityComponentIdPair.GetEntityId();
|
||||
m_entityComponentIdPair = entityComponentIdPair;
|
||||
|
||||
m_transformInterface = TransformBus::FindFirstHandler(m_entityId);
|
||||
m_transformInterface = TransformBus::FindFirstHandler(entityId);
|
||||
AZ_Warning("MeshComponentController", m_transformInterface, "Unable to attach to a TransformBus handler. This mesh will always be rendered at the origin.");
|
||||
|
||||
m_meshFeatureProcessor = RPI::Scene::GetFeatureProcessorForEntity<MeshFeatureProcessorInterface>(m_entityId);
|
||||
m_meshFeatureProcessor = RPI::Scene::GetFeatureProcessorForEntity<MeshFeatureProcessorInterface>(entityId);
|
||||
AZ_Error("MeshComponentController", m_meshFeatureProcessor, "Unable to find a MeshFeatureProcessorInterface on the entityId.");
|
||||
|
||||
m_cachedNonUniformScale = AZ::Vector3::CreateOne();
|
||||
AZ::NonUniformScaleRequestBus::EventResult(m_cachedNonUniformScale, m_entityId, &AZ::NonUniformScaleRequests::GetScale);
|
||||
AZ::NonUniformScaleRequestBus::Event(m_entityId, &AZ::NonUniformScaleRequests::RegisterScaleChangedEvent,
|
||||
AZ::NonUniformScaleRequestBus::EventResult(m_cachedNonUniformScale, entityId, &AZ::NonUniformScaleRequests::GetScale);
|
||||
AZ::NonUniformScaleRequestBus::Event(entityId, &AZ::NonUniformScaleRequests::RegisterScaleChangedEvent,
|
||||
m_nonUniformScaleChangedHandler);
|
||||
|
||||
MeshComponentRequestBus::Handler::BusConnect(m_entityId);
|
||||
TransformNotificationBus::Handler::BusConnect(m_entityId);
|
||||
MaterialReceiverRequestBus::Handler::BusConnect(m_entityId);
|
||||
MaterialComponentNotificationBus::Handler::BusConnect(m_entityId);
|
||||
AzFramework::BoundsRequestBus::Handler::BusConnect(m_entityId);
|
||||
MeshComponentRequestBus::Handler::BusConnect(entityId);
|
||||
TransformNotificationBus::Handler::BusConnect(entityId);
|
||||
MaterialReceiverRequestBus::Handler::BusConnect(entityId);
|
||||
MaterialComponentNotificationBus::Handler::BusConnect(entityId);
|
||||
AzFramework::BoundsRequestBus::Handler::BusConnect(entityId);
|
||||
AzFramework::EntityContextId contextId;
|
||||
AzFramework::EntityIdContextQueryBus::EventResult(
|
||||
contextId, entityId, &AzFramework::EntityIdContextQueries::GetOwningContextId);
|
||||
AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusConnect({entityId, contextId});
|
||||
|
||||
//Buses must be connected before RegisterModel in case requests are made as a result of HandleModelChange
|
||||
RegisterModel();
|
||||
@@ -209,6 +214,7 @@ namespace AZ
|
||||
// Buses must be disconnected after unregistering the model, otherwise they can't deliver the events during the process.
|
||||
UnregisterModel();
|
||||
|
||||
AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusDisconnect();
|
||||
AzFramework::BoundsRequestBus::Handler::BusDisconnect();
|
||||
MeshComponentRequestBus::Handler::BusDisconnect();
|
||||
TransformNotificationBus::Handler::BusDisconnect();
|
||||
@@ -219,7 +225,7 @@ namespace AZ
|
||||
|
||||
m_meshFeatureProcessor = nullptr;
|
||||
m_transformInterface = nullptr;
|
||||
m_entityId = AZ::EntityId(AZ::EntityId::InvalidEntityId);
|
||||
m_entityComponentIdPair = AZ::EntityComponentIdPair(AZ::EntityId(), AZ::InvalidComponentId);
|
||||
m_configuration.m_modelAsset.Release();
|
||||
}
|
||||
|
||||
@@ -293,10 +299,11 @@ namespace AZ
|
||||
Data::Asset<RPI::ModelAsset> modelAsset = m_meshFeatureProcessor->GetModelAsset(m_meshHandle);
|
||||
if (model && modelAsset)
|
||||
{
|
||||
const AZ::EntityId entityId = m_entityComponentIdPair.GetEntityId();
|
||||
m_configuration.m_modelAsset = modelAsset;
|
||||
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelReady, m_configuration.m_modelAsset, model);
|
||||
MaterialReceiverNotificationBus::Event(m_entityId, &MaterialReceiverNotificationBus::Events::OnMaterialAssignmentsChanged);
|
||||
AZ::Interface<AzFramework::IEntityBoundsUnion>::Get()->RefreshEntityLocalBoundsUnion(m_entityId);
|
||||
MeshComponentNotificationBus::Event(entityId, &MeshComponentNotificationBus::Events::OnModelReady, m_configuration.m_modelAsset, model);
|
||||
MaterialReceiverNotificationBus::Event(entityId, &MaterialReceiverNotificationBus::Events::OnMaterialAssignmentsChanged);
|
||||
AZ::Interface<AzFramework::IEntityBoundsUnion>::Get()->RefreshEntityLocalBoundsUnion(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,8 +311,10 @@ namespace AZ
|
||||
{
|
||||
if (m_meshFeatureProcessor && m_configuration.m_modelAsset.GetId().IsValid())
|
||||
{
|
||||
const AZ::EntityId entityId = m_entityComponentIdPair.GetEntityId();
|
||||
|
||||
MaterialAssignmentMap materials;
|
||||
MaterialComponentRequestBus::EventResult(materials, m_entityId, &MaterialComponentRequests::GetMaterialOverrides);
|
||||
MaterialComponentRequestBus::EventResult(materials, entityId, &MaterialComponentRequests::GetMaterialOverrides);
|
||||
|
||||
m_meshFeatureProcessor->ReleaseMesh(m_meshHandle);
|
||||
m_meshHandle = m_meshFeatureProcessor->AcquireMesh(m_configuration.m_modelAsset, materials,
|
||||
@@ -330,7 +339,8 @@ namespace AZ
|
||||
{
|
||||
if (m_meshFeatureProcessor && m_meshHandle.IsValid())
|
||||
{
|
||||
MeshComponentNotificationBus::Event(m_entityId, &MeshComponentNotificationBus::Events::OnModelPreDestroy);
|
||||
MeshComponentNotificationBus::Event(
|
||||
m_entityComponentIdPair.GetEntityId(), &MeshComponentNotificationBus::Events::OnModelPreDestroy);
|
||||
m_meshFeatureProcessor->ReleaseMesh(m_meshHandle);
|
||||
}
|
||||
}
|
||||
@@ -462,5 +472,34 @@ namespace AZ
|
||||
return Aabb::CreateNull();
|
||||
}
|
||||
}
|
||||
|
||||
AzFramework::RenderGeometry::RayResult MeshComponentController::RenderGeometryIntersect(
|
||||
const AzFramework::RenderGeometry::RayRequest& ray)
|
||||
{
|
||||
AzFramework::RenderGeometry::RayResult result;
|
||||
if (const Data::Instance<RPI::Model> model = GetModel())
|
||||
{
|
||||
float t;
|
||||
AZ::Vector3 normal;
|
||||
if (model->RayIntersection(
|
||||
m_transformInterface->GetWorldTM(), m_cachedNonUniformScale, ray.m_startWorldPosition,
|
||||
ray.m_endWorldPosition - ray.m_startWorldPosition, t, normal))
|
||||
{
|
||||
// note: this is a temporary workaround to handle cases where model->RayIntersection
|
||||
// returns negative distances, follow-up ATOM-15673
|
||||
const auto absT = AZStd::abs(t);
|
||||
|
||||
// fill in ray result structure after successful intersection
|
||||
const auto intersectionLine = (ray.m_endWorldPosition - ray.m_startWorldPosition);
|
||||
result.m_uv = AZ::Vector2::CreateZero();
|
||||
result.m_worldPosition = ray.m_startWorldPosition + intersectionLine * absT;
|
||||
result.m_worldNormal = normal;
|
||||
result.m_distance = intersectionLine.GetLength() * absT;
|
||||
result.m_entityAndComponent = m_entityComponentIdPair;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
|
||||
Reference in New Issue
Block a user