]> git.tdb.fi Git - libs/gl.git/blob - blender/io_mspgl/export_scene.py
Support multiple lights in a single pass
[libs/gl.git] / blender / io_mspgl / export_scene.py
1 import math
2 import os
3
4 class SceneExporter:
5         def __init__(self):
6                 self.selected_only = False
7                 self.visible_only = True
8                 self.collection = True
9                 self.skip_existing = True
10
11         def export_to_file(self, context, out_fn):
12                 from .util import Progress
13                 progress = Progress(context)
14
15                 from .scene import create_scene_from_current
16                 scene = create_scene_from_current(context, selected_only=self.selected_only, visible_only=self.visible_only)
17
18                 resources = {}
19                 self.export_scene_resources(context, scene, resources, progress)
20                 scene_res = self.export_scene(scene, resources)
21                 progress.set_progress(1.0)
22
23                 path, base = os.path.split(out_fn)
24                 base, ext = os.path.splitext(base)
25
26                 if self.collection:
27                         existing = None
28                         if self.skip_existing:
29                                 existing = lambda r: not os.path.exists(os.path.join(path, r.name))
30                         scene_res.write_collection(out_fn, filter=existing)
31                 else:
32                         scene_res.write_to_file(out_fn)
33                         for r in scene_res.collect_references():
34                                 r.write_to_file(os.path.join(path, r.name))
35
36         def export_scene_resources(self, context, scene, resources, progress):
37                 from .export import DataExporter
38                 data_exporter = DataExporter()
39
40                 data_exporter.export_resources(context, scene.prototypes, resources, None, progress)
41
42         def export_scene(self, scene, resources):
43                 from .datafile import Resource, Statement, Token
44                 scene_res = Resource(scene.name+".scene", "scene")
45
46                 scene_res.statements.append(Statement("type", Token(scene.scene_type.lower())))
47
48                 for i in scene.instances:
49                         obj_res = resources[i.prototype+".object"]
50                         st = scene_res.create_reference_statement("object", obj_res, i.name)
51
52                         ss = Statement("transform")
53
54                         loc = i.matrix_world.to_translation()
55                         ss.sub.append(Statement("position", *tuple(loc)))
56
57                         quat = i.matrix_world.to_quaternion()
58                         if i.rotation_mode in ('XYZ', 'XZY', 'YXZ', 'YZX', 'ZXY', 'ZYX'):
59                                 angles = [a*180/math.pi for a in quat.to_euler()]
60                                 ss.sub.append(Statement("euler", *angles));
61                         else:
62                                 ss.sub.append(Statement("rotation", quat.angle*180/math.pi, *tuple(quat.axis)))
63
64                         scale = i.matrix_world.to_scale()
65                         ss.sub.append(Statement("scale", *tuple(scale)))
66
67                         st.sub.append(ss)
68                         scene_res.statements.append(st)
69
70                 return scene_res
71
72         def export_sequence_resources(self, scene, resources):
73                 from .datafile import Resource, Statement, Token
74
75                 if scene.background_set:
76                         wrapper_name = scene.name+".wrapper.scene"
77                         if wrapper_name not in resources:
78                                 wrapper_res = Resource(wrapper_name, "scene")
79                                 wrapper_res.statements.append(Statement("type", Token("ordered")))
80                                 for s in scene.get_chain():
81                                         wrapper_res.statements.append(wrapper_res.create_reference_statement("scene", resources[s.name+".scene"]))
82
83                                 resources[wrapper_name] = wrapper_res
84
85                 lights = []
86                 s = scene
87                 while s:
88                         lights += s.lights
89                         s = s.background_set
90
91                 from .util import make_unique
92                 lights = make_unique(lights)
93
94                 from .export_light import LightExporter
95                 light_exporter = LightExporter()
96                 for l in lights:
97                         light_name = l.name+".light"
98                         if light_name not in resources:
99                                 resources[light_name] = light_exporter.export_light(l)
100
101                 lighting_name = scene.name+".lightn"
102                 if lighting_name not in resources:
103                         lighting_res = Resource(lighting_name, "lighting")
104                         lighting_res.statements.append(Statement("ambient", *tuple(scene.ambient_light)))
105                         for l in lights:
106                                 lighting_res.statements.append(lighting_res.create_reference_statement("light", resources[l.name+".light"]))
107
108                         resources[lighting_name] = lighting_res
109
110         def export_sequence(self, scene, resources):
111                 from .datafile import Resource, Statement, Token
112                 seq_res = Resource(scene.name+".seq", "sequence")
113
114                 if scene.use_hdr:
115                         seq_res.statements.append(Statement("hdr", True))
116
117                 content = scene
118                 if scene.background_set:
119                         content = resources[scene.name+".wrapper.scene"]
120
121                 ss = Statement("clear")
122                 ss.sub.append(Statement("color", 0.0, 0.0, 0.0, 0.0))
123                 ss.sub.append(Statement("depth", 1.0))
124                 seq_res.statements.append(ss)
125
126                 ss = Statement("step", "", "content")
127                 ss.sub.append(Statement("depth_test", Token("LEQUAL")))
128                 ss.sub.append(seq_res.create_reference_statement("lighting", resources[scene.name+".lightn"]))
129                 ss.sub.append(seq_res.create_reference_statement("scene", content))
130                 seq_res.statements.append(ss)
131
132                 if scene.use_ao:
133                         ss = Statement("ambient_occlusion")
134                         ss.sub.append(Statement("occlusion_radius", scene.ao_distance))
135                         ss.sub.append(Statement("samples", scene.ao_samples))
136                         seq_res.statements.append(ss)
137
138                 if scene.use_hdr:
139                         seq_res.statements.append(Statement("bloom"))
140                         ss = Statement("colorcurve")
141                         ss.sub.append(Statement("exposure_adjust", scene.exposure))
142                         ss.sub.append(Statement("srgb"))
143                         seq_res.statements.append(ss)
144                 else:
145                         # Add a colorcurve with linear response to convert into sRGB color space
146                         ss = Statement("colorcurve")
147                         ss.sub.append(Statement("brightness_response", 1.0))
148                         ss.sub.append(Statement("srgb"))
149                         seq_res.statements.append(ss)
150
151                 return seq_res