567156b85a
Currently, the first time a raycast is attempted for a model, the raycast will fail and the model's kdtree will asynchronously get built. This breaks the vegetation system, which expects the queries to always work. This adds in a brute-force fallback for use while the kdtree is building. However, other use cases like the Editor mouse cursor selection raycast still should get the current "silent failure" behavior, because otherwise the Editor will lock up for several seconds the first time the mouse moves over an extremely complex model.
44 lines
1.7 KiB
C++
44 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
#include "SurfaceData_precompiled.h"
|
|
#include <SurfaceData/Utility/SurfaceDataUtility.h>
|
|
#include <Atom/RPI.Reflect/Model/ModelAssetCreator.h>
|
|
|
|
namespace SurfaceData
|
|
{
|
|
bool GetMeshRayIntersection(
|
|
const AZ::RPI::ModelAsset& meshAsset, const AZ::Transform& meshTransform,
|
|
const AZ::Transform& meshTransformInverse, const AZ::Vector3& nonUniformScale,
|
|
const AZ::Vector3& rayStart, const AZ::Vector3& rayEnd,
|
|
AZ::Vector3& outPosition, AZ::Vector3& outNormal)
|
|
{
|
|
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
|
|
|
|
const AZ::Vector3 clampedScale = nonUniformScale.GetMax(AZ::Vector3(AZ::MinTransformScale));
|
|
|
|
// Transform everything into model space
|
|
const AZ::Vector3 rayStartLocal = meshTransformInverse.TransformPoint(rayStart) / clampedScale;
|
|
const AZ::Vector3 rayEndLocal = meshTransformInverse.TransformPoint(rayEnd) / clampedScale;
|
|
const AZ::Vector3 rayDirectionLocal = (rayEndLocal - rayStartLocal).GetNormalized();
|
|
float distance = rayEndLocal.GetDistance(rayStartLocal);
|
|
|
|
AZ::Vector3 normalLocal;
|
|
|
|
constexpr bool AllowBruteForce = true;
|
|
if (meshAsset.LocalRayIntersectionAgainstModel(rayStartLocal, rayDirectionLocal, AllowBruteForce, distance, normalLocal))
|
|
{
|
|
// Transform everything back to world space
|
|
outPosition = meshTransform.TransformPoint((rayStartLocal + (rayDirectionLocal * distance)) * clampedScale);
|
|
outNormal = meshTransform.TransformVector(normalLocal * clampedScale);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
}
|