Skip to content

Commit

Permalink
Get metadata picking working
Browse files Browse the repository at this point in the history
  • Loading branch information
j9liu committed Nov 17, 2023
1 parent 1486c5b commit 0793ae1
Show file tree
Hide file tree
Showing 17 changed files with 884 additions and 221 deletions.
8 changes: 7 additions & 1 deletion Runtime/CesiumFeatureIdAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ internal CesiumFeatureIdAttribute()
/// <param name="vertexIndex">The index of the target vertex.</param>
/// <returns>The feature ID associated with the given vertex, or -1
/// if the feature ID set is invalid or if the vertex is out of bounds.</returns>
public override partial Int64 GetFeatureIDForVertex(Int64 vertexIndex);
public override partial Int64 GetFeatureIdForVertex(Int64 vertexIndex);

public override Int64 GetFeatureIdFromRaycastHit(RaycastHit hitInfo)
{
int vertex = GetFirstVertexFromHitTriangle(hitInfo);
return this.GetFeatureIdForVertex(vertex);
}
}
}
73 changes: 64 additions & 9 deletions Runtime/CesiumFeatureIdSet.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Reinterop;
using System;
using UnityEngine;

Expand Down Expand Up @@ -88,24 +87,80 @@ internal CesiumFeatureIdSet(Int64 featureCount)

/// <summary>
/// Gets the feature ID associated with a given vertex. The feature ID can be
/// used with a CesiumPropertyTable to retrieve the corresponding metadata.
/// used with a <see cref="CesiumPropertyTable"/> to retrieve the corresponding
/// metadata.
/// </summary>
/// <remarks>
/// This returns -1 if the given vertex is out-of-bounds, or if the feature ID
/// set is invalid.
/// </remarks>
/// <param name="vertexIndex">The index of the target vertex.</param>
/// <returns>The feature ID associated with the given vertex, or -1 for an invalid
/// feature ID set or invalid input.</returns>
public virtual Int64 GetFeatureIDForVertex(Int64 vertexIndex)
/// <returns>The feature ID associated with the given vertex, or -1 for an
/// invalid feature ID set or invalid input.</returns>
public virtual Int64 GetFeatureIdForVertex(Int64 vertexIndex)
{
if (this.type == CesiumFeatureIdSetType.Implicit)
if (this.type != CesiumFeatureIdSetType.Implicit)
{
return vertexIndex;
// Other methods should be handled by CesiumFeatureIdAttribute and CesiumFeatureIdTexture respectively.
return -1;
}

// Other methods should be handled by CesiumFeatureIdAttribute and CesiumFeatureIdTexture respectively.
return -1;
if (vertexIndex < 0 || vertexIndex >= this.featureCount)
{
return -1;
}

return vertexIndex;
}

/// <summary>
/// Gets the feature ID from the feature ID set using the given raycast hit.
/// This returns a more accurate value for feature ID textures, since they
/// define feature IDs per-texel instead of per-vertex. The feature ID can
/// be used with a <see cref="CesiumPropertyTable"/> to retrieve the
/// corresponding metadata.
/// </summary>
/// <remarks>
/// This can still retrieve the feature IDs for non-texture feature ID sets.
/// For attribute or implicit feature IDs, the first feature ID associated
/// with the first vertex of the intersected face is returned.
///
/// This returns -1 if the feature ID set is invalid.
/// </remarks>
///
/// <param name="hitInfo">The raycast hit info.</param>
/// <returns></returns>
public virtual Int64 GetFeatureIdFromRaycastHit(RaycastHit hitInfo)
{
if (this.type != CesiumFeatureIdSetType.Implicit)
{
// Other methods should be handled by CesiumFeatureIdAttribute and
// CesiumFeatureIdTexture respectively.
return -1;
}

return GetFirstVertexFromHitTriangle(hitInfo);
}


/// <summary>
/// Given a successful raycast hit, finds the index of the first vertex from
/// the triangle hit. Returns -1 if the triangleIndex is invalid.
/// </summary>
/// <param name="hitInfo">The raycast hit info.</param>
/// <returns>The index of the first vertex on the triangle.</returns>
protected int GetFirstVertexFromHitTriangle(RaycastHit hitInfo)
{
MeshFilter meshFilter = hitInfo.transform.GetComponent<MeshFilter>();
if (meshFilter == null || meshFilter.mesh == null)
{
return -1;
}

Mesh mesh = meshFilter.mesh;
int[] indices = mesh.GetTriangles(0);
int targetVertex = hitInfo.triangleIndex * 3;
return targetVertex < indices.Length ? indices[targetVertex] : -1;
}
}
}
4 changes: 2 additions & 2 deletions Runtime/CesiumMetadataValueType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public enum CesiumMetadataType
Mat2,
Mat3,
Mat4,
String,
Boolean,
Enum,
String
Enum
}

/// <summary>
Expand Down
2 changes: 0 additions & 2 deletions Runtime/CesiumModelMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Reinterop;
using System;
using UnityEngine;

Expand All @@ -9,7 +8,6 @@ namespace CesiumForUnity
/// <see cref="Cesium3DTileset"/>. This component is automatically added
/// to tile game objects if their models contain the root extension.
/// </summary>
[ReinteropNativeImplementation("CesiumForUnityNative::CesiumModelMetadataImpl", "CesiumModelMetadataImpl.h")]
[IconAttribute("Packages/com.cesium.unity/Editor/Resources/Cesium-24x24.png")]
[AddComponentMenu("")]
public partial class CesiumModelMetadata : MonoBehaviour
Expand Down
18 changes: 15 additions & 3 deletions Runtime/CesiumPrimitiveFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,20 @@ public CesiumFeatureIdSet[] featureIdSets
/// <param name="hitInfo">The raycast hit info.</param>
/// <param name="featureIdSetIndex">The index of the target feature ID set.</param>
/// <returns>The feature ID, or -1 if the specified feature ID set is invalid.</returns>
//public partial Int64 GetFeatureIDFromRaycastHit(
// RaycastHit hitInfo,
// Int64 featureIdSetIndex = 0);
public static Int64 GetFeatureIdFromRaycastHit(
RaycastHit hitInfo,
Int64 featureIdSetIndex = 0)
{
CesiumPrimitiveFeatures primitiveFeatures = hitInfo.transform.GetComponent<CesiumPrimitiveFeatures>();
if (primitiveFeatures == null ||
featureIdSetIndex < 0 || featureIdSetIndex >= primitiveFeatures.featureIdSets.Length)
{
return -1;
}

CesiumFeatureIdSet featureIdSet = primitiveFeatures.featureIdSets[featureIdSetIndex];

return featureIdSet.GetFeatureIdFromRaycastHit(hitInfo);
}
}
}
46 changes: 31 additions & 15 deletions Runtime/CesiumPropertyTable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Reinterop;
using System;
using System.Collections.Generic;
using UnityEngine;
Expand Down Expand Up @@ -30,42 +29,59 @@ public enum CesiumPropertyTableStatus
/// <summary>
/// Represents a glTF property table in the EXT_structural_metadata extension.
/// A property table is a collection of properties for the features in a mesh.
/// It knows how to look up the metadata values associated with a given
/// feature ID.
/// It knows how to look up the metadata values associated with a given feature ID.
/// </summary>
[ReinteropNativeImplementation("CesiumForUnityNative::CesiumPropertyTableImpl", "CesiumPropertyTableImpl.h")]
public partial class CesiumPropertyTable
public class CesiumPropertyTable
{
private CesiumPropertyTableStatus _status =
CesiumPropertyTableStatus.ErrorInvalidPropertyTable;

/// <summary>
/// The status of the property table. If an error occurred while parsing
/// the property table from the glTF extension, this briefly conveys why.
/// </summary>
public CesiumPropertyTableStatus status
{
get => this._status;
internal set => this._status = value;
get; internal set;
}

/// <summary>
/// The name of the property table. If no name was specified in the glTF
/// extension, this is an empty string.
/// </summary>
public string name { get; internal set; }
public string name
{
get; internal set;
}

/// <summary>
/// The number of values each property in the table is expected to have.
/// If an error occurred while parsing the property table, this returns zero.
/// </summary>
public Int64 count { get; internal set; }
public Int64 count
{
get; internal set;
}

/// <summary>
/// The properties of the property table, mapped by property name.
/// The properties of the property table, mapped by property id.
/// </summary>
public Dictionary<string, CesiumPropertyTableProperty> properties { get; internal set; }
public Dictionary<String, CesiumPropertyTableProperty> properties
{
get; internal set;
}

internal CesiumPropertyTable()
{
this.status = CesiumPropertyTableStatus.ErrorInvalidPropertyTable;
this.count = 0;
}

// public Dictionary<string, ____> GetMetadataValuesForFeature() { }
public Dictionary<String, String> GetMetadataValuesForFeatureAsStrings(Int64 featureId)
{
Dictionary<String, String> result = new Dictionary<String, String>();
foreach (KeyValuePair<String, CesiumPropertyTableProperty> property in this.properties)
{
result.Add(property.Key, property.Value.GetString(featureId));
}
return result;
}
}
}
Loading

0 comments on commit 0793ae1

Please sign in to comment.