Skip to content

Commit

Permalink
Merge pull request #361 from Netherlands3D/bugfix/obj-in-project
Browse files Browse the repository at this point in the history
Bugfix/obj in project
  • Loading branch information
TomSimons authored Jan 7, 2025
2 parents 02efb32 + 601db66 commit d686da5
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ public class HierarchicalObjectLayerGameObject : LayerGameObject, IPointerClickH
private Vector3 previousScale;

LayerPropertyData ILayerWithPropertyData.PropertyData => transformPropertyData;
public bool TransformIsSetFromProperty { get; private set; } = false;

protected void Awake()
{
transformPropertyData = new TransformLayerPropertyData(new Coordinate(transform.position), transform.eulerAngles, transform.localScale);

propertySections = GetComponents<IPropertySectionInstantiator>().ToList();
toggleScatterPropertySectionInstantiator = GetComponent<ToggleScatterPropertySectionInstantiator>();
}
Expand Down Expand Up @@ -100,7 +101,8 @@ public virtual void LoadProperties(List<LayerPropertyData> properties)
UpdatePosition(this.transformPropertyData.Position);
UpdateRotation(this.transformPropertyData.EulerRotation);
UpdateScale(this.transformPropertyData.LocalScale);

TransformIsSetFromProperty = true;

transformPropertyData.OnPositionChanged.AddListener(UpdatePosition);
transformPropertyData.OnRotationChanged.AddListener(UpdateRotation);
transformPropertyData.OnScaleChanged.AddListener(UpdateScale);
Expand Down
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.

22 changes: 15 additions & 7 deletions Assets/_Functionalities/ObjImporter/Scripts/OBJPropertyData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,33 @@ public Uri ObjFile
OnObjUriChanged.Invoke(value);
}
}

[JsonIgnore]
public Uri MtlFile
{
get => mtlFile;
set
{
mtlFile= value;
mtlFile = value;
OnMtlUriChanged.Invoke(value);
}
}

public IEnumerable<LayerAsset> GetAssets()
{
return new List<LayerAsset>()
var existingAssets = new List<LayerAsset>();

if (objFile != null)
{
new (this, objFile != null ? objFile : null),
new (this, mtlFile != null ? mtlFile : null)
};
existingAssets.Add(new(this, objFile));
}

if (mtlFile != null)
{
existingAssets.Add(new(this, mtlFile));
}

return existingAssets;
}
}
}
}
37 changes: 32 additions & 5 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 @@ -93,22 +105,37 @@ private void ImportObj(string objPath, string mtlPath = "")

private void OnObjImported(GameObject returnedGameObject)
{
// By explicitly stating the worldPositionStays to false, we ensure Obj is spawned and it will retain the
// position and scale in this parent object
bool isGeoReferenced = !importer.createdGameobjectIsMoveable;
bool hasTransformProperty = false;

var holgo = GetComponent<HierarchicalObjectLayerGameObject>();
if (holgo)
hasTransformProperty = holgo.TransformIsSetFromProperty;

importedObject = returnedGameObject;
if (isGeoReferenced)
{
transform.position = returnedGameObject.transform.position;
SetObjectPosition(returnedGameObject, hasTransformProperty);
Debug.Log("Geo-referenced object importer, moving camera to this position: " + returnedGameObject.transform.position);
var mainCam = Camera.main;
mainCam.transform.position = returnedGameObject.transform.position + (-cameraDistanceFromGeoReferencedObject * mainCam.transform.forward);
}

returnedGameObject.transform.SetParent(this.transform, isGeoReferenced);
// 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 );
returnedGameObject.AddComponent<MeshCollider>();

DisposeImporter();
IsImportComplete = true;
}

private void SetObjectPosition(GameObject returnedGameObject, bool hasTransformProperty)
{
// if we already have a position from the transform properties, match the returned object's positioning to this saved position, otherwise set it to the returned object's positioning, since this is the georeferenced position.
if (hasTransformProperty)
returnedGameObject.transform.position = transform.position;
else
transform.position = returnedGameObject.transform.position;
}

private void DisposeImporter()
Expand Down

0 comments on commit d686da5

Please sign in to comment.