How to stitch together scenes in 3D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lacethespace

I’m trying to proceduraly stitch together a level from multiple rooms. Each room has several entrances that can be placed on walls, floor or ceiling. When two rooms are stitched together, their entrances have to align perfectly, both in position and in orientation.

Entrances are marked with invisible markers that are inside the room scene. They are positioned and rotated so that +Y is up and +Z points outward from the room. I place the room1 at world origin, and then I want to use GDScript to modify orientation and position of room2, so that marker1 and marker2 are perfectly aligned.

world Node
    room1  Spatial
        marker1  Spatial
    room2  Spatial
        marker2  Spatial

The tricky part is that marker2 is child of room2, and I need to manipulate room2 in order to align markers 1 and 2. It would make sense for marker to be a parent of room, but then I would only have one marker per room.

These transitions through coordinate systems are giving me a headache. Please help.

Edited heavily for clarity.

:bust_in_silhouette: Reply From: lacethespace

I worked out how to reliably do it, so I’m documenting the solution here. After it is executed, the room2 is placed so that markers are perfectly aligned in both position and orientation. Both rooms need to be present in world before function is executed, otherwise to_global() function won’t give correct position.

func stitch_rooms(room2, room2_marker, room1, room1_marker):
    room2.transform.basis =  room1.transform.basis * room1_marker.transform.basis * room2_marker.transform.basis.inverse().rotated(Vector3(0,1,0), PI)
    room2.transform.origin += room1_marker.to_global(Vector3(0,0,0)) - room2_marker.to_global(Vector3(0,0,0))

First step is setting room2’s orientation, so that it is aligned with marker1 but rotated by 180deg. Transformations are:

  • Compensate for any rotation of room1 by orienting room2 to same direction
  • If marker1 has different orientation than room1, apply that orientation as well
  • The marker2 is inside the room2, so it’s orientation is inversed to compensate for it’s orientation
  • Rotate by 180deg around Y axis so that room2 extends out of room1 instead of overlapping it

Once the orientation is correct, markers 1 and 2 need to be placed at same spot in space. There are probably better solutions, but this works. Take global position of marker1 and marker2, subtract them to get translation vector, and apply that vector to room2 position.

This function should work for any prior orientation of objects and markers. It is useful for stitching scenes in procedural 3D world, and also for modular systems where parts are to be placed in slots. It would work for placing gems on swords, for constructing buildings out of blocks, for modular vehicles and other similar stuff. I hope it’s useful to someone.