Skip to content

Commit

Permalink
Added obj parse queue as a workaround for obj parser mixing up meshes
Browse files Browse the repository at this point in the history
  • Loading branch information
TomSimons committed Jan 7, 2025
1 parent 690bbec commit 601db66
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
88 changes: 88 additions & 0 deletions Assets/_Functionalities/ObjImporter/Scripts/OBJParseQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Netherlands3D.Twin.Layers
{
public class OBJParseQueue : MonoBehaviour
{
public static OBJParseQueue Instance;

public static bool IsParsing = false; //todo: the obj parser currently mixes up meshes if multiple are parsed at once. As a quick fix, only parse one at a time.
public static Queue<ObjSpawner> ParseQueue = new();
public static Coroutine QueueCoroutine;

private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}

Instance = this;
}

public static void Enqueue(ObjSpawner spawner)
{
if (spawner == null) return;

ParseQueue.Enqueue(spawner);

// Start processing if not already active
if (!IsParsing)
{
Instance.StartCoroutine(Instance.ProcessQueue());
}
}

public static void Remove(ObjSpawner spawner)
{
if (ParseQueue.Contains(spawner))
{
// Rebuild the queue without the removed spawner
var tempQueue = new Queue<ObjSpawner>();
while (ParseQueue.Count > 0)
{
var item = ParseQueue.Dequeue();
if (item != spawner)
{
tempQueue.Enqueue(item);
}
}

foreach (var item in tempQueue)
{
ParseQueue.Enqueue(item);
}
}
}

private IEnumerator ProcessQueue()
{
IsParsing = true;

while (ParseQueue.Count > 0)
{
ObjSpawner currentSpawner = ParseQueue.Dequeue();

// Skip null or destroyed OBJSpawners
if (currentSpawner == null)
{
continue;
}

currentSpawner.StartImport();

// Wait until the current spawner signals completion
while (!currentSpawner.IsImportComplete)
{
yield return null;
}
}

IsParsing = false;
}
}
}
11 changes: 11 additions & 0 deletions Assets/_Functionalities/ObjImporter/Scripts/OBJParseQueue.cs.meta

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

17 changes: 15 additions & 2 deletions Assets/_Functionalities/ObjImporter/Scripts/ObjSpawner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class ObjSpawner : MonoBehaviour, ILayerWithPropertyData
public bool HasMtl => GetMtlPathFromPropertyData() != string.Empty;
public UnityEvent<bool> MtlImportSuccess = new();

public bool IsImportComplete { get; private set; } = false;

private void Awake()
{
gameObject.transform.position = ObjectPlacementUtility.GetSpawnPoint();
Expand All @@ -47,7 +49,17 @@ public void LoadProperties(List<LayerPropertyData> properties)

private void Start()
{
StartImport(); //called after loading properties or after setting the file path through the import adapter
if (!OBJParseQueue.Instance)
{
var queue = new GameObject("OBJParseQueue").AddComponent<OBJParseQueue>();
}

OBJParseQueue.Enqueue(this);
}

private void OnDestroy()
{
OBJParseQueue.Remove(this);
}

public void StartImport()
Expand Down Expand Up @@ -110,10 +122,11 @@ private void OnObjImported(GameObject returnedGameObject)
}

// In case the returned object is georeferenced, or this (parent) object has its transform set from a property, we will use either of those positionings, and need to retain the world position.
returnedGameObject.transform.SetParent(this.transform, isGeoReferenced || hasTransformProperty);
returnedGameObject.transform.SetParent(this.transform, isGeoReferenced );
returnedGameObject.AddComponent<MeshCollider>();

DisposeImporter();
IsImportComplete = true;
}

private void SetObjectPosition(GameObject returnedGameObject, bool hasTransformProperty)
Expand Down

0 comments on commit 601db66

Please sign in to comment.