;+ ; Creates a combined image from images from the left and right eyes where the ; left eye is "shaded" red and the right eye is "shaded" blue. ; ; @private ; @returns bytarr(3, xsize, ysize) ; @param left_image {in}{optional}{type=bytarr(3, xsize, ysize)} image from ; left eye ; @param right_image {in}{optional}{type=bytarr(3, xsize, ysize)} image from ; right eye ;- function mggr3dconverter::combineImages, left_image, right_image compile_opt strictarr ; define combined_image to the correct size combined_image = left_image * 0B dims = size(left_image, /dimensions) temp_left = byte(total(fix(left_image), 1) / 3) temp_right = byte(total(fix(right_image), 1) / 3) combined_image[0, 0, 0] = Reform(temp_left, 1, dims[1], dims[2]) combined_image[1, 0, 0] = Reform(temp_right, 1, dims[1], dims[2]) combined_image[2, 0, 0] = Reform(temp_right, 1, dims[1], dims[2]) return, combined_image end ;+ ; Rotates "top-level" models of the given picture by the given number of ; degrees about the y-axis. ; ; @private ; @param picture {in}{required}{type=obj ref} the view, viewgroup, or scene to ; be drawn ; @param degrees {in}{required}{type=float} number of degrees to rotate ; "top-level" models ;- pro mggr3dconverter::rotateModels, picture, degrees compile_opt strictarr ; if picture is a model then rotate it, but don't rotate models inside it if (obj_isa(picture, 'IDLgrModel')) then begin picture->rotate, [0, 1, 0], degrees return endif if (obj_isa(picture, 'IDL_Container')) then begin items = picture->get(/all, count=count) for i = 0L, count - 1 do begin self->rotateModels, items[i], degrees endfor endif end ;+ ; Converts a standard object graphics picture to a view containing a 3D image. ; ; @returns IDLgrView object reference ; @param opicture {in}{optional}{type=obj ref} the view, viewgroup, or scene to ; be drawn; if the GRAPHICS_TREE property is set to a valid picture, ; then this argument must not be given ;- function mggr3dconverter::convert, opicture ; rotate "top-level" models for left eye self->rotateModels, opicture, self.eye_separation / 2. ; draw picture to left eye buffer self.obuffer->draw, opicture ; get data out of left eye buffer oleft_image = self.obuffer->read() oleft_image->getProperty, data=left_image obj_destroy, oleft_image ; rotate "top-level" models for right eye self->rotateModels, opicture, - self.eye_separation ; draw picture to right eye buffer self.obuffer->draw, opicture ; get data out of left eye buffer oright_image = self.obuffer->read() oright_image->getProperty, data=right_image obj_destroy, oright_image ; rotate "top-level" models back to center self->rotateModels, opicture, self.eye_separation / 2. combined_image = self->combineImages(left_image, right_image) self.oimage->setProperty, data=combined_image return, self.oview end ;+ ; Get properties of the converter. ; ; @keyword eye_separation {out}{optional}{type=float} number of degrees of the ; cone formed by drawing lines from each eye to the origin ; @keyword dimensions {out}{optional}{type=intarr(2)} dimensions of the window ;- pro mggr3dconverter::getProperty, eye_separation=eye_separation, $ dimensions=dimensions compile_opt strictarr if (arg_present(eye_separation)) then begin eye_separation = self.eye_separation endif if (arg_present(dimensions)) then begin self.obuffer->getProperty, dimensions=dimensions endif end ;+ ; Set properties of the converter. ; ; @keyword eye_separation {in}{optional}{type=float} number of degrees of the ; cone formed by drawing lines from each eye to the origin ; @keyword dimensions {in}{optional}{type=intarr(2)} dimensions of the window ;- pro mggr3dconverter::setProperty, eye_separation=eye_separation, $ dimensions=dimensions compile_opt strictarr if (n_elements(eye_separation) gt 0) then begin self.eye_separation = eye_separation endif if (n_elements(dimensions) gt 0) then begin self.oview->setProperty, viewplace_rect=[0, 0, dimensions] self.obuffer->setProperty, dimensions=dimensions endif end ;+ ; Free resources. ;- pro mggr3dconverter::cleanup compile_opt strictarr obj_destroy, [self.oview, self.obuffer] end ;+ ; Initialize Window3D. ; ; @returns 1 for success, o/w for failure ; @keyword eye_separation {in}{optional}{type=float}{default=4.0} number of ; degrees of the cone formed by drawing lines from each eye to the ; origin ; @keyword dimensions {in}{required}{type=intarr(2)} dimensions of the window ; @keyword picture {out}{optional}{type=IDLgrView} view which will contain a 3D ; image; the same view is updated each time that "convert_3d_picture" ; method is called ; @keyword _extra {in}{optional}{type=keywords} keywords to IDLgrWindows "init" ; method are accepted ;- function mggr3dconverter::init, eye_separation=eye_separation, $ dimensions=dimensions, picture=picture, _extra=e compile_opt strictarr self.eye_separation = n_elements(eye_separation) eq 0 ? 4.0 : eye_separation self.obuffer = obj_new('IDLgrBuffer', dimensions=dimensions) self.oview = obj_new('IDLgrView', viewplane_rect=[0, 0, dimensions]) omodel = obj_new('IDLgrModel') self.oview->add, omodel self.oimage = obj_new('IDLgrImage') omodel->add, self.oimage return, 1 end ;+ ; Helper object to transform a normal object graphics scene to a 3d picture. ; ; @field eye_separation number of degrees of the cone formed by drawing lines ; from each eye to the origin ; @field obuffer IDLgrBuffer to send left and right eye images to and extract ; @field oview IDLgrView to contain the 3D image ; @field oimage IDLgrImage actually being displayed ; @author Michael Galloy ;- pro mggr3dconverter__define compile_opt strictarr define = { mggr3dconverter, $ eye_separation : 0.0, $ obuffer : obj_new(), $ oview : obj_new(), $ oimage : obj_new() $ } end