Search Unity

Why does clone have a different position and orientation than my default in game object?

Discussion in 'General Graphics' started by ambareeshsrja16, Jul 16, 2019.

  1. ambareeshsrja16

    ambareeshsrja16

    Joined:
    Jun 26, 2019
    Posts:
    12
    I am importing my own 3D mesh (a ply file converted to a .obj and imported to Unity) and using it to render an image in Unity. I have added the object to prefab and I'm accessing it during rendering (Code is attached at the end)

    While rendering I'm noticing that there are two objects - Clone and default (which have different orientations, positions, and scale). The Clone seems to have the positions, orientations, scale, etc I'm setting from my script, but the one that is getting rendered is the default one. I can see this when I select the objects and observing the co-ordinate frames. Adding pictures for reference.
    clone.PNG default.PNG


    Why are there two objects, and how do I get the correct one to render?

    As an experiment I tried changing the properties of the default to match the ones of the clone, (so I thought if I match them, the default one which is rendering would come to the pos and orientation that I want), but when I did that the default went completely out of the frame to a different pos altogether, so I am suspecting they are on different coordinate frames altogether)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SceneController : MonoBehaviour
    6. {
    7.     public ImageSynthesis synth;
    8.     public GameObject[] prefabs;
    9.     public int num_Objects = 2;
    10.  
    11.     public int trainingImages;
    12.     public int valImages;
    13.  
    14.     public bool grayscale = false;
    15.     public bool save = false;
    16.  
    17.     private ShapePool pool;
    18.  
    19.     private int frameCount = 0;
    20.  
    21.     // Start is called before the first frame update
    22.     void Start()
    23.     {
    24.         pool = ShapePool.Create(prefabs);
    25.     }
    26.  
    27.     // Update is called once per frame
    28.     void Update()
    29.     {
    30.         if (frameCount < trainingImages + valImages) {
    31.  
    32.             GenerateRandom();
    33.             Debug.Log($"FrameCount: {frameCount}");
    34.             frameCount++;
    35.  
    36.             if (save)
    37.             {
    38.                 if (frameCount < trainingImages)
    39.                 {
    40.                     string filename = $"image_{frameCount.ToString().PadLeft(5, '0')}";
    41.                     synth.Save(filename, 1920, 1080, "captures/train", 2);
    42.                 }
    43.                 else if (frameCount < trainingImages + valImages)
    44.                 {
    45.                     int valFrameCount = frameCount - trainingImages;
    46.                     string filename = $"image_{valFrameCount.ToString().PadLeft(5, '0')}";
    47.                     synth.Save(filename,  1920, 1080, "captures/val", 2);
    48.                 }
    49.  
    50.             }
    51.  
    52.          
    53.         }
    54.     }
    55.  
    56.     void GenerateRandom()
    57.     {
    58.         pool.ReclaimAll();
    59.        
    60.                 //pick out prefab
    61.                 int prefabIndx = Random.Range(0, prefabs.Length);
    62.                 GameObject prefab = prefabs[prefabIndx];
    63.                
    64.                 //OBJECT 1
    65.                 /*
    66.                 DATA from Python script
    67.                 PSM_1 Orientation in quaternions  WXYZ [ 0.06844   0.458484 -0.60438   0.647945]
    68.                 PSM_1 Position in mm [14.620537  3.197186 64.227186
    69.                 */
    70.  
    71.                 //Position
    72.                 float newX, newY, newZ;
    73.                 newX = 14.620537f;
    74.                 newY = 3.197186f;
    75.                 newZ = 64.227186f;
    76.                 var newPos = new Vector3(newX, newY, newZ);
    77.  
    78.                 var shape = pool.Get((ShapeLabel)prefabIndx);
    79.                 var newObj = shape.obj;
    80.                 newObj.transform.position = newPos;
    81.  
    82.                 //Rotation
    83.                
    84.                 float quatX = 0.458484f;
    85.                 float quatY = -0.60438f;
    86.                 float quatZ = 0.647945f;
    87.                 float quatW = 0.06844f;
    88.                 newObj.transform.rotation = new Quaternion(quatX, quatY, quatZ, quatW);
    89.  
    90.                 //Scale
    91.                 float sx = 1.0f;
    92.                 Vector3 newScale = new Vector3(sx, sx, sx);
    93.                 newObj.transform.localScale = newScale;
    94.  
    95.                 // Color
    96.                 /*
    97.                 float newR, newG, newB;
    98.                 newR = Random.Range(0.0f, 1.0f);
    99.                 newG = Random.Range(0.0f, 1.0f);
    100.                 newB = Random.Range(0.0f, 1.0f);
    101.  
    102.                 var newColor = new Color(newR, newG, newB);
    103.                 newObj.GetComponent<Renderer>().material.color = newColor;
    104.                 */
    105.             }
    106.              
    107.         }
    108.             synth.OnSceneChange(grayscale);
    109.         }
    110.     }
    111.  
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,336
    A mesh renderer with no mesh filter doesn’t do anything, it’s basically a dummy component on a parent game object. The “default” is the actual mesh that’s being rendered.

    Usually the obj file format is used to hold a single mesh, and Unity’s importer is probably setup assuming that setup. However the format does support additional named objects, and it seems whatever method you used to convert your original ply file into an obj did so by putting all of the triangles in an object named “default” inside the obj file instead of leaving it in the root mesh. This is a little silly since AFAIK the ply format does not support multiple objects and is always a single mesh.

    The “default” object is however just a child of the main game object and thus will move and scale with the parent. The transform component will show values in it’s parent’s coordinate space. As for why it has been moved off of 0,0,0, rotated, and scaled, I can only guess that you accidentally modified the prefab or otherwise moved the child object after spawning it. The obj format does not support unique pivots per object and all are assumed to be in the same space.

    My suggestion would be to move the “default” object out by itself, rename it, and either save it as a new prefab to use.
     
  3. ambareeshsrja16

    ambareeshsrja16

    Joined:
    Jun 26, 2019
    Posts:
    12
    Thank you for the detailed answer, really appreciate it.

    "As for why it has been moved off of 0,0,0, rotated, and scaled, I can only guess that you accidentally modified the prefab or otherwise moved the child object after spawning it." I don't really remember doing it, but this was 2 weeks ago, when I literally had zero experience with Unity, and I must have done something silly.

    I converted .ply into .obj I guess using an online converter, which probably isn't the best way to do it. So what I am going to do now, is to convert it using Blender, and try a .fbx instead.

    P.S - Tried importing again, but again, somehow the child "default" is twisted by 90 degrees about X-axis of the parent. I ended up separating the child from the parent object and rendering it separately! Worked! Thank you!