Uzamsal sorgular
Uzamsal sorgular, uzak işleme hizmetine bir alanda hangi nesnelerin bulunduğunu sorabileceğiniz işlemlerdir. Uzamsal sorgular, kullanıcının hangi nesneye işaret ettiği gibi etkileşimleri uygulamak için sıklıkla kullanılır.
Tüm uzamsal sorgular sunucuda değerlendirilir. Buna göre, sorgular zaman uyumsuz işlemlerdir ve sonuçlar ağ gecikmenize bağlı bir gecikmeyle gelir.
Ray casts
Işın ataması, çalışma zamanının belirli bir konumdan başlayıp belirli bir yöne işaret eden bir ışınla kesişen nesneleri denetlediği uzamsal bir sorgudur. İyileştirme olarak, çok uzak olan nesneleri aramamak için maksimum ışın uzaklığı da verilir. Her çerçevenin sunucu tarafında yüzlerce ışın ataması yapılması işlem açısından uygun olsa da, her sorgu ağ trafiği de oluşturur, bu nedenle çerçeve başına sorgu sayısı mümkün olduğunca düşük tutulmalıdır.
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
}
}
});
}
Üç isabet toplama modu vardır:
Closest
: Bu modda yalnızca en yakın isabet bildirilir.Any
: Tek bilmek istediğiniz bir ışın herhangi bir şeye çarpar mı , ancak tam olarak neyin isabet edildiği önemli değilse bu modu tercih edin. Bu sorguyu değerlendirmek çok daha ucuz olabilir, ancak yalnızca birkaç uygulaması da vardır.All
: Bu modda, ışın boyunca yapılan tüm isabetler, mesafeye göre sıralanmış olarak raporlanır. İlk vuruştan daha fazlasına ihtiyacınız yoksa bu modu kullanmayın. Seçeneğiyle bildirilen isabet sayısını sınırlayınMaxHits
.
Nesneleri işın atamaları için seçmeli olarak dikkate alınmadan dışlamak için HierarchicalStateOverrideComponent bileşeni kullanılabilir.
İsabet sonucu
Bir ışın atama sorgusunun sonucu, isabet dizisidir. Hiçbir nesneye isabet verilmediyse dizi boş olur.
İsabet aşağıdaki özelliklere sahiptir:
HitEntity
: Hangi varlığa isabet edildi.SubPartId
: MeshComponent'te hangi alt bileşene isabet edildi? Bu noktada içine dizinMeshComponent.UsedMaterials
oluşturmak ve malzemeyi aramak için kullanılabilir.HitPosition
: Ray'in nesnenin kesiştiği dünya uzay konumu.HitNormal
: Dünya uzayı kesişim konumunda ağın normal yüzeyidir.DistanceToHit
: Işın başlangıç konumundan vuruşa olan uzaklık.HitType
: Ray tarafından ne isabet edilir:TriangleFrontFace
,TriangleBackFace
veyaPoint
. Varsayılan olarak ARR, kullanıcının gördüğü üçgenlerin ön tarafa dönük olması gerekmeyecek şekilde çift taraflı olarak işlenir. Kodunuzda veTriangleBackFace
arasındaTriangleFrontFace
ayrım yapmak istiyorsanız, önce modellerinizin doğru yüz tarifleriyle yazıldığından emin olun.
Uzamsal sorgular
Uzamsal sorgu , çalışma zamanının hangi MeshComponents'in kullanıcı tanımlı bir birimle kesiştiği denetlemesini sağlar. Tek tek denetim, tek tek üçgen temelinde değil, sahnedeki her bir mesh parçasının sınırları temelinde yapıldığından bu denetim gerçekleştirilir. İyileştirme olarak en fazla isabetli ağ bileşeni sayısı sağlanabilir.
Böyle bir sorgu istemci tarafında el ile çalıştırılabilirken, büyük sahneler için sunucunun bunu hesaplaması daha hızlı bir şekilde sıralanabilir.
Aşağıdaki örnek kod, eksene hizalanmış sınırlayıcı kutuya (AABB) karşı sorguların nasıl yapılacağını gösterir. Sorgunun varyantları, yönlendirmeli sınırlayıcı kutu birimlerine (SpatialQueryObbAsync
) ve küre birimlerine (SpatialQuerySphereAsync
) de olanak sağlar.
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 belgeleri
- C# İşleme Bağlan ion. RayCastQueryAsync()
- C# İşleme Bağlan ion. SpatialQueryAabbAsync()
- C# İşleme Bağlan ion. SpatialQuerySphereAsync()
- C# İşleme Bağlan ion. SpatialQueryObbAsync()
- C++ Rendering Bağlan ion::RayCastQueryAsync()
- C++ Rendering Bağlan ion::SpatialQueryAabbAsync()
- C++ Rendering Bağlan ion::SpatialQuerySphereAsync()
- C++ Rendering Bağlan ion::SpatialQueryObbAsync()