Skip to content

Commit

Permalink
Basic Unity height query API.
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Sep 23, 2024
1 parent 3837e0d commit a134330
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 6 deletions.
10 changes: 5 additions & 5 deletions Reinterop~/MethodsImplementedInCpp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ private static void GenerateMethod(CppGenerationContext context, TypeToGenerate

CSharpType csWrapperType = CSharpType.FromSymbol(context, item.Type);
CSharpType csReturnType = CSharpType.FromSymbol(context, method.ReturnType);
var csParameters = method.Parameters.Select(parameter => (Name: parameter.Name, CallName: parameter.Name, Type: CSharpType.FromSymbol(context, parameter.Type)));
var csParameters = method.Parameters.Select(parameter => (Name: parameter.Name, CallName: parameter.Name, Type: CSharpType.FromSymbol(context, parameter.Type), IsParams: parameter.IsParams));
var csParametersInterop = csParameters;
var implementationPointer = new CSharpType(context, InteropTypeKind.Primitive, csWrapperType.Namespaces, csWrapperType.Name + ".ImplementationHandle", csWrapperType.SpecialType, null);

Expand All @@ -354,13 +354,13 @@ private static void GenerateMethod(CppGenerationContext context, TypeToGenerate
{
csParametersInterop = new[]
{
(Name: "implementation", CallName: "_implementation", Type: implementationPointer)
(Name: "implementation", CallName: "_implementation", Type: implementationPointer, IsParams: false)
}.Concat(csParametersInterop);
}

csParametersInterop = new[]
{
(Name: "thiz", CallName: "this", Type: csWrapperType),
(Name: "thiz", CallName: "this", Type: csWrapperType, IsParams: false),
}.Concat(csParametersInterop);
}

Expand All @@ -370,7 +370,7 @@ private static void GenerateMethod(CppGenerationContext context, TypeToGenerate
{
csParametersInterop = csParametersInterop.Concat(new[]
{
(Name: "pReturnValue", CallName: "&returnValue", Type: csInteropReturnType.AsPointer())
(Name : "pReturnValue", CallName : "&returnValue", Type : csInteropReturnType.AsPointer(), IsParams : false)
});
csInteropReturnType = CSharpType.FromSymbol(context, returnType.Kind == InteropTypeKind.Nullable ? context.Compilation.GetSpecialType(SpecialType.System_Byte) : context.Compilation.GetSpecialType(SpecialType.System_Void));
}
Expand Down Expand Up @@ -429,7 +429,7 @@ private static void GenerateMethod(CppGenerationContext context, TypeToGenerate
result.CSharpPartialMethodDefinitions.Methods.Add(new(
methodDefinition:
$$"""
{{modifiers}} partial {{csReturnType.GetFullyQualifiedName()}} {{method.Name}}({{string.Join(", ", csParameters.Select(parameter => $"{parameter.Type.GetFullyQualifiedName()} {parameter.Name}"))}})
{{modifiers}} partial {{csReturnType.GetFullyQualifiedName()}} {{method.Name}}({{string.Join(", ", csParameters.Select(parameter => $"{(parameter.IsParams ? "params " : "")}{parameter.Type.GetFullyQualifiedName()} {parameter.Name}"))}})
{
unsafe
{
Expand Down
15 changes: 15 additions & 0 deletions Runtime/Cesium3DTileset.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Reinterop;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;

namespace CesiumForUnity
Expand All @@ -20,6 +23,13 @@ public enum CesiumDataSource
FromUrl
}

public class SampleHeightResult
{
public double3[] longitudeLatitudeHeightPositions { get; set; }
public bool[] heightSampled { get; set; }
public string[] warnings { get; set; }
}

/// <summary>
/// A tileset in the 3D Tiles format. <see href="https://github.com/CesiumGS/3d-tiles">3D Tiles</see>
/// is an open specification for sharing, visualizing, fusing, and interacting with massive
Expand Down Expand Up @@ -714,6 +724,8 @@ public bool createPhysicsMeshes
/// </summary>
public partial void FocusTileset();

public partial Task<SampleHeightResult> SampleHeightMostDetailed(params double3[] longitudeLatitudeHeightPositions);

#endregion

#region Private Methods
Expand All @@ -731,6 +743,8 @@ public bool createPhysicsMeshes

#endregion

#region Backward Compatibility

void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
Expand All @@ -748,5 +762,6 @@ void ISerializationCallbackReceiver.OnAfterDeserialize()
#if UNITY_EDITOR
private bool _useDefaultServer = false;
#endif
#endregion
}
}
15 changes: 15 additions & 0 deletions Runtime/ConfigureReinterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,21 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails
camera = manager.additionalCameras[i];
}

TaskCompletionSource<SampleHeightResult> promise = new TaskCompletionSource<SampleHeightResult>();
promise.SetException(new Exception("message"));
SampleHeightResult result = new SampleHeightResult();
result.longitudeLatitudeHeightPositions = null;
result.heightSampled = null;
result.warnings = null;
promise.SetResult(result);
Task<SampleHeightResult> task = promise.Task;

double3[] positions = null;
for (int i = 0; i < positions.Length; ++i)
{
positions[i] = positions[i];
}

#if UNITY_EDITOR
SceneView sv = SceneView.lastActiveSceneView;
sv.pivot = sv.pivot;
Expand Down
73 changes: 73 additions & 0 deletions Tests/TestCesium3DTileset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using CesiumForUnity;
using NUnit.Framework;
using System;
using System.Collections;
using System.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.TestTools;

public class TestCesium3DTileset
{
[UnityTest]
public IEnumerator SampleHeightMostDetailedWorksWithAnEmptyArrayOfPositions()
{
GameObject go = new GameObject();
go.name = "Cesium World Terrain";
Cesium3DTileset tileset = go.AddComponent<Cesium3DTileset>();
tileset.ionAssetID = 1;

// TODO: remove this
yield return null;

Task<SampleHeightResult> task = tileset.SampleHeightMostDetailed();

while (!task.IsCompleted)
{
yield return null;
}

SampleHeightResult result = task.Result;
Assert.IsNotNull(result);
Assert.IsNotNull(result.longitudeLatitudeHeightPositions);
Assert.IsNotNull(result.heightSampled);
Assert.IsNotNull(result.warnings);
Assert.AreEqual(result.longitudeLatitudeHeightPositions.Length, 0);
Assert.AreEqual(result.heightSampled.Length, 0);
Assert.AreEqual(result.warnings.Length, 0);
}

[UnityTest]
public IEnumerator SampleHeightMostDetailedWorksWithASinglePosition()
{
GameObject go = new GameObject();
go.name = "Cesium World Terrain";
Cesium3DTileset tileset = go.AddComponent<Cesium3DTileset>();
tileset.ionAssetID = 1;

// TODO: remove this
yield return null;

Task<SampleHeightResult> task = tileset.SampleHeightMostDetailed(new double3(-105.1, 40.1, 1.0));

while (!task.IsCompleted)
{
yield return null;
}

SampleHeightResult result = task.Result;
Assert.IsNotNull(result);
Assert.IsNotNull(result.longitudeLatitudeHeightPositions);
Assert.IsNotNull(result.heightSampled);
Assert.IsNotNull(result.warnings);
Assert.AreEqual(result.longitudeLatitudeHeightPositions.Length, 1);
Assert.AreEqual(result.heightSampled.Length, 1);
Assert.AreEqual(result.warnings.Length, 0);

Assert.AreEqual(result.heightSampled[0], true);
Assert.AreEqual(result.longitudeLatitudeHeightPositions[0].x, -105.1, 1e-12);
Assert.AreEqual(result.longitudeLatitudeHeightPositions[0].y, 40.1, 1e-12);
// Returned height should be different from the original height (1.0) by at least one meter.
Assert.IsTrue(math.abs(result.longitudeLatitudeHeightPositions[0].z - 1.0) > 1.0);
}
}
11 changes: 11 additions & 0 deletions Tests/TestCesium3DTileset.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 77 additions & 0 deletions native~/Runtime/src/Cesium3DTilesetImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
#include <DotNet/CesiumForUnity/CesiumIonServer.h>
#include <DotNet/CesiumForUnity/CesiumRasterOverlay.h>
#include <DotNet/CesiumForUnity/CesiumTileExcluder.h>
#include <DotNet/CesiumForUnity/SampleHeightResult.h>
#include <DotNet/System/Exception.h>
#include <DotNet/System/Object.h>
#include <DotNet/System/String.h>
#include <DotNet/System/Threading/Tasks/Task1.h>
#include <DotNet/System/Threading/Tasks/TaskCompletionSource1.h>
#include <DotNet/Unity/Mathematics/double3.h>
#include <DotNet/UnityEngine/Application.h>
#include <DotNet/UnityEngine/Camera.h>
#include <DotNet/UnityEngine/Component.h>
Expand Down Expand Up @@ -381,6 +386,78 @@ float Cesium3DTilesetImpl::ComputeLoadProgress(
return getTileset()->computeLoadProgress();
}

System::Threading::Tasks::Task1<CesiumForUnity::SampleHeightResult>
Cesium3DTilesetImpl::SampleHeightMostDetailed(
const CesiumForUnity::Cesium3DTileset& tileset,
const System::Array1<Unity::Mathematics::double3>&
longitudeLatitudeHeightPositions) {
System::Threading::Tasks::TaskCompletionSource1<
CesiumForUnity::SampleHeightResult>
promise{};

Tileset* pTileset = this->getTileset();
if (pTileset == nullptr) {
// TODO: wait a tick for the tileset to be created.
promise.SetException(
System::Exception(System::String("Tileset not created yet.")));
return promise.Task();
}

std::vector<CesiumGeospatial::Cartographic> positions;
positions.reserve(longitudeLatitudeHeightPositions.Length());

for (int32_t i = 0, len = longitudeLatitudeHeightPositions.Length(); i < len;
++i) {
Unity::Mathematics::double3 position = longitudeLatitudeHeightPositions[i];
positions.emplace_back(CesiumGeospatial::Cartographic::fromDegrees(
position.x,
position.y,
position.z));
}

pTileset->sampleHeightMostDetailed(positions)
.thenImmediately(
[promise](Cesium3DTilesSelection::SampleHeightResult&& result) {
System::Array1<Unity::Mathematics::double3> positions(
result.positions.size());
for (size_t i = 0; i < result.positions.size(); ++i) {
const CesiumGeospatial::Cartographic& positionRadians =
result.positions[i];
positions.Item(
i,
Unity::Mathematics::double3{
CesiumUtility::Math::radiansToDegrees(
positionRadians.longitude),
CesiumUtility::Math::radiansToDegrees(
positionRadians.latitude),
positionRadians.height});
}

System::Array1<bool> heightSampled(result.heightSampled.size());
for (size_t i = 0; i < result.heightSampled.size(); ++i) {
heightSampled.Item(i, result.heightSampled[i]);
}

System::Array1<System::String> warnings(result.warnings.size());
for (size_t i = 0; i < result.warnings.size(); ++i) {
warnings.Item(i, System::String(result.warnings[i]));
}

CesiumForUnity::SampleHeightResult unityResult;
unityResult.longitudeLatitudeHeightPositions(positions);
unityResult.heightSampled(heightSampled);
unityResult.warnings(warnings);

promise.SetResult(unityResult);
})
.catchImmediately([promise](std::exception&& exception) {
promise.SetException(
System::Exception(System::String(exception.what())));
});

return promise.Task();
}

Tileset* Cesium3DTilesetImpl::getTileset() { return this->_pTileset.get(); }

const Tileset* Cesium3DTilesetImpl::getTileset() const {
Expand Down
13 changes: 13 additions & 0 deletions native~/Runtime/src/Cesium3DTilesetImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <DotNet/CesiumForUnity/CesiumGeoreference.h>
#include <DotNet/System/Action.h>
#include <DotNet/System/Array1.h>
#include <DotNet/System/Threading/Tasks/Task1.h>

#include <memory>

Expand All @@ -19,8 +20,13 @@
namespace DotNet::CesiumForUnity {
class Cesium3DTileset;
class CesiumRasterOverlay;
class SampleHeightResult;
} // namespace DotNet::CesiumForUnity

namespace DotNet::Unity::Mathematics {
struct double3;
}

namespace Cesium3DTilesSelection {
class Tileset;
}
Expand Down Expand Up @@ -49,6 +55,13 @@ class Cesium3DTilesetImpl : public CesiumImpl<Cesium3DTilesetImpl> {
float
ComputeLoadProgress(const DotNet::CesiumForUnity::Cesium3DTileset& tileset);

DotNet::System::Threading::Tasks::Task1<
DotNet::CesiumForUnity::SampleHeightResult>
SampleHeightMostDetailed(
const DotNet::CesiumForUnity::Cesium3DTileset& tileset,
const DotNet::System::Array1<DotNet::Unity::Mathematics::double3>&
longitudeLatitudeHeightPositions);

Cesium3DTilesSelection::Tileset* getTileset();
const Cesium3DTilesSelection::Tileset* getTileset() const;

Expand Down

0 comments on commit a134330

Please sign in to comment.