Skip to content

Commit 5dff073

Browse files
Merge pull request #226368 from FlorianBorn71/MentionOtherSpatialQueries
Extend the spatial query functions and remove negative collision mesh…
2 parents 297beeb + 87f480e commit 5dff073

File tree

2 files changed

+23
-29
lines changed

2 files changed

+23
-29
lines changed

articles/remote-rendering/how-tos/conversion/configure-model-conversion.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ The `none` mode has the least runtime overhead and also slightly better loading
147147
148148
### Physics parameters
149149

150-
* `generateCollisionMesh` - If you need support for [spatial queries](../../overview/features/spatial-queries.md) on a model, this option has to be enabled. In the worst case, the creation of a collision mesh can double the conversion time. Models with collision meshes take longer to load and when using a `dynamic` scene graph, they also have a higher runtime performance overhead. For overall optimal performance, you should disable this option on all models on which you don't need spatial queries.
150+
* `generateCollisionMesh` - If you need support for [spatial queries](../../overview/features/spatial-queries.md) on a model, this option has to be enabled. Collision mesh generation does not add any extra conversion time and also does not increase the output file size. Furthermore, the loading time and runtime cost of a model with collision meshes is only insignificantly higher.
151+
Accordingly this flag can be left to default (enabled) unless there are strong reasons to exclude a model from spatial queries.
151152

152153
### Unlit materials
153154

@@ -159,7 +160,7 @@ The `none` mode has the least runtime overhead and also slightly better loading
159160

160161
### Coordinate system overriding
161162

162-
* `axis` - To override coordinate system unit-vectors. Default values are `["+x", "+y", "+z"]`. In theory, the FBX format has a header where those vectors are defined and the conversion uses that information to transform the scene. The glTF format also defines a fixed coordinate system. In practice, some assets either have incorrect information in their header or were saved with a different coordinate system convention. This option allows you to override the coordinate system to compensate. For example: `"axis" : ["+x", "+z", "-y"]` will exchange the Z-axis and the Y-axis and keep coordinate system handedness by inverting the Y-axis direction.
163+
* `axis` - To override coordinate system unit-vectors. Default values are `["+x", "+y", "+z"]`. In theory, the FBX format has a header where those vectors are defined and the conversion uses that information to transform the scene. The glTF format also defines a fixed coordinate system. In practice, some assets either have incorrect information in their header or were saved with a different coordinate system convention. This option allows you to override the coordinate system to compensate. For example: `"axis" : ["+x", "+z", "-y"]` will exchange the Z-axis and the Y-axis and keep coordinate system handed-ness by inverting the Y-axis direction.
163164

164165
### Node meta data
165166

@@ -239,7 +240,7 @@ The memory footprints of the formats are as follows:
239240

240241
Assume you have a photogrammetry model, which has lighting baked into the textures. All that is needed to render the model are :::no-loc text="vertex"::: positions and texture coordinates.
241242

242-
By default the converter has to assume that you may want to use PBR materials on a model at some time, so it will generate `normal`, `tangent`, and `binormal` data for you. Consequently, the per vertex memory usage is `position` (12 bytes) + `texcoord0` (8 bytes) + `normal` (4 bytes) + `tangent` (4 bytes) + `binormal` (4 byte) = 32 bytes. Larger models of this type can easily have many millions of :::no-loc text="vertices"::: resulting in models that can take up multiple gigabytes of memory. Such large amounts of data will affect performance and you may even run out of memory.
243+
By default the converter has to assume that you may want to use PBR materials on a model at some time, so it will generate `normal`, `tangent`, and `binormal` data for you. So, the per vertex memory usage is `position` (12 bytes) + `texcoord0` (8 bytes) + `normal` (4 bytes) + `tangent` (4 bytes) + `binormal` (4 byte) = 32 bytes. Larger models of this type can easily have many millions of :::no-loc text="vertices"::: resulting in models that can take up multiple gigabytes of memory. Such large amounts of data will affect performance and you may even run out of memory.
243244

244245
Knowing that you never need dynamic lighting on the model, and knowing that all texture coordinates are in `[0; 1]` range, you can set `normal`, `tangent`, and `binormal` to `NONE` and `texcoord0` to half precision (`16_16_FLOAT`), resulting in only 16 bytes per :::no-loc text="vertex":::. Cutting the mesh data in half enables you to load larger models and potentially improves performance.
245246

@@ -254,7 +255,7 @@ The properties that do have an effect on point cloud conversion are:
254255
* `axis` - same meaning as for triangular meshes. Default values are `["+x", "+y", "+z"]`, however most point cloud data will be rotated compared to renderer's own coordinate system. To compensate, in most cases `["+x", "+z", "-y"]` fixes the rotation.
255256
* `gammaToLinearVertex` - similar to triangular meshes, this flag indicates whether point colors should be converted from gamma space to linear space. Default value for point cloud formats (E57, PLY, LAS, LAZ and XYZ) is true.
256257

257-
* `generateCollisionMesh` - similar to triangular meshes, this flag needs to be enabled to support [spatial queries](../../overview/features/spatial-queries.md). But unlike for triangular meshes, this flag doesn't incurs longer conversion times, larger output file sizes, or longer runtime loading times. So disabling this flag can't be considered an optimization.
258+
* `generateCollisionMesh` - similar to triangular meshes, this flag needs to be enabled to support [spatial queries](../../overview/features/spatial-queries.md).
258259

259260
## Memory optimizations
260261

@@ -314,8 +315,6 @@ There are certain classes of use cases that qualify for specific optimizations.
314315

315316
* These types of scenes tend to be static, meaning they don't need movable parts. Accordingly, the `sceneGraphMode` can be set to `static` or even `none`, which improves runtime performance. With `static` mode, the scene's root node can still be moved, rotated, and scaled, for example to dynamically switch between 1:1 scale (for first person view) and a table top view.
316317

317-
* When you need to move parts around, that typically also means that you need support for raycasts or other [spatial queries](../../overview/features/spatial-queries.md), so that you can pick those parts in the first place. On the other hand, if you don't intend to move something around, chances are high that you also don't need it to participate in spatial queries and therefore can turn off the `generateCollisionMesh` flag. This switch has significant impact on conversion times, loading times, and also runtime per-frame update costs.
318-
319318
* If the application doesn't use [cut planes](../../overview/features/cut-planes.md), the `opaqueMaterialDefaultSidedness` flag should be turned off. The performance gain is typically 20%-30%. Cut planes can still be used, but there won't be back-faces when looking into the inner parts of objects, which looks counter-intuitive. For more information, see [:::no-loc text="single sided"::: rendering](../../overview/features/single-sided-rendering.md).
320319

321320
### Use case: Photogrammetry models

articles/remote-rendering/overview/features/spatial-queries.md

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,13 @@ ms.custom: devx-track-csharp
1212

1313
Spatial queries are operations with which you can ask the remote rendering service which objects are located in an area. Spatial queries are frequently used to implement interactions, such as figuring out which object a user is pointing at.
1414

15-
All spatial queries are evaluated on the server. Accordingly, they're asynchronous operations and results will arrive with a delay that depends on your network latency. Since every spatial query generates network traffic, be careful not to do too many at once.
16-
17-
## Collision meshes
18-
19-
For triangular meshes, spatial queries are powered by the [Havok Physics](https://www.havok.com/products/havok-physics) engine and require a dedicated collision mesh to be present. By default, [model conversion](../../how-tos/conversion/model-conversion.md) generates collision meshes. If you don't require spatial queries on a complex model, consider disabling collision mesh generation in the [conversion options](../../how-tos/conversion/configure-model-conversion.md), as it has an impact in multiple ways:
20-
21-
* [Model conversion](../../how-tos/conversion/model-conversion.md) will take considerably longer.
22-
* Converted model file sizes are noticeably larger, impacting download speed.
23-
* Runtime loading times are longer.
24-
* Runtime CPU memory consumption is higher.
25-
* There's a slight runtime performance overhead for every model instance.
26-
27-
For point clouds, none of these drawbacks apply.
15+
All spatial queries are evaluated on the server. Accordingly, the queries are asynchronous operations and results will arrive with a delay that depends on your network latency.
2816

2917
## Ray casts
3018

3119
A *ray cast* is a spatial query where the runtime checks which objects are intersected by a ray, starting at a given position and pointing into a certain direction. As an optimization, a maximum ray distance is also given, to not search for objects that are too far away.
20+
Although doing hundreds of ray casts each frame is computationally feasible on the server side, each query also generates network traffic, so the number of queries per frame should be kept as low as possible.
21+
3222

3323
```cs
3424
async void CastRay(RenderingSession session)
@@ -84,7 +74,6 @@ void CastRay(ApiHandle<RenderingSession> session)
8474
}
8575
```
8676
87-
8877
There are three hit collection modes:
8978
9079
* **`Closest`:** In this mode, only the closest hit will be reported.
@@ -110,22 +99,24 @@ A Hit has the following properties:
11099
* **`HitPosition`:** The world space position where the ray intersected the object.
111100
* **`HitNormal`:** The world space surface normal of the mesh at the position of the intersection.
112101
* **`DistanceToHit`:** The distance from the ray starting position to the hit.
113-
* **`HitType`:** What was hit by the ray: `TriangleFrontFace`, `TriangleBackFace` or `Point`. By default, [ARR renders double sided](single-sided-rendering.md#prerequisites) so the triangles the user sees are not necessarily front facing. If you want to differentiate between `TriangleFrontFace` and `TriangleBackFace` in your code, make sure your models are authored with correct face directions first.
102+
* **`HitType`:** What was hit by the ray: `TriangleFrontFace`, `TriangleBackFace` or `Point`. By default, [ARR renders double sided](single-sided-rendering.md#prerequisites) so the triangles the user sees aren't necessarily front facing. If you want to differentiate between `TriangleFrontFace` and `TriangleBackFace` in your code, make sure your models are authored with correct face directions first.
114103
115104
## Spatial queries
116105
117-
A *spatial query* allows for the runtime to check which [MeshComponent](../../concepts/meshes.md#meshcomponent) are intersected by a world-space axis-aligned bounding box (AABB). This check is very performant as the individual check is performed based on each mesh part's bounds in the scene, not on an individual triangle basis. As an optimization, a maximum number of hit mesh components can be provided.\
118-
While such a query can be run manually on the client side, for large scenes it will be much faster for the server to compute this.
106+
A *spatial query* allows for the runtime to check which [MeshComponents](../../concepts/meshes.md#meshcomponent) intersect with a user defined volume. This check is performant as the individual check is performed based on each mesh part's bounds in the scene, not on an individual triangle basis. As an optimization, a maximum number of hit mesh components can be provided.\
107+
While such a query can be run manually on the client side, for large scenes it can be orders of magnitude faster for the server to compute this.
108+
109+
The following example code shows how to do queries against an axis aligned bounding box (AABB). Variants of the query also allow for oriented bounding box volumes (`SpatialQueryObbAsync`) and sphere volumes (`SpatialQuerySphereAsync`).
119110
120111
```cs
121112
async void QueryAABB(RenderingSession session)
122113
{
123114
// Query all mesh components in a 2x2x2m cube.
124-
SpatialQuery query = new SpatialQuery();
115+
SpatialQueryAabb query = new SpatialQueryAabb();
125116
query.Bounds = new Microsoft.Azure.RemoteRendering.Bounds(new Double3(-1, -1, -1), new Double3(1, 1, 1));
126117
query.MaxResults = 100;
127118
128-
SpatialQueryResult result = await session.Connection.SpatialQueryAsync(query);
119+
SpatialQueryResult result = await session.Connection.SpatialQueryAabbAsync(query);
129120
foreach (MeshComponent meshComponent in result.Overlaps)
130121
{
131122
Entity owner = meshComponent.Owner;
@@ -138,12 +129,12 @@ async void QueryAABB(RenderingSession session)
138129
void QueryAABB(ApiHandle<RenderingSession> session)
139130
{
140131
// Query all mesh components in a 2x2x2m cube.
141-
SpatialQuery query;
132+
SpatialQueryAabb query;
142133
query.Bounds.Min = {-1, -1, -1};
143134
query.Bounds.Max = {1, 1, 1};
144135
query.MaxResults = 100;
145136

146-
session->Connection()->SpatialQueryAsync(query, [](Status status, ApiHandle<SpatialQueryResult> result)
137+
session->Connection()->SpatialQueryAabbAsync(query, [](Status status, ApiHandle<SpatialQueryResult> result)
147138
{
148139
if (status == Status::OK)
149140
{
@@ -162,8 +153,12 @@ void QueryAABB(ApiHandle<RenderingSession> session)
162153
163154
## API documentation
164155
165-
* [C# RenderingConnection.RayCastQueryAsync()](/dotnet/api/microsoft.azure.remoterendering.renderingconnection.raycastqueryasync)
166-
* [C++ RenderingConnection::RayCastQueryAsync()](/cpp/api/remote-rendering/renderingconnection#raycastqueryasync)
156+
* [C# RenderingConnection.RayCastQueryAabbAsync()](/dotnet/api/microsoft.azure.remoterendering.renderingconnection.raycastqueryaabbasync)
157+
* [C# RenderingConnection.RayCastQueryObbAsync()](/dotnet/api/microsoft.azure.remoterendering.renderingconnection.raycastqueryobbasync)
158+
* [C# RenderingConnection.RayCastQuerySphereAsync()](/dotnet/api/microsoft.azure.remoterendering.renderingconnection.raycastquerysphereasync)
159+
* [C++ RenderingConnection::RayCastQueryAabbAsync()](/cpp/api/remote-rendering/renderingconnection#raycastqueryaabbasync)
160+
* [C++ RenderingConnection::RayCastQueryObbAsync()](/cpp/api/remote-rendering/renderingconnection#raycastqueryobbasync)
161+
* [C++ RenderingConnection::RayCastQuerySphereAsync()](/cpp/api/remote-rendering/renderingconnection#raycastquerysphereasync)
167162
168163
## Next steps
169164

0 commit comments

Comments
 (0)