Planetside Software Forums

General => Terragen Discussion => Topic started by: Aerometrex on October 28, 2012, 08:40:43 PM

Title: 3D stereoscopic camera for TG
Post by: Aerometrex on October 28, 2012, 08:40:43 PM
Hi all,

After struggling to make good 3D stereoscopic animations in TG, I wanted to share with the community the script we developed.
We came up with a python script to generate a Stereo camera based on the position and rotation of the first camera and the 1/30th eye separation rule.
This is still a work in progress and at this stage, the z rotation of the main camera is not taken into account. So if you use this script, avoid rotating your camera using z axis.

To run the script, you will need to install Python 2.7 and vpython:
http://www.lfd.uci.edu/~gohlke/pythonlibs/ (http://www.lfd.uci.edu/~gohlke/pythonlibs/)

this is how it works:

copy the code below into a file called stereo.py

create a text file with your zero-paralax heights (this is the location right in the middle of your camera frame where you want your terrain to be right on the screen) . One height per keyframe.

for example if you have a 200 frames animation with 4 key-frames at 0, 50, 150 and 200, your file will look like:

35
35
35
35 (make sure there is no other caracter after the last number).

with 35m being the projection plane altitude at the center of your frame. this value will be probably different for at each key-frame, just check the altitude of your center point.


The script will create a new project file with a second camera called "Stereo Camera".
I've used the 1/30th rule to create the stereo camera location and rotation.
http://www.dashwood3d.com/blog/beginners-guide-to-shooting-stereoscopic-3d/ (http://www.dashwood3d.com/blog/beginners-guide-to-shooting-stereoscopic-3d/)

to run the script, open a cmd windows and use the following command line:

c:\python27\python [script folder\]stereo.py [input TGD project] [output TGD project name] [focal-height text file]

Have fun!

check out our Youtube channel, I will upload one of our 3D stereo animation very soon.
http://www.youtube.com/user/Aerometrex/ (http://www.youtube.com/user/Aerometrex/)



'''
Created on 03/09/2012

Parse TGD XML file and add second camera, offsetting and rotating first camera

@author: Tisham- Aerometrex
'''

from visual import *
import codecs
import xml.dom.minidom as mdom
import sys

infile = sys.argv[1]
outfile = sys.argv[2]
focal_heights = sys.argv[3]

focals = map(lambda x : float(x), file(focal_heights).readlines())
doc = mdom.parse(infile)
camera_node = doc.getElementsByTagName("camera")[0]
anim_datas = camera_node.getElementsByTagName("animationData")

camera_data = {"position_0":list(),
               "position_1":list(),
               "position_2":list(),
               "rotation_0":list(),
               "rotation_1":list(),
               "rotation_2":list(),
               "motion_blur_length_0":list()}


for anim_data in anim_datas:
    pa = anim_data.getAttribute("param")
    index = anim_data.getAttribute("componentIndex")
   
    dict_key = pa+"_"+index
   
    keys = anim_data.getElementsByTagName("key")
    for key in keys:
        camera_data[dict_key].append(float(key.getAttribute("value")))

num_keys = len(camera_data['position_0'])

if (len(focals) != num_keys):
    print "Need matching",len(focals),"!=",num_keys,"focal heights"

print "Offsetting",num_keys,"Key Frames"



for i in range(num_keys):
    x = camera_data["position_0"][i]
    y = camera_data["position_1"][i]
    z = camera_data["position_2"][i]
    o = camera_data["rotation_0"][i]
    t = camera_data["rotation_1"][i]
    k = camera_data["rotation_2"][i]
   
    eye_sep = (y-focals[i])/(cos(radians(90+o))*30)
    v = vector(eye_sep,0,0)
   
    print "Key Frame:",i,"Magic var:",eye_sep*30,"Eye sep:",eye_sep
   
    pos = vector(x,y,z)
    offset = v.rotate(radians(o),vector(1,0,0)).rotate(radians(t),vector(0,1,0))
    pos = pos+offset
    camera_data["position_0"][i] = pos.x
    camera_data["position_1"][i] = pos.y
    camera_data["position_2"][i] = pos.z
   

camera_copy_node = camera_node.cloneNode(True)
camera_copy_node.setAttribute("name","Stereo Camera")

copy_anim_datas = camera_copy_node.getElementsByTagName("animationData")

for anim_data in copy_anim_datas:
    pa = anim_data.getAttribute("param")
    index = anim_data.getAttribute("componentIndex")
   
    dict_key = pa+"_"+index
   
    keys = anim_data.getElementsByTagName("key")
    if pa=="position":
        for i in range(num_keys):
            keys[i].setAttribute("value",str(camera_data[dict_key][i]))


doc.childNodes[0].appendChild(camera_copy_node)


with codecs.open(outfile, "w", "utf-8") as out:
    doc.writexml(out)
Title: Re: 3D stereoscopic camera for TG
Post by: Henry Blewer on October 28, 2012, 09:44:23 PM
This is cool, I just wish I could see in 3D. Thanks for sharing!
Title: Re: 3D stereoscopic camera for TG
Post by: Aerometrex on October 29, 2012, 08:51:51 PM
I've just uploaded a 3D video using this script on Youtube:
http://youtu.be/9t9dgEbGeUg
Title: Re: 3D stereoscopic camera for TG
Post by: Bjur on October 29, 2012, 11:07:55 PM
It´s looking fine!  8)
Title: Re: 3D stereoscopic camera for TG
Post by: Henry Blewer on October 30, 2012, 09:12:16 AM
Love it. You are also teasing me :)  I shared it on Facebook.
Title: Re: 3D stereoscopic camera for TG
Post by: Dune on October 31, 2012, 03:32:56 AM
How would you need to look at this; with red/green spectacles?
Title: Re: 3D stereoscopic camera for TG
Post by: Bjur on October 31, 2012, 01:52:29 PM
It´s your choice Dune.

In YouTube you can switch between several kinds of 3D display modes like red/blue, green/magenta, SBS etc.. (check 3D button).

I watched it with an old classic red/blue plastic glasses.   
Title: Re: 3D stereoscopic camera for TG
Post by: Aerometrex on October 31, 2012, 07:08:34 PM
I did this animation to use on a large 3D TV for a presentation. With red/blue glasses it doesn't really look impressive but using a 3D monitor or TV and polarized glasses, you will get all the magic of 3D stereoscopy. I guess these 3D devices will be more common and affordable in the near future.