Skip to content

Commit 00d98e4

Browse files
committed
for creating unity mesh and instanced rendering from i3dm gltf converted data
note that this change is a proof of concept i3dm instanced rendering in Unity
1 parent e03b3ee commit 00d98e4

File tree

5 files changed

+584
-93
lines changed

5 files changed

+584
-93
lines changed

Runtime/ConfigureReinterop.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ public void ExposeToCPP()
6464

6565
Vector4 v = new Vector4(1.0f, 0.0f, 1.0f, 0.0f);
6666

67+
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
68+
propertyBlock.SetVectorArray(0, new Vector4[0]);
69+
propertyBlock.SetVectorArray(0, new List<Vector4>());
70+
propertyBlock.SetVectorArray("name", new Vector4[0]);
71+
propertyBlock.SetVectorArray("name", new List<Vector4>());
72+
6773
t.position = new Vector3();
6874
Vector3 p = t.position;
6975
float x = p.x;
@@ -129,19 +135,26 @@ public void ExposeToCPP()
129135

130136
Mesh mesh = new Mesh();
131137
Mesh[] meshes = new[] { mesh };
138+
139+
Matrix4x4[] mats = new[] { m2 };
140+
132141
mesh = meshes[0];
133142
int meshesLength = meshes.Length;
134143
mesh.SetVertices(new NativeArray<Vector3>());
135144
mesh.SetNormals(new NativeArray<Vector3>());
136145
mesh.SetUVs(0, new NativeArray<Vector2>());
137146
mesh.SetIndices(new NativeArray<int>(), MeshTopology.Triangles, 0, true, 0);
138147
mesh.RecalculateBounds();
148+
mesh.indexFormat = IndexFormat.UInt32;
139149
int vertexCount = mesh.vertexCount;
140150
int instanceID = mesh.GetInstanceID();
141151

142152
Vector3[] vertices = mesh.vertices;
143153
Vector3 vertex = vertices[0];
144154

155+
int[] triangles = mesh.triangles;
156+
int triangle = triangles[0];
157+
145158
Bounds bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(1, 2, 1));
146159

147160
MeshCollider meshCollider = go.AddComponent<MeshCollider>();
@@ -175,6 +188,7 @@ public void ExposeToCPP()
175188
meshRenderer.material.shaderKeywords = meshRenderer.material.shaderKeywords;
176189
meshRenderer.sharedMaterial = meshRenderer.sharedMaterial;
177190
meshRenderer.material.shader = meshRenderer.material.shader;
191+
meshRenderer.material.enableInstancing = true;
178192
UnityEngine.Object.Destroy(meshGameObject);
179193
UnityEngine.Object.DestroyImmediate(meshGameObject, true);
180194
UnityEngine.Object.DestroyImmediate(meshGameObject);
@@ -483,6 +497,16 @@ public void ExposeToCPP()
483497
stringList.Clear();
484498
count = stringList.Count;
485499

500+
List<Matrix4x4> matList = new List<Matrix4x4>();
501+
matList.Add(m2);
502+
matList.Clear();
503+
count = matList.Count;
504+
505+
List<double4x4> double4x4List = new List<double4x4>();
506+
double4x4List.Add(ecefToLocal);
507+
double4x4List.Clear();
508+
count = double4x4List.Count;
509+
486510
string test = string.Concat("string", "string2");
487511
string[] stringArray = stringList.ToArray();
488512
test = stringArray[0];
@@ -515,6 +539,14 @@ Cesium3DTilesetLoadFailureDetails tilesetDetails
515539
double3 cv4 = new double3(1.0, 2.0, 3.0);
516540
double3x3 matrix3x3 = double3x3.identity;
517541

542+
go.GetComponent<I3dmInstanceRenderer>();
543+
I3dmInstanceRenderer[] i3dmRenderers = go.GetComponentsInChildren<I3dmInstanceRenderer>();
544+
i3dmRenderers = go.GetComponentsInChildren<I3dmInstanceRenderer>(true);
545+
I3dmInstanceRenderer i3dmRenderer = i3dmRenderers[i3dmRenderers.Length - 1];
546+
i3dmRenderer = go.AddComponent<I3dmInstanceRenderer>();
547+
548+
i3dmRenderer.AddInstanceGroup("groupId",mesh,meshRenderer.material,double4x4List);
549+
518550
go.GetComponent<CesiumGlobeAnchor>();
519551
CesiumGlobeAnchor[] globeAnchors = go.GetComponentsInChildren<CesiumGlobeAnchor>();
520552
globeAnchors = go.GetComponentsInChildren<CesiumGlobeAnchor>(true);

Runtime/I3dmInstanceRenderer.cs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using UnityEngine;
2+
using System.Collections.Generic;
3+
using Unity.Mathematics;
4+
5+
namespace CesiumForUnity
6+
{
7+
public static class MatrixUtils
8+
{
9+
public static Matrix4x4 Double4x4ToMatrix4x4(double4x4 m)
10+
{
11+
return new Matrix4x4(
12+
new Vector4((float)m.c0.x, (float)m.c0.y, (float)m.c0.z, (float)m.c0.w),
13+
new Vector4((float)m.c1.x, (float)m.c1.y, (float)m.c1.z, (float)m.c1.w),
14+
new Vector4((float)m.c2.x, (float)m.c2.y, (float)m.c2.z, (float)m.c2.w),
15+
new Vector4((float)m.c3.x, (float)m.c3.y, (float)m.c3.z, (float)m.c3.w)
16+
);
17+
}
18+
19+
public static Matrix4x4[] Double4x4ArrayToMatrix4x4Array(double4x4[] arr)
20+
{
21+
if (arr == null) return null;
22+
Matrix4x4[] result = new Matrix4x4[arr.Length];
23+
for (int i = 0; i < arr.Length; i++)
24+
{
25+
result[i] = Double4x4ToMatrix4x4(arr[i]);
26+
}
27+
return result;
28+
}
29+
}
30+
public class I3dmInstanceRenderer : MonoBehaviour
31+
{
32+
// Instance groups prepared in the C++ cesium-unity dll
33+
private Dictionary<string, InstanceGroupData> instanceGroups = new Dictionary<string, InstanceGroupData>();
34+
35+
//private MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
36+
37+
[System.Serializable]
38+
public class InstanceGroupData
39+
{
40+
public Mesh mesh;
41+
public Material material;
42+
public Matrix4x4[] matrices;
43+
public int maxInstancesPerBatch = 1023;
44+
}
45+
46+
void Update()
47+
{
48+
// Perform rendering for all instance groups
49+
foreach (var kvp in instanceGroups)
50+
{
51+
var groupData = kvp.Value;
52+
RenderInstanceGroup(groupData);
53+
}
54+
}
55+
56+
void RenderInstanceGroup(InstanceGroupData groupData)
57+
{
58+
if (groupData.mesh == null || groupData.material == null || groupData.matrices == null)
59+
return;
60+
61+
int totalInstances = groupData.matrices.Length;
62+
int maxBatchSize = groupData.maxInstancesPerBatch;
63+
64+
// Rendering divided by batch
65+
for (int batchStart = 0; batchStart < totalInstances; batchStart += maxBatchSize)
66+
{
67+
int batchSize = Mathf.Min(maxBatchSize, totalInstances - batchStart);
68+
69+
// Extract the matrices of the current batch
70+
Matrix4x4[] batchMatrices = new Matrix4x4[batchSize];
71+
72+
for(int i = 0; i < batchSize; i++)
73+
{
74+
batchMatrices[i] = transform.GetChild(i).localToWorldMatrix;
75+
}
76+
//System.Array.Copy(groupData.matrices, batchStart, batchMatrices, 0, batchSize);
77+
78+
// Rendering with GPU Instancing
79+
Graphics.DrawMeshInstanced(
80+
groupData.mesh,
81+
0,
82+
groupData.material,
83+
batchMatrices,
84+
batchSize
85+
);
86+
}
87+
}
88+
89+
// called from C++ cesium-unity dll
90+
public void AddInstanceGroup(string groupId, Mesh mesh, Material material, List<double4x4> matrices)
91+
{
92+
// MaterialPropertyBlock setting (for each instance)
93+
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
94+
95+
// TODO: color setting and shader property setting
96+
/*
97+
std::vector<UnityEngine::Vector4> colorVector;
98+
colorVector.reserve(batchSize);
99+
100+
for (size_t i = 0; i < batchSize; ++i) {
101+
size_t sourceIndex = batchStart + i;
102+
const glm::dvec4& glmColor = instanceGroup->colors[sourceIndex];
103+
104+
std::vector<double> colorValues = {
105+
glmColor.x, glmColor.y, glmColor.z, glmColor.w
106+
};
107+
108+
colorVector.push_back(gltfVectorToUnityVector(colorValues, 1.0f));
109+
}
110+
111+
// Set the color array as a shader property
112+
propertyBlock.SetVectorArray(
113+
UnityEngine::Shader::PropertyToID(System::String("_InstanceColors")),
114+
colorArray);
115+
*/
116+
117+
instanceGroups[groupId] = new InstanceGroupData
118+
{
119+
mesh = mesh,
120+
material = material,
121+
matrices = MatrixUtils.Double4x4ArrayToMatrix4x4Array(matrices.ToArray())
122+
};
123+
}
124+
125+
public void RemoveInstanceGroup(string groupId)
126+
{
127+
instanceGroups.Remove(groupId);
128+
}
129+
}
130+
}

Runtime/I3dmInstanceRenderer.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)