Skip to content

Commit 9f43b38

Browse files
committed
Add C++ flavor to all code samples
1 parent bb5bb86 commit 9f43b38

File tree

8 files changed

+182
-20
lines changed

8 files changed

+182
-20
lines changed

articles/remote-rendering/concepts/components.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ lightComponent.Destroy();
3434
lightComponent = null;
3535
```
3636

37+
```cpp
38+
// create a point light component
39+
ApiHandle<AzureSession> session = GetCurrentlyConnectedSession();
40+
41+
ApiHandle<PointLightComponent> lightComponent = session->Actions()->CreateComponent(ObjectType::PointLightComponent, ownerEntity)->as<PointLightComponent>();
42+
43+
// ...
44+
45+
// destroy the component
46+
lightComponent->Destroy();
47+
lightComponent = nullptr;
48+
```
49+
50+
3751
A component is attached to an entity at creation time. It cannot be moved to another entity afterwards. Components are explicitly deleted with `Component.Destroy()` or automatically when the component's owner entity is destroyed.
3852
3953
Only one instance of each component type may be added to an entity at a time.

articles/remote-rendering/concepts/entities.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ CutPlaneComponent cutplane = (CutPlaneComponent)entity.FindComponentOfType(Objec
3636
CutPlaneComponent cutplane = entity.FindComponentOfType<CutPlaneComponent>();
3737
```
3838

39+
```cpp
40+
ApiHandle<CutPlaneComponent> cutplane = entity->FindComponentOfType(ObjectType::CutPlaneComponent)->as<CutPlaneComponent>();
41+
42+
// or alternatively:
43+
ApiHandle<CutPlaneComponent> cutplane = *entity->FindComponentOfType<CutPlaneComponent>();
44+
```
45+
3946
### Querying transforms
4047
4148
Transform queries are synchronous calls on the object. It is important to note that transforms queried through the API are local space transforms, relative to the object's parent. Exceptions are root objects, for which local space and world space are identical.
@@ -49,6 +56,13 @@ Double3 translation = entity.Position;
4956
Quaternion rotation = entity.Rotation;
5057
```
5158

59+
```cpp
60+
// local space transform of the entity
61+
Double3 translation = *entity->Position();
62+
Quaternion rotation = *entity->Rotation();
63+
```
64+
65+
5266
### Querying spatial bounds
5367

5468
Bounds queries are asynchronous calls that operate on a full object hierarchy, using one entity as a root. See the dedicated chapter about [object bounds](object-bounds.md).
@@ -74,6 +88,21 @@ metaDataQuery.Completed += (MetadataQueryAsync query) =>
7488
};
7589
```
7690

91+
```cpp
92+
ApiHandle<MetadataQueryAsync> metaDataQuery = *entity->QueryMetaDataAsync();
93+
metaDataQuery->Completed([](const ApiHandle<MetadataQueryAsync>& query)
94+
{
95+
if (query->IsRanToCompletion())
96+
{
97+
ApiHandle<ObjectMetaData> metaData = *query->Result();
98+
ApiHandle<ObjectMetaDataEntry> entry = *metaData->GetMetadataByName("MyInt64Value");
99+
int64_t intValue = *entry->AsInt64();
100+
101+
// ...
102+
}
103+
});
104+
```
105+
77106
The query will succeed even if the object does not hold any metadata.
78107
79108
## Next steps

articles/remote-rendering/concepts/models.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,28 @@ async void LoadModel(AzureSession session, Entity modelParent, string modelUri)
5353
}
5454
```
5555

56+
```cpp
57+
ApiHandle<LoadModelAsync> LoadModel(ApiHandle<AzureSession> session, ApiHandle<Entity> modelParent, std::string modelUri)
58+
{
59+
LoadModelFromSASParams modelParams;
60+
modelParams.ModelUrl = modelUri;
61+
modelParams.Parent = modelParent;
62+
63+
ApiHandle<LoadModelAsync> loadOp = *session->Actions()->LoadModelFromSASAsync(modelParams);
64+
65+
loadOp->Completed([](const ApiHandle<LoadModelAsync>& async)
66+
{
67+
printf("Loading: finished.");
68+
});
69+
loadOp->ProgressUpdated([](float progress)
70+
{
71+
printf("Loading: %.1f%%", progress*100.f);
72+
});
73+
74+
return loadOp;
75+
}
76+
```
77+
5678
If you want to load a model by directly using its blob storage parameters, use code similar to the following snippet:
5779
5880
```csharp
@@ -72,6 +94,19 @@ async void LoadModel(AzureSession session, Entity modelParent, string storageAcc
7294
}
7395
```
7496

97+
```cpp
98+
ApiHandle<LoadModelAsync> LoadModel(ApiHandle<AzureSession> session, ApiHandle<Entity> modelParent, std::string storageAccount, std::string containerName, std::string assetFilePath)
99+
{
100+
LoadModelParams modelParams;
101+
modelParams.Blob.StorageAccountName = std::move(storageAccount);
102+
modelParams.Blob.BlobContainerName = std::move(containerName);
103+
modelParams.Blob.AssetPath = std::move(assetFilePath);
104+
105+
ApiHandle<LoadModelAsync> loadOp = *session->Actions()->LoadModelAsync(modelParams);
106+
// ... (identical to the SAS URI snippet above)
107+
}
108+
```
109+
75110
Afterwards you can traverse the entity hierarchy and modify the entities and components. Loading the same model multiple times creates multiple instances, each with their own copy of the entity/component structure. Since meshes, materials, and textures are [shared resources](../concepts/lifetime.md), their data will not be loaded again, though. Therefore instantiating a model more than once incurs relatively little memory overhead.
76111
77112
> [!CAUTION]

articles/remote-rendering/how-tos/frontend-apis.md

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,33 @@ The important fields are:
1919

2020
```cs
2121

22-
public class AzureFrontendAccountInfo
23-
{
24-
// Something akin to "<region>.mixedreality.azure.com"
25-
public string AccountDomain;
26-
27-
// Can use one of:
28-
// 1) ID and Key.
29-
// 2) AuthenticationToken.
30-
// 3) AccessToken.
31-
public string AccountId = Guid.Empty.ToString();
32-
public string AccountKey = string.Empty;
33-
public string AuthenticationToken = string.Empty;
34-
public string AccessToken = string.Empty;
35-
}
22+
public class AzureFrontendAccountInfo
23+
{
24+
// Something akin to "<region>.mixedreality.azure.com"
25+
public string AccountDomain;
26+
27+
// Can use one of:
28+
// 1) ID and Key.
29+
// 2) AuthenticationToken.
30+
// 3) AccessToken.
31+
public string AccountId = Guid.Empty.ToString();
32+
public string AccountKey = string.Empty;
33+
public string AuthenticationToken = string.Empty;
34+
public string AccessToken = string.Empty;
35+
}
36+
```
37+
38+
The C++ counterpart looks like this:
39+
40+
```cpp
41+
struct AzureFrontendAccountInfo
42+
{
43+
std::string AccountDomain{};
44+
std::string AccountId{};
45+
std::string AccountKey{};
46+
std::string AuthenticationToken{};
47+
std::string AccessToken{};
48+
};
3649

3750
```
3851

articles/remote-rendering/overview/features/cut-planes.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ void CreateCutPlane(AzureSession session, Entity ownerEntity)
3838
}
3939
```
4040

41+
```cpp
42+
void CreateCutPlane(ApiHandle<AzureSession> session, ApiHandle<Entity> ownerEntity)
43+
{
44+
ApiHandle<CutPlaneComponent> cutPlane = session->Actions()->CreateComponent(ObjectType::CutPlaneComponent, ownerEntity)->as<CutPlaneComponent>();;
45+
cutPlane->Normal(Axis::X); // normal points along the positive x-axis of the owner object's orientation
46+
Color4Ub fadeColor;
47+
fadeColor.channels = { 255, 0, 0, 128 }; // fade to 50% red
48+
cutPlane->FadeColor(fadeColor);
49+
cutPlane->FadeLength(0.05f); // gradient width: 5cm
50+
}
51+
```
52+
53+
4154
### CutPlaneComponent properties
4255
4356
The following properties are exposed on a cut plane component:

articles/remote-rendering/overview/features/override-hierarchical-state.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,21 @@ component.SetState(HierarchicalStates.SeeThrough, HierarchicalEnableState.Inheri
6565
component.SetState(HierarchicalStates.Hidden | HierarchicalStates.DisableCollision, HierarchicalEnableState.ForceOff);
6666
```
6767

68+
```cpp
69+
ApiHandle<HierarchicalStateOverrideComponent> component = ...;
70+
71+
// set one state directly
72+
component->HiddenState(HierarchicalEnableState::ForceOn);
73+
74+
// set a state with the SetState function
75+
component->SetState(HierarchicalStates::SeeThrough, HierarchicalEnableState::InheritFromParent);
76+
77+
// set multiple states at once with the SetState function
78+
component->SetState(
79+
(HierarchicalStates)((int32_t)HierarchicalStates::Hidden | (int32_t)HierarchicalStates::DisableCollision), HierarchicalEnableState::ForceOff);
80+
81+
```
82+
6883
### Tint color
6984
7085
The tint color override is slightly special in that there's both an on/off/inherit state and a tint color property. The alpha portion of the tint color defines the weight of the tinting effect: If set to 0.0, no tint color is visible and if set to 1.0 the object will be rendered with pure tint color. For in-between values, the final color will be mixed with the tint color. The tint color can be changed on a per-frame basis to achieve a color animation.

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The illustration shows how:
3232

3333
Frame statistics provide some high-level information for the last frame, such as latency. The data provided in the `FrameStatistics` structure is measured on the client side, so the API is a synchronous call:
3434

35-
````c#
35+
```cs
3636
void QueryFrameData(AzureSession session)
3737
{
3838
FrameStatistics frameStatistics;
@@ -41,7 +41,18 @@ void QueryFrameData(AzureSession session)
4141
// do something with the result
4242
}
4343
}
44-
````
44+
```
45+
46+
```cpp
47+
void QueryFrameData(ApiHandle<AzureSession> session)
48+
{
49+
FrameStatistics frameStatistics;
50+
if (*session->GetGraphicsBinding()->GetLastFrameStatistics(&frameStatistics) == Result::Success)
51+
{
52+
// do something with the result
53+
}
54+
}
55+
```
4556
4657
The retrieved `FrameStatistics` object holds the following members:
4758

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

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Spatial queries are powered by the [Havok Physics](https://www.havok.com/product
2727

2828
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.
2929

30-
````c#
30+
```cs
3131
async void CastRay(AzureSession session)
3232
{
3333
// trace a line from the origin into the +z direction, over 10 units of distance.
@@ -40,14 +40,46 @@ async void CastRay(AzureSession session)
4040

4141
if (hits.Length > 0)
4242
{
43-
var hitObject = hits[0].HitEntity;
43+
var hitObject = hits[0].HitObject;
4444
var hitPosition = hits[0].HitPosition;
4545
var hitNormal = hits[0].HitNormal;
4646

4747
// do something with the hit information
4848
}
4949
}
50-
````
50+
```
51+
52+
```cpp
53+
void CastRay(ApiHandle<AzureSession> session)
54+
{
55+
// trace a line from the origin into the +z direction, over 10 units of distance.
56+
RayCast rayCast;
57+
rayCast.StartPos = { 0, 0, 0 };
58+
rayCast.EndPos = { 0, 0, 1 };
59+
rayCast.MaxHits = 10;
60+
61+
// only return the closest hit
62+
rayCast.HitCollection = HitCollectionPolicy::ClosestHit;
63+
64+
ApiHandle<RaycastQueryAsync> castQuery = *session->Actions()->RayCastQueryAsync(rayCast);
65+
66+
castQuery->Completed([](const ApiHandle<RaycastQueryAsync>& async)
67+
{
68+
std::vector<RayCastHit> hits = *async->Result();
69+
70+
if (hits.size() > 0)
71+
{
72+
auto hitObject = hits[0].HitObject;
73+
auto hitPosition = hits[0].HitPosition;
74+
auto hitNormal = hits[0].HitNormal;
75+
76+
// do something with the hit information
77+
}
78+
});
79+
80+
}
81+
```
82+
5183
5284
There are three hit collection modes:
5385
@@ -58,7 +90,7 @@ There are three hit collection modes:
5890
To exclude objects selectively from being considered for ray casts, the [HierarchicalStateOverrideComponent](override-hierarchical-state.md) component can be used.
5991
6092
<!--
61-
The CollisionMask allows the quey to consider or ignore some objects based on their collision layer. If an object has layer L, it will be hit only if the mask has bit L set.
93+
The CollisionMask allows the query to consider or ignore some objects based on their collision layer. If an object has layer L, it will be hit only if the mask has bit L set.
6294
It is useful in case you want to ignore objects, for instance when setting an object transparent, and trying to select another object behind it.
6395
TODO : Add an API to make that possible.
6496
-->

0 commit comments

Comments
 (0)