psychopath/psychoblend/world.py
Nathan Vegdahl 1c801ee605 PsychoBlend: implement object and material export.
Material bindings don't work, since they're now on the objects
themselves rather than the instances, and I haven't updated
Psychopath itself for that yet.
2022-08-07 10:23:54 -07:00

118 lines
3.3 KiB
Python

import bpy
from math import degrees, tan, atan
from mathutils import Vector, Matrix
from .util import escape_name, mat2str, ExportCancelled
class World:
def __init__(self, render_engine, depsgraph):
scene = depsgraph.scene
self.background_shader = BackgroundShader(render_engine, scene.world)
def take_sample(self, render_engine, depsgraph, time):
if render_engine.test_break():
raise ExportCancelled()
self.background_shader.take_sample(render_engine, depsgraph, time)
def cleanup(self):
pass
def export(self, render_engine, w):
w.write("World {\n")
w.indent()
self.background_shader.export(render_engine, w)
w.unindent()
w.write("}\n")
class Camera:
def __init__(self, render_engine, ob, aspect_ratio):
self.ob = ob
self.aspect_ratio = aspect_ratio
self.fovs = []
self.aperture_radii = []
self.focal_distances = []
self.xforms = []
def take_sample(self, render_engine, depsgraph, time):
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.ob.name, time))
# Fov
self.fovs += [degrees(self.ob.data.angle_x)]
if self.ob.data.dof.use_dof:
# TODO
# # Aperture radius
# self.aperture_radii += [self.ob.data.psychopath.aperture_radius]
# Dof distance
if self.ob.data.dof_object == None:
self.focal_distances += [self.ob.data.dof_distance]
else:
# TODO: implement DoF object tracking here
self.focal_distances += [0.0]
print("WARNING: DoF object tracking not yet implemented.")
else:
self.aperture_radii += [0.0]
self.focal_distances += [1.0]
# Transform
mat = self.ob.matrix_world.copy()
matz = Matrix()
matz[2][2] = -1
self.xforms += [(mat @ matz).inverted()]
def cleanup(self):
pass
def export(self, render_engine, w):
render_engine.update_stats("", "Psychopath: Exporting %s" % self.ob.name)
w.write("Camera {\n")
w.indent()
for fov in self.fovs:
w.write("Fov [%f]\n" % fov)
for rad in self.aperture_radii:
w.write("ApertureRadius [%f]\n" % rad)
for dist in self.focal_distances:
w.write("FocalDistance [%f]\n" % dist)
for mat in self.xforms:
w.write("Transform [%s]\n" % mat2str(mat))
w.unindent()
w.write("}\n")
class BackgroundShader:
def __init__(self, render_engine, world):
self.world = world
self.color = []
def take_sample(self, render_engine, depsgraph, time):
if self.world != None:
self.color += [(
self.world.psychopath.background_color[0],
self.world.psychopath.background_color[1],
self.world.psychopath.background_color[2],
)]
def export(self, render_engine, w):
if self.world != None:
w.write("BackgroundShader {\n")
w.indent();
w.write("Type [Color]\n")
for c in self.color:
w.write("Color [rec709, %f %f %f]\n" % c)
w.unindent()
w.write("}\n")