From 3ccef959f7288e4dc53a8fb801d376c4057d4ef8 Mon Sep 17 00:00:00 2001 From: Mike van Riel Date: Mon, 7 Oct 2024 14:12:14 +0200 Subject: [PATCH 1/3] Restore OBJ Importer so that importing 3D objects works again --- Assets/Prefabs/ObjImporter.prefab | 56 ++++++++++++++++++++++++++ Assets/Prefabs/ObjImporter.prefab.meta | 7 ++++ 2 files changed, 63 insertions(+) create mode 100644 Assets/Prefabs/ObjImporter.prefab create mode 100644 Assets/Prefabs/ObjImporter.prefab.meta diff --git a/Assets/Prefabs/ObjImporter.prefab b/Assets/Prefabs/ObjImporter.prefab new file mode 100644 index 00000000..81e81541 --- /dev/null +++ b/Assets/Prefabs/ObjImporter.prefab @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &3683644799359541447 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2552652701665730137} + - component: {fileID: 7917579944522795273} + m_Layer: 0 + m_Name: ObjImporter + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2552652701665730137 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3683644799359541447} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &7917579944522795273 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3683644799359541447} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8b6caa935ef381440b46ff58c21721cd, type: 3} + m_Name: + m_EditorClassIdentifier: + createdGameobjectIsMoveable: 0 + gameObjectData: + name: + materials: [] + gameObjects: [] + BaseMaterial: {fileID: 0} + objFilePath: + mtlFilePath: + imgFilePath: + createSubMeshes: 0 diff --git a/Assets/Prefabs/ObjImporter.prefab.meta b/Assets/Prefabs/ObjImporter.prefab.meta new file mode 100644 index 00000000..4ee63e84 --- /dev/null +++ b/Assets/Prefabs/ObjImporter.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 17813655602a70c46a78e7f4ec2e2b97 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 2aaa133f98cfeffe71889d4ba6b7484228fbc63b Mon Sep 17 00:00:00 2001 From: Mike van Riel Date: Mon, 7 Oct 2024 16:52:54 +0200 Subject: [PATCH 2/3] Refactor the positioning script to use coordinates fully, to ensure no issues arise from shifting. The transform position was used, but that can be awkward as soon as a shift occurs. Unfortunately that didn't fix the situation with the erroneous positioning. --- .../HierarchicalObjectLayerGameObject.cs | 89 +++++++++++-------- .../FloatingOrigin/Scripts/WorldTransform.cs | 14 +-- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/Assets/Scripts/Layers/LayerTypes/HierarchicalObjectLayerGameObject.cs b/Assets/Scripts/Layers/LayerTypes/HierarchicalObjectLayerGameObject.cs index cbf95a61..6ca327bf 100644 --- a/Assets/Scripts/Layers/LayerTypes/HierarchicalObjectLayerGameObject.cs +++ b/Assets/Scripts/Layers/LayerTypes/HierarchicalObjectLayerGameObject.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Netherlands3D.Coordinates; +using Netherlands3D.Twin.FloatingOrigin; using Netherlands3D.Twin.Layers.LayerTypes; using Netherlands3D.Twin.Layers.Properties; using Netherlands3D.Twin.Projects; @@ -11,22 +12,28 @@ namespace Netherlands3D.Twin.Layers { + [RequireComponent(typeof(WorldTransform))] public class HierarchicalObjectLayerGameObject : LayerGameObject, IPointerClickHandler, ILayerWithPropertyPanels, ILayerWithPropertyData { private ToggleScatterPropertySectionInstantiator toggleScatterPropertySectionInstantiator; [SerializeField] private UnityEvent objectCreated = new(); private List propertySections = new(); private TransformLayerPropertyData transformPropertyData; - private Vector3 previousPosition; + private Coordinate previousPosition; private Quaternion previousRotation; private Vector3 previousScale; + private WorldTransform worldTransform; LayerPropertyData ILayerWithPropertyData.PropertyData => transformPropertyData; protected void Awake() { - var coord = new Coordinate(transform.position); - transformPropertyData = new TransformLayerPropertyData(coord, transform.eulerAngles, transform.localScale); + worldTransform = GetComponent(); + transformPropertyData = new TransformLayerPropertyData( + worldTransform.Coordinate, + worldTransform.Rotation.eulerAngles, + transform.localScale + ); propertySections = GetComponents().ToList(); toggleScatterPropertySectionInstantiator = GetComponent(); @@ -47,8 +54,8 @@ protected override void OnDisable() protected override void Start() { base.Start(); - previousPosition = transform.position; - previousRotation = transform.rotation; + previousPosition = worldTransform.Coordinate; + previousRotation = worldTransform.Rotation; previousScale = transform.localScale; objectCreated.Invoke(gameObject); @@ -68,62 +75,72 @@ protected void OnDestroy() private void UpdatePosition(Coordinate newPosition) { - if (newPosition.ToUnity() != transform.position) - transform.position = newPosition.ToUnity(); + if (newPosition.ToUnity() == worldTransform.Coordinate.ToUnity()) return; + + worldTransform.Coordinate = newPosition; + transform.position = worldTransform.Coordinate.ToUnity(); } private void UpdateRotation(Vector3 newAngles) { - if (newAngles != transform.eulerAngles) - transform.eulerAngles = newAngles; + if (newAngles == transform.eulerAngles) return; + + worldTransform.Rotation = Quaternion.Euler(newAngles); + transform.rotation = worldTransform.Rotation; } private void UpdateScale(Vector3 newScale) { - if (newScale != transform.localScale) - transform.localScale = newScale; + if (newScale == transform.localScale) return; + + transform.localScale = newScale; } public virtual void LoadProperties(List properties) { - var transformProperty = (TransformLayerPropertyData)properties.FirstOrDefault(p => p is TransformLayerPropertyData); - if (transformProperty != null) + var transformProperty = properties.OfType().FirstOrDefault(); + if (transformProperty == default(TransformLayerPropertyData)) return; + + // unsubscribe events from previous property object, resubscribe to new object at the end of this if block + if (transformPropertyData != null) { - if (transformPropertyData != null) //unsubscribe events from previous property object, resubscribe to new object at the end of this if block - { - transformPropertyData.OnPositionChanged.RemoveListener(UpdatePosition); - transformPropertyData.OnRotationChanged.RemoveListener(UpdateRotation); - transformPropertyData.OnScaleChanged.RemoveListener(UpdateScale); - } - - this.transformPropertyData = transformProperty; //take existing TransformProperty to overwrite the unlinked one of this class - - UpdatePosition(this.transformPropertyData.Position); - UpdateRotation(this.transformPropertyData.EulerRotation); - UpdateScale(this.transformPropertyData.LocalScale); - - transformPropertyData.OnPositionChanged.AddListener(UpdatePosition); - transformPropertyData.OnRotationChanged.AddListener(UpdateRotation); - transformPropertyData.OnScaleChanged.AddListener(UpdateScale); + transformPropertyData.OnPositionChanged.RemoveListener(UpdatePosition); + transformPropertyData.OnRotationChanged.RemoveListener(UpdateRotation); + transformPropertyData.OnScaleChanged.RemoveListener(UpdateScale); } + + // take existing TransformProperty to overwrite the unlinked one of this class + this.transformPropertyData = transformProperty; + + UpdatePosition(this.transformPropertyData.Position); + UpdateRotation(this.transformPropertyData.EulerRotation); + UpdateScale(this.transformPropertyData.LocalScale); + + // Reset the previous[X] to prevent a reset of the + previousPosition = transformPropertyData.Position; + previousRotation = Quaternion.Euler(transformPropertyData.EulerRotation); + previousScale = transformPropertyData.LocalScale; + + transformPropertyData.OnPositionChanged.AddListener(UpdatePosition); + transformPropertyData.OnRotationChanged.AddListener(UpdateRotation); + transformPropertyData.OnScaleChanged.AddListener(UpdateScale); } private void Update() { // We cannot use transform.hasChanged, because this flag is not correctly set when adjusting this transform using runtimeTransformHandles, instead we have to compare the values directly // Check for position change - if (transform.position != previousPosition) + if (worldTransform.Coordinate.ToUnity() != previousPosition.ToUnity()) { - var rdCoordinate = new Coordinate(CoordinateSystem.Unity, transform.position.x, transform.position.y, transform.position.z); - transformPropertyData.Position = rdCoordinate; - previousPosition = transform.position; + transformPropertyData.Position = worldTransform.Coordinate; + previousPosition = worldTransform.Coordinate; } // Check for rotation change - if (transform.rotation != previousRotation) + if (worldTransform.Rotation != previousRotation) { - transformPropertyData.EulerRotation = transform.eulerAngles; - previousRotation = transform.rotation; + transformPropertyData.EulerRotation = worldTransform.Rotation.eulerAngles; + previousRotation = worldTransform.Rotation; } // Check for scale change diff --git a/Assets/_BuildingBlocks/FloatingOrigin/Scripts/WorldTransform.cs b/Assets/_BuildingBlocks/FloatingOrigin/Scripts/WorldTransform.cs index 6533d942..5b724fdc 100644 --- a/Assets/_BuildingBlocks/FloatingOrigin/Scripts/WorldTransform.cs +++ b/Assets/_BuildingBlocks/FloatingOrigin/Scripts/WorldTransform.cs @@ -8,15 +8,10 @@ public class WorldTransform : MonoBehaviour, IHasCoordinate { [SerializeField] private WorldTransformShifter worldTransformShifter; [SerializeField] private CoordinateSystem referenceCoordinateSystem = CoordinateSystem.RDNAP; - public Coordinate Coordinate { - get; - set; - } - public Quaternion Rotation - { - get; - set; - } + + public Coordinate Coordinate { get; set; } = new(CoordinateSystem.RDNAP); + + public Quaternion Rotation { get; set; } = Quaternion.identity; public CoordinateSystem ReferenceCoordinateSystem => referenceCoordinateSystem; public Origin Origin => Origin.current; @@ -56,7 +51,6 @@ private void OnEnable() { ShiftTo(Coordinate, Coordinate); } - } private void OnDisable() From c5ab67008e74e7184a65c1d699ddbfe3e19dd799 Mon Sep 17 00:00:00 2001 From: Mike van Riel Date: Tue, 8 Oct 2024 10:53:25 +0200 Subject: [PATCH 3/3] Make sure the position of an imported 3d model doesn't overwrite a position set through the loading of a project, or another external method --- .../Scripts/Layers/LayerTypes/ObjSpawner.cs | 21 ++++++++----------- Assets/Scripts/ObjectPlacementUtility.cs | 9 +++++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Assets/Scripts/Layers/LayerTypes/ObjSpawner.cs b/Assets/Scripts/Layers/LayerTypes/ObjSpawner.cs index 6e27d4bb..4cda2950 100644 --- a/Assets/Scripts/Layers/LayerTypes/ObjSpawner.cs +++ b/Assets/Scripts/Layers/LayerTypes/ObjSpawner.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -20,6 +21,11 @@ public class ObjSpawner : MonoBehaviour, ILayerWithPropertyData private ObjImporter.ObjImporter importer; + private void Awake() + { + gameObject.transform.position = ObjectPlacementUtility.GetSpawnPoint(); + } + private void Start() { StartImport(); @@ -68,8 +74,10 @@ private void ImportObj(string path) 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 returnedGameObject.transform.SetParent(this.transform, false); - AddLayerScriptToObj(returnedGameObject); + returnedGameObject.AddComponent(); DisposeImporter(); } @@ -78,16 +86,5 @@ private void DisposeImporter() { if (importer != null) Destroy(importer.gameObject); } - - private void AddLayerScriptToObj(GameObject parsedObj) - { - var spawnPoint = ObjectPlacementUtility.GetSpawnPoint(); - - gameObject.transform.position = spawnPoint; - - parsedObj.AddComponent(); - - // CreatedMoveableGameObject.Invoke(parsedObj); - } } } \ No newline at end of file diff --git a/Assets/Scripts/ObjectPlacementUtility.cs b/Assets/Scripts/ObjectPlacementUtility.cs index 7c299c1f..45834ff8 100644 --- a/Assets/Scripts/ObjectPlacementUtility.cs +++ b/Assets/Scripts/ObjectPlacementUtility.cs @@ -7,14 +7,17 @@ public static class ObjectPlacementUtility public static Vector3 GetSpawnPoint() { var camera = Camera.main; - var ray = camera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2)); + var cameraTransform = camera.transform; + + var ray = camera.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f)); var plane = new Plane(Vector3.up, 0); var intersect = plane.Raycast(ray, out float distance); if (!intersect) + { distance = 10f; + } - var spawnPoint = camera.transform.position + camera.transform.forward * distance; - return spawnPoint; + return cameraTransform.position + cameraTransform.forward * distance; } } }