Skip to content

Commit 6443579

Browse files
committed
Enhancement: basic support for glTF LINES primitive mode
ie list of segments: wouldn't be hard to support line loops and strips I guess, but I'd need a dataset to test that. No support for rendering with "attenuation" like point clouds: haven't looked at the custom vertex factory and shader yet to see how hard it would be to support lines. Probably need to change the name of CesiumGltfPointsComponent and proxy, unless it makes more sense to duplicate them.
1 parent 7a021a1 commit 6443579

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

Source/CesiumRuntime/Private/CesiumGltfComponent.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,7 @@ getIndices(const TIndexAccessor& indicesView, int32 primitiveMode) {
13281328
break;
13291329
case CesiumGltf::MeshPrimitive::Mode::TRIANGLES:
13301330
case CesiumGltf::MeshPrimitive::Mode::POINTS:
1331+
case CesiumGltf::MeshPrimitive::Mode::LINES:
13311332
default:
13321333
indices.SetNum(static_cast<TArray<uint32>::SizeType>(indicesView.size()));
13331334
for (int32 i = 0; i < indicesView.size(); ++i) {
@@ -1360,6 +1361,7 @@ static void loadPrimitive(
13601361

13611362
switch (primitive.mode) {
13621363
case CesiumGltf::MeshPrimitive::Mode::POINTS:
1364+
case CesiumGltf::MeshPrimitive::Mode::LINES:
13631365
case CesiumGltf::MeshPrimitive::Mode::TRIANGLES:
13641366
case CesiumGltf::MeshPrimitive::Mode::TRIANGLE_STRIP:
13651367
case CesiumGltf::MeshPrimitive::Mode::TRIANGLE_FAN:
@@ -1540,8 +1542,10 @@ static void loadPrimitive(
15401542
bool needToGenerateFlatNormals = normalsAreRequired && !hasNormals;
15411543
bool needToGenerateTangents = needsTangents && !hasTangents;
15421544
bool duplicateVertices = needToGenerateFlatNormals || needToGenerateTangents;
1543-
duplicateVertices = duplicateVertices &&
1544-
primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS;
1545+
duplicateVertices =
1546+
duplicateVertices &&
1547+
primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS &&
1548+
primitive.mode != CesiumGltf::MeshPrimitive::Mode::LINES;
15451549

15461550
uint32 numVertices =
15471551
duplicateVertices ? uint32(indices.Num()) : uint32(positionView.size());
@@ -1759,7 +1763,8 @@ static void loadPrimitive(
17591763
section.MinVertexIndex = 0;
17601764
section.MaxVertexIndex = numVertices - 1;
17611765
section.bEnableCollision =
1762-
primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS;
1766+
primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS &&
1767+
primitive.mode != CesiumGltf::MeshPrimitive::Mode::LINES;
17631768
section.bCastShadow = true;
17641769
section.MaterialIndex = 0;
17651770

@@ -1786,7 +1791,8 @@ static void loadPrimitive(
17861791
#if ENGINE_VERSION_5_5_OR_HIGHER
17871792
// UE 5.5 requires that we do this in order to avoid a crash when ray
17881793
// tracing is enabled.
1789-
if (primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS) {
1794+
if (primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS &&
1795+
primitive.mode != CesiumGltf::MeshPrimitive::Mode::LINES) {
17901796
// UE 5.5 requires that we do this in order to avoid a crash when ray
17911797
// tracing is enabled.
17921798
RenderData->InitializeRayTracingRepresentationFromRenderingLODs();
@@ -1800,7 +1806,7 @@ static void loadPrimitive(
18001806

18011807
primitiveResult.transform = transform * yInvertMatrix * scaleMatrix;
18021808

1803-
if (primitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS &&
1809+
if (section.bEnableCollision &&
18041810
options.pMeshOptions->pNodeOptions->pModelOptions->createPhysicsMeshes) {
18051811
if (numVertices != 0 && indices.Num() != 0) {
18061812
TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::ChaosCook)
@@ -3040,9 +3046,12 @@ static void loadPrimitiveGameThreadPart(
30403046

30413047
UStaticMeshComponent* pMesh = nullptr;
30423048
ICesiumPrimitive* pCesiumPrimitive = nullptr;
3043-
if (meshPrimitive.mode == CesiumGltf::MeshPrimitive::Mode::POINTS) {
3049+
if (meshPrimitive.mode == CesiumGltf::MeshPrimitive::Mode::POINTS ||
3050+
meshPrimitive.mode == CesiumGltf::MeshPrimitive::Mode::LINES) {
30443051
UCesiumGltfPointsComponent* pPointMesh =
30453052
NewObject<UCesiumGltfPointsComponent>(pGltf, componentName);
3053+
pPointMesh->bLinesList =
3054+
(meshPrimitive.mode == CesiumGltf::MeshPrimitive::Mode::LINES);
30463055
pPointMesh->UsesAdditiveRefinement =
30473056
tile.getRefine() == Cesium3DTilesSelection::TileRefine::Add;
30483057
pPointMesh->GeometricError = static_cast<float>(tile.getGeometricError());
@@ -3114,7 +3123,8 @@ static void loadPrimitiveGameThreadPart(
31143123
// sense, but if Unreal will crash trying to generate ray tracing
31153124
// information for a static mesh without triangles.
31163125
pStaticMesh->bSupportRayTracing =
3117-
meshPrimitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS;
3126+
meshPrimitive.mode != CesiumGltf::MeshPrimitive::Mode::POINTS &&
3127+
meshPrimitive.mode != CesiumGltf::MeshPrimitive::Mode::LINES;
31183128
pMesh->SetStaticMesh(pStaticMesh);
31193129

31203130
pStaticMesh->SetFlags(

Source/CesiumRuntime/Private/CesiumGltfPointsComponent.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ FPrimitiveSceneProxy* UCesiumGltfPointsComponent::CreateSceneProxy() {
1818
}
1919

2020
FCesiumGltfPointsSceneProxy* Proxy =
21-
new FCesiumGltfPointsSceneProxy(this, GetScene()->GetFeatureLevel());
21+
new FCesiumGltfPointsSceneProxy(this, GetScene()->GetFeatureLevel(), bLinesList);
2222

2323
FCesiumGltfPointsSceneProxyTilesetData TilesetData;
2424
TilesetData.UpdateFromComponent(this);

Source/CesiumRuntime/Private/CesiumGltfPointsComponent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class UCesiumGltfPointsComponent : public UCesiumGltfPrimitiveComponent {
2828
// error.
2929
glm::vec3 Dimensions;
3030

31+
bool bLinesList = false;
32+
3133
// Override UPrimitiveComponent interface.
3234
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
3335
};

Source/CesiumRuntime/Private/CesiumGltfPointsSceneProxy.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void FCesiumGltfPointsSceneProxyTilesetData::UpdateFromComponent(
2626
UsesAdditiveRefinement = Component->UsesAdditiveRefinement;
2727
GeometricError = Component->GeometricError;
2828
Dimensions = Component->Dimensions;
29+
bLinesList = Component->bLinesList;
2930
}
3031

3132
SIZE_T FCesiumGltfPointsSceneProxy::GetTypeHash() const {
@@ -35,11 +36,12 @@ SIZE_T FCesiumGltfPointsSceneProxy::GetTypeHash() const {
3536

3637
FCesiumGltfPointsSceneProxy::FCesiumGltfPointsSceneProxy(
3738
UCesiumGltfPointsComponent* InComponent,
38-
ERHIFeatureLevel::Type InFeatureLevel)
39+
ERHIFeatureLevel::Type InFeatureLevel,
40+
bool bLinesList)
3941
: FPrimitiveSceneProxy(InComponent),
4042
RenderData(InComponent->GetStaticMesh()->GetRenderData()),
4143
NumPoints(RenderData->LODResources[0].IndexBuffer.GetNumIndices()),
42-
bAttenuationSupported(
44+
bAttenuationSupported(!bLinesList &&
4345
RHISupportsManualVertexFetch(GetScene().GetShaderPlatform())),
4446
TilesetData(),
4547
AttenuationVertexFactory(
@@ -116,6 +118,7 @@ uint32 FCesiumGltfPointsSceneProxy::GetMemoryFootprint(void) const {
116118
void FCesiumGltfPointsSceneProxy::UpdateTilesetData(
117119
const FCesiumGltfPointsSceneProxyTilesetData& InTilesetData) {
118120
TilesetData = InTilesetData;
121+
ensure(!TilesetData.bLinesList || !bAttenuationSupported); // see ctor
119122
}
120123

121124
float FCesiumGltfPointsSceneProxy::GetGeometricError() const {
@@ -208,17 +211,22 @@ void FCesiumGltfPointsSceneProxy::CreateMesh(FMeshBatch& Mesh) const {
208211
Mesh.VertexFactory = &RenderData->LODVertexFactories[0].VertexFactory;
209212
Mesh.MaterialRenderProxy = Material->GetRenderProxy();
210213
Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative();
211-
Mesh.Type = PT_PointList;
214+
Mesh.Type = TilesetData.bLinesList ? PT_LineList : PT_PointList;
212215
Mesh.DepthPriorityGroup = SDPG_World;
213216
Mesh.LODIndex = 0;
214217
Mesh.bCanApplyViewModeOverrides = false;
215218
Mesh.bUseAsOccluder = false;
216-
Mesh.bWireframe = false;
219+
Mesh.bWireframe = TilesetData.bLinesList;
217220

218221
FMeshBatchElement& BatchElement = Mesh.Elements[0];
219222
BatchElement.IndexBuffer = &RenderData->LODResources[0].IndexBuffer;
220-
BatchElement.NumPrimitives = NumPoints;
221223
BatchElement.FirstIndex = 0;
222224
BatchElement.MinVertexIndex = 0;
223-
BatchElement.MaxVertexIndex = BatchElement.NumPrimitives - 1;
225+
BatchElement.MaxVertexIndex = NumPoints - 1;
226+
if (TilesetData.bLinesList) {
227+
ensure((NumPoints % 2) == 0);
228+
BatchElement.NumPrimitives = NumPoints / 2;
229+
} else {
230+
BatchElement.NumPrimitives = NumPoints;
231+
}
224232
}

Source/CesiumRuntime/Private/CesiumGltfPointsSceneProxy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct FCesiumGltfPointsSceneProxyTilesetData {
1919
bool UsesAdditiveRefinement;
2020
float GeometricError;
2121
glm::vec3 Dimensions;
22+
bool bLinesList;
2223

2324
FCesiumGltfPointsSceneProxyTilesetData();
2425

@@ -36,7 +37,8 @@ class FCesiumGltfPointsSceneProxy final : public FPrimitiveSceneProxy {
3637

3738
FCesiumGltfPointsSceneProxy(
3839
UCesiumGltfPointsComponent* InComponent,
39-
ERHIFeatureLevel::Type InFeatureLevel);
40+
ERHIFeatureLevel::Type InFeatureLevel,
41+
bool bLinesList);
4042

4143
virtual ~FCesiumGltfPointsSceneProxy();
4244

0 commit comments

Comments
 (0)