2017-10-03 6 views
0

J'ai deux objets identiques et deux caméras. Ce que je voudrais obtenir est la suivante:Position de capture et rotation d'un objet par rapport à un autre objet

1) Capturer la position et la rotation du cube A par rapport à la caméra A

2) Transfert à un cube que B, de sorte que dans l'appareil photo B (que je ne peut pas se déplacer), Cube B ressemble exactement comme Cube A regarde dans la caméra Un

j'ai réussi le faire avec la position avec le code suivant:

positionDifference = CubeA.InverseTransformPoint(CameraA.transform.position); 

Pour le transférer sur Cube B, je fais:

cubeBpos = transform.InverseTransformPoint(CubeB.transform.localPosition);  

while (Mathf.Abs (cubeBpos.x + positionDifference.x) > 0.01f) { 
    if (cubeBpos.x + positionDifference.x > 0) { 
     CubeB.transform.position += new Vector3(-0.01f, 0, 0); 
    } 
    else if (cubeBpos.x + positionDifference.x < 0) { 
     CubeB.transform.position += new Vector3(+0.01f, 0, 0); 
    } 
    cubeBpos = transform.InverseTransformPoint(CubeB.transform.position); 
} 

C'est maladroit, mais cela fonctionne. Cependant, lorsque j'essaie de transférer des rotations, le cube B commence à pivoter autour de l'origine. Fait intéressant, lorsque je déplace le cube A en coordonnées mondiales, le cube B se déplace en local, et vice versa. Je suppose que la traduction de coordonnées de local à monde est un problème, mais je pense aussi que mon code de rotation est naïf. J'ai essayé de capturer la rotation de deux manières, d'abord comme ceci:

rotationDifference = Quaternion.Inverse(CubeA.transform.rotation) * CameraA.transform.rotation; 

CubeB.transform.rotation = Quaternion.Inverse(rotationDifference); 

Deuxième tentative:

rotationDifference = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z); 

CubeB.transform.eulerAngles = rotationDifference; 

Les deux approches ont donné lieu à des décalages de rotation étranges. J'ai essayé d'utiliser localPosition et localEulerAngles, n'a pas aidé.

J'espère qu'il ya une façon plus intelligente de le faire :)

EDIT: Voici un Dropbox link au projet

Répondre

0

Le problème est que vous traitez la position et la rotation séparément bien qu'ils influencent chaque autre. Mettons les deux ensemble et disons que nous avons des transformations de modèles pour les deux caméras et les deux cubes (représentés comme des matrices homogènes, en supposant des vecteurs de colonne). Ensuite, nous voulons trouver le Transform cube B TCubeB, tel que:

TCameraA^-1 * TCubeA = TCameraB^-1 * TCubeB 

Notez que TCamera est le modèle de transformation de la caméra, et non pas la matrice de vue. Si vous avez la matrice de vue, laissez simplement l'inverse.

Nous pouvons résoudre immédiatement pour TCubeB:

TCameraB * TCameraA^-1 * TCubeA = TCubeB 

Je ne suis pas trop familier avec l'API Unity mais il semble que vous ne pouvez pas utiliser des matrices de transformation directement. Donc, nous allons diviser la matrice de transformation T dans une partie de rotation R et une partie de la traduction Tr:

TrCameraB * RCameraB * (TrCameraA * RCameraA)^-1 * TrCubeA * RCubeA = TrCubeB * RCubeB 
TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA = TrCubeB * RCubeB 

Si nous nous soucions seulement la rotation, on peut calculer le quaternion respectif en faisant simplement:

QCameraB * QCameraA^-1 * QCubeA = QCubeB 

La traduction devient un peu plus difficile.Nous devons trouver la traduction de transformation, de sorte que

TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA * RCubeB^-1 = TrCubeB 

Pour trouver le vecteur de translation, il suffit de multiplier l'origine sur le côté gauche:

TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA * RCubeB^-1 * (0, 0, 0, 1) 

En pseudo-code, cela se résume à (les matrices qui apparaissent représentent les vecteurs de la traduction):

Vector4 translation = (0, 0, 0, 1) 
translation += TrCubeA 
translation -= TrCameraA 
translation = RCameraA.Inverse().Transform(translation) 
translation = RCameraB.Transform(translation) 
translation += TrCameraB 

Encore une fois, je connais à peine l'API Unity et il peut utiliser des différentes conventions que moi (conventions en Transforma les mathématiques sont particulièrement délicates). Mais je suis sûr que vous pouvez adapter les dérivations ci-dessus si quelque chose n'est pas correct.

+0

Merci beaucoup Nico! Je ne savais pas comment l'adapter à l'unité, mais j'ai fini avec cela, il fait ce que je voulais: \t \t 'traduction Vector3 = new Vector3 (0,0,0),' ' \t \t Traduction + = cubeA.transform.position; '' \t \t traduction - = cameraA.transform.position; '' \t \t traduction = cameraA.transform.InverseTransformPoint (traduction); '' \t \t traduction = cameraB.transform.TransformPoint (traduction/2); ' \t \t' cubeB.transform.position = traduction; ' \t rotation \t 'Quaternion = Quaternion.identity,' ' \t \t rotation = Quaternion.Inverse (cameraA.transform.rotation)' ' \t \t cubeB.transform.rotation = rotation;' –

0

Nico grande réponse résolu mon problème, mais étant donné que le code de formatage dans la section commentaire n'a pas été construit pour cela, voici le code que j'ai écrit pour l'unité basée sur la réponse de Nico:

Vector3 translation = new Vector3(0,0,0); 
    translation += cubeA.transform.position; 
    translation -= cameraA.transform.position; 
    translation = cameraA.transform.InverseTransformPoint(translation); 
    translation = cameraB.transform.TransformPoint(translation/2); 

    cubeB.transform.position = translation; 

    Quaternion rotation = Quaternion.identity; 
    rotation = cameraB.transform.rotation * Quaternion.Inverse(cameraA.transform.rotation) * cubeA.transform.rotation; 

    cubeB.transform.rotation = rotation; 

Ce n'est pas un -to-one, mais il réalise ce que j'espérais: Si le cube A est stationnaire et que la caméra A se déplace, alors le cube B se déplace par rapport à la caméra B de telle manière que le cube A et le cube B ont toujours exactement la même position. rotation par rapport à leurs caméras respectives.

+0

Je pense que vous devez supprimer la ligne 'translation - = cameraA.transform.position' puisque cela fait déjà partie de l'inverse suivant. Peut-être que c'est la raison pour laquelle vous avez 'translation/2' dans la dernière ligne? A l'air correct, sinon. Vous êtes les bienvenus. –