空間查詢
空間查詢是您可以向遠端轉譯服務詢問哪些物件位於區域中的作業。 空間查詢經常用來實作互動,例如找出使用者指向的物件。
所有空間查詢都會在伺服器上進行評估。 因此,查詢是非同步作業,結果會隨著您的網路延遲而延遲而抵達。
光線轉換
光線轉換 是空間查詢,執行時間會檢查哪些物件與光線交集,從指定的位置開始,並指向特定方向。 作為優化,也會提供最大光線距離,以不搜尋太遠的物件。 雖然在伺服器端執行數百個光線轉換是可行的,但每個查詢也會產生網路流量,因此每個畫面的查詢數目應盡可能低。
async void CastRay(RenderingSession session)
{
// trace a line from the origin into the +z direction, over 10 units of distance.
RayCast rayCast = new RayCast(new Double3(0, 0, 0), new Double3(0, 0, 1), 10);
// only return the closest hit
rayCast.HitCollection = HitCollectionPolicy.ClosestHit;
RayCastQueryResult result = await session.Connection.RayCastQueryAsync(rayCast);
RayCastHit[] hits = result.Hits;
if (hits.Length > 0)
{
var hitObject = hits[0].HitObject;
var hitPosition = hits[0].HitPosition;
var hitNormal = hits[0].HitNormal;
var hitType = hits[0].HitType;
// do something with the hit information
}
}
void CastRay(ApiHandle<RenderingSession> session)
{
// trace a line from the origin into the +z direction, over 10 units of distance.
RayCast rayCast;
rayCast.StartPos = {0, 0, 0};
rayCast.EndPos = {0, 0, 10};
// only return the closest hit
rayCast.HitCollection = HitCollectionPolicy::ClosestHit;
session->Connection()->RayCastQueryAsync(rayCast, [](Status status, ApiHandle<RayCastQueryResult> result)
{
if (status == Status::OK)
{
std::vector<RayCastHit> hits;
result->GetHits(hits);
if (hits.size() > 0)
{
auto hitObject = hits[0].HitObject;
auto hitPosition = hits[0].HitPosition;
auto hitNormal = hits[0].HitNormal;
auto hitType = hits[0].HitType;
// do something with the hit information
}
}
});
}
點擊收集模式有三種:
Closest
: 在此模式中,只會報告最接近的點擊數。Any
: 當您想要知道 光線是否會 擊中任何專案時,偏好此模式,但不在乎所擊中的內容。 此查詢可大幅降低評估成本,但只有少數應用程式。All
: 在此模式中,會報告沿著光線的所有點擊,依距離排序。 除非您真的需要超過第一次點擊,否則請勿使用此模式。 使用MaxHits
選項來限制回報點擊數目。
若要選擇性地排除物件不考慮光線轉換, 可以使用 HierarchicalStateOverrideComponent 元件。
點擊結果
光線轉換查詢的結果是點擊陣列。 如果未叫用任何物件,則陣列是空的。
Hit 具有下列屬性:
HitEntity
: 已叫用哪一個 實體 。SubPartId
: 在 MeshComponent 中叫用哪 一個 submesh 。 可用來編制索引,MeshComponent.UsedMaterials
並在該時間點查閱 材質 。HitPosition
: 光線與物件交集所在的世界空間位置。HitNormal
: 世界空間表面在交集位置的網格正常。DistanceToHit
: 從光線開始位置到點擊的距離。HitType
: 光線擊中的內容:TriangleFrontFace
、TriangleBackFace
或Point
。 根據預設, ARR 會呈現雙面, 因此使用者看到的三角形不一定是正面。 如果您想要區分TriangleFrontFace
程式碼中的 和TriangleBackFace
,請確定您的模型會先以正確的臉部指示撰寫。
空間查詢
空間查詢 可讓執行時間檢查 哪些 MeshComponent 與使用者定義的磁片區相交。 由於個別檢查是根據場景中每個網格部分的界限執行,而不是個別的三角形,因此此檢查的執行效能是有效的。 作為優化,可以提供命中網格元件的數目上限。
雖然這類查詢可以在用戶端手動執行,但對於大型場景,伺服器可以更快速地計算此查詢。
下列範例程式碼示範如何針對座標軸對齊周框方塊執行查詢(AABB)。 查詢的變體也允許導向周框方塊磁片區 ( SpatialQueryObbAsync
) 和球體磁片區 ( SpatialQuerySphereAsync
)。
async void QueryAABB(RenderingSession session)
{
// Query all mesh components in a 2x2x2m cube.
SpatialQueryAabb query = new SpatialQueryAabb();
query.Bounds = new Microsoft.Azure.RemoteRendering.Bounds(new Double3(-1, -1, -1), new Double3(1, 1, 1));
query.MaxResults = 100;
SpatialQueryResult result = await session.Connection.SpatialQueryAabbAsync(query);
foreach (MeshComponent meshComponent in result.Overlaps)
{
Entity owner = meshComponent.Owner;
// do something with the hit MeshComponent / Entity
}
}
void QueryAABB(ApiHandle<RenderingSession> session)
{
// Query all mesh components in a 2x2x2m cube.
SpatialQueryAabb query;
query.Bounds.Min = {-1, -1, -1};
query.Bounds.Max = {1, 1, 1};
query.MaxResults = 100;
session->Connection()->SpatialQueryAabbAsync(query, [](Status status, ApiHandle<SpatialQueryResult> result)
{
if (status == Status::OK)
{
std::vector<ApiHandle<MeshComponent>> overlaps;
result->GetOverlaps(overlaps);
for (ApiHandle<MeshComponent> meshComponent : overlaps)
{
ApiHandle<Entity> owner = meshComponent->GetOwner();
// do something with the hit MeshComponent / Entity
}
}
});
}
API 文件
- C# 轉譯連線。RayCastQueryAsync()
- C# 轉譯連線。SpatialQueryAabbAsync()
- C# 轉譯連線。SpatialQuerySphereAsync()
- C# 轉譯連線。SpatialQueryObbAsync()
- C++ 轉譯連線ion::RayCastQueryAsync()
- C++ 轉譯連線ion::SpatialQueryAabbAsync()
- C++ 轉譯連線ion::SpatialQuerySphereAsync()
- C++ 轉譯連線ion::SpatialQueryObbAsync()