Convert a 3d point to 2d Screen Space in Maya

Convert a 3d point to 2d Screen Space in Maya

Very often you want to find the 2d coordinates on the screen for a given 3d point. Here’s a little mel script that knows the projection math and takes care of generating the data in a “raw channel text file” format. From here, it’s easy to generate just about any ascii file format that a compositing program might be expecting.

I’ve seen people rendering out small green tracking markers on their 3d objects to later track them in 2d to get approximately the same results. The computer can save you these steps and get you the exact result much quicker. To quote Homer Simpson, “Computer’s can do that!"




// Rob Bredow
// rob (at) 185vfx.com
// http://www.185vfx.com/
// Copyright 3/2002 Rob Bredow, All Rights Reserved
// 
// Converts currently selected point or object from 3d space to 
// screen space for use in a compositing package.
//
// Writes out "normalized" 2d coordinates so multiply the x by the
// width of your image and y by the height to get pixels
//
// Assumes your camera is called "cam_main"


// Get a matrix
proc matrix screenSpaceGetMatrix(string $attr){
  float $v[]=`getAttr $attr`;
  matrix $mat[4][4]=>;
 return $mat;
}

// Multiply the vector v by the 4x4 matrix m, this is probably
// already in mel but I cant find it.
proc vector screenSpaceVecMult(vector $v, matrix $m){
  matrix $v1[1][4]=>;
  matrix $v2[1][4]=$v1*$m;
  return >;
}

global proc int screenSpace()
{
  // get the currently selected point
  string $dumpList[] = `ls -sl`;
  int $argc = size($dumpList);

  if ($argc != 1)
  {
    confirmDialog -t "screenSpace Usage" -m "To use, select a point on a geometry or a single object to write";
    return -1;
  }
  
  string $dumpPt = $dumpList[0];

  // Make $dumpPt a unix friendly name
  string $name = $dumpPt;
  while ( match("\\[",$name) != "" ) {
    $name = `substitute "\\[" $name "_"`;
  }
  while ( match("\\]",$name) != "" ) {
    $name = `substitute "\\]" $name ""`;
  }
  while ( match("\\.",$name) != "" ) {
    $name = `substitute "\\." $name "_"`;
  }

  // Find the frame range
  float $fs = `playbackOptions -q -min`;
  float $fe = `playbackOptions -q -max`;
  string $verify = "Will create " + $name + "_screenSpace.cmp\n" +
                   "For the frame range of " + $fs + "-" + $fe + "\n" +
                   "The camera used will be cam_main\n";
 
  if (`confirmDialog -t "screenSpace Verify" -m $verify -b "Dump" -b "Cancel"` == "Cancel")
    return -2;

  print ("Dumping selection...\n");

  string $pointWsFile = $name+"_screenSpace.cmp";
  int $outFileId = fopen($pointWsFile,"w");

  if ($outFileId == 0) {
    print ("Could not open output file " + $pointWsFile);
    return -1;
  }

  string $line;

  int $f;
  float $tx[],$ty[],$tz[];
  for ($f=$fs;$f>;

    // Grab the worldInverseMatrix from cam_main
    matrix $cam_mat[4][4] = screenSpaceGetMatrix("cam_main.worldInverseMatrix");

    // Multiply the point by that matrix
    vector $ptVecCs = screenSpaceVecMult($ptVecWs,$cam_mat);

    // Adjust the point's position for the camera perspective
    float $hfv = `camera -q -hfv cam_main`;
    float $ptx = (($ptVecCs.x/(-$ptVecCs.z))/tand($hfv/2))/2.0+.5;
    float $vfv = `camera -q -vfv cam_main`;
    float $pty = (($ptVecCs.y/(-$ptVecCs.z))/tand($vfv/2))/2.0+.5;

    float $ptz = $ptVecCs.z;

    $line = $ptx + " " + $pty + " " + "\n";
    fprint $outFileId $line; 
  }
 
  fclose $outFileId;

  return 1;
}

Here’s an alternative version submitted by Andrew Roberts that looks to be more complete in every way. It builds a simple interface for the user and handles non-square pixels (NTSC) accurately.

Renderman on Film: With Examples from Stuart Little
Newer post

From Mocap To Movie

From Mocap To Movie

This sounds fun, are you hiring?

Yes! We are almost always hiring at ILM. Check ILM.com/careers for the latest info and browse the posted positions in our studios around the world.

Can I send you a Star Wars idea or a script?

Unfortunately no. As an employee of Lucasfilm I cannot receive unsolicated pitches.

I'd like to study to work in the entertainment industry, what roles should I consider?

Check out Get In the Door for interviews with a number of people in a wide variety of positions at Lucasfilm and Industrial Light & Magic. I think you may find someone there who inspires you.

How can I contribute to software used by the entertainment industry?

The Academy Software Foundation is an open source, non-profit organization dedicated to getting people involved in a healthy software ecosytem for filmmaking, many of our projects focus on visual-effects and animation. I recommend checking out ASWF.io to learn more and get involved as it's a great way to meet people working in the industry and find a passion project to contribute to.