if "bpy" in locals():
import imp
- for sub in "armature", "export_armature", "export_mesh", "export_object", "mesh", "outfile", "properties", "util":
+ for sub in "armature", "export_armature", "export_mesh", "export_object", "export_scene", "mesh", "outfile", "properties", "util":
if sub in locals():
imp.reload(locals()[sub])
filename_ext = ".object"
- external_tech = bpy.props.BoolProperty(name="External technique", description="Use an external technique specified in the object", default=True)
+ external_tech = bpy.props.BoolProperty(name="External technique", description="Use an external technique specified in the object's properties", default=True)
textures = bpy.props.EnumProperty(name="Textures", description="Export textures", default="REF",
items=(("NONE", "None", "Ignore textures"),
from .export_armature import ArmatureExporter
return ArmatureExporter()
+class ExportMspGLScene(bpy.types.Operator, ExportMspGLBase):
+ bl_idname = "export.mspgl_scene"
+ bl_label = "Export Msp GL scene"
+
+ filename_ext = ".scene"
+
+ external_tech = bpy.props.BoolProperty(name="External techniques", description="Use external techniques specified in objects' properties", default=True)
+ resource_collection = bpy.props.BoolProperty(name="Resource collection", description="Put resources to a single collection file", default=True)
+
+ def create_exporter(self):
+ from .export_scene import SceneExporter
+ return SceneExporter()
+
+ def draw(self, context):
+ col = self.layout.column()
+ col.prop(self, "resource_collection")
+
def menu_func_export(self, context):
self.layout.operator(ExportMspGLMesh.bl_idname, text="Msp GL mesh")
self.layout.operator(ExportMspGLObject.bl_idname, text="Msp GL object")
self.layout.operator(ExportMspGLArmature.bl_idname, text="Msp GL armature")
+ self.layout.operator(ExportMspGLScene.bl_idname, text="Msp GL scene")
from .properties import MspGLProperties
return strips, loose
- def export(self, context, out_file):
+ def export(self, context, out_file, objs=None):
if self.compound:
- objs = context.selected_objects
+ if objs is None:
+ objs = context.selected_objects
check = objs
while check:
children = []
children.append(c)
objs += children
check = children
- else:
+ elif objs is None:
objs = [context.active_object]
if not objs:
self.external_tech = True
self.shared_tech = True
- def export(self, context, out_file):
- obj = context.active_object
+ def export(self, context, out_file, objs=None):
+ if objs is None:
+ obj = context.active_object
+ else:
+ obj = objs[0]
from .outfile import open_output
out_file = open_output(out_file)
path, base = os.path.split(out_file.filename)
base, ext = os.path.splitext(base)
mesh_out = open_output(os.path.join(path, base+".mesh"))
- mesh = mesh_export.export(context, mesh_out)
+ mesh = mesh_export.export(context, mesh_out, objs)
out_file.write("mesh", '"{}.mesh"'.format(base))
else:
out_file.begin("mesh")
- mesh = mesh_export.export(context, out_file)
+ mesh = mesh_export.export(context, out_file, objs)
out_file.end()
if self.external_tech and obj.technique:
--- /dev/null
+import math
+import os
+from .export_object import ObjectExporter
+from .outfile import OutFile
+
+class SceneExporter:
+ def __init__(self):
+ self.external_tech = True
+ self.resource_collection = True
+
+ def export(self, context, out_file):
+ objs = context.selected_objects
+ objs = [o for o in objs if o.type=="MESH" and (not o.compound or o.parent not in objs)]
+
+ from .outfile import open_output
+ out_file = open_output(out_file)
+
+ path, base = os.path.split(out_file.filename)
+ base, ext = os.path.splitext(base)
+
+ object_export = ObjectExporter()
+ object_export.compound = True
+ object_export.external_tech = self.external_tech
+
+ if self.resource_collection:
+ res_out = open_output(os.path.join(path, base+"_resources.mdc"))
+
+ # TODO Export techniques as separate items in the collection
+ for o in objs:
+ res_out.begin("object", '"{}.object"'.format(o.name))
+ object_export.export(context, res_out, [o])
+ res_out.end()
+ else:
+ object_export.separate_tech = True
+ res_dir = os.path.join(path, base+"_resources")
+ if not os.path.exists(res_dir):
+ os.makedirs(res_dir)
+ for o in objs:
+ obj_out = open_output(os.path.join(res_dir, o.name+".object"))
+ object_export.export(context, obj_out, [o])
+
+ for o in objs:
+ out_file.begin("object", '"{}.object"'.format(o.name))
+ # XXX Parent relationships screw up the location and rotation
+ out_file.write("position", o.location[0], o.location[1], o.location[2])
+ if o.rotation_mode=="AXIS_ANGLE":
+ angle = o.rotation_axis_angle[0]
+ axis = o.rotation_axis_angle[1:]
+ else:
+ if o.rotation_mode=="QUATERNION":
+ q = o.rotation_quaternion
+ else:
+ q = o.rotation_euler.to_quaternion()
+ angle = q.angle
+ axis = q.axis
+ out_file.write("rotation", angle*180/math.pi, axis[0], axis[1], axis[2])
+ out_file.end();
renderer.add_shader_data(*shdata);
}
+
+AnimatedObject::Loader::Loader(AnimatedObject &o):
+ DataFile::ObjectLoader<AnimatedObject>(o)
+{
+ add("position", &Loader::position);
+ add("rotation", &Loader::rotation);
+ add("scale", &Loader::scale);
+ add("scale", &Loader::scale_uniform);
+}
+
+void AnimatedObject::Loader::position(float x, float y, float z)
+{
+ obj.matrix.translate(x, y, z);
+}
+
+void AnimatedObject::Loader::rotation(float a, float x, float y, float z)
+{
+ obj.matrix.rotate_deg(a, x, y, z);
+}
+
+void AnimatedObject::Loader::scale(float x, float y, float z)
+{
+ obj.matrix.scale(x, y, z);
+}
+
+void AnimatedObject::Loader::scale_uniform(float s)
+{
+ obj.matrix.scale(s);
+}
+
} // namespace GL
} // namespace Msp
#define MSP_GL_ANIMATEDOBJECT_H_
#include <vector>
+#include <msp/datafile/objectloader.h>
#include "matrix.h"
#include "objectinstance.h"
*/
class AnimatedObject: public ObjectInstance
{
+public:
+ class Loader: public DataFile::ObjectLoader<AnimatedObject>
+ {
+ public:
+ Loader(AnimatedObject &);
+
+ private:
+ void position(float, float, float);
+ void rotation(float, float, float, float);
+ void scale(float, float, float);
+ void scale_uniform(float);
+ };
+
private:
Matrix matrix;
std::vector<float> pose_data;
+#include <msp/datafile/collection.h>
+#include "animatedobject.h"
#include "culler.h"
#include "renderer.h"
#include "scene.h"
namespace Msp {
namespace GL {
+Scene::~Scene()
+{
+ for(list<Renderable *>::iterator i=owned_data.begin(); i!=owned_data.end(); ++i)
+ delete *i;
+}
+
void Scene::add_culler(Culler &c)
{
cullers.push_back(&c);
return false;
}
+
+Scene::Loader::Loader(Scene &s, Collection &c):
+ DataFile::CollectionObjectLoader<Scene>(s, &c)
+{
+ add("object", &Loader::object);
+}
+
+void Scene::Loader::object(const string &n)
+{
+ RefPtr<AnimatedObject> anob = new AnimatedObject(get_collection().get<GL::Object>(n));
+ load_sub(*anob);
+ obj.add(*anob);
+ obj.owned_data.push_back(anob.release());
+}
+
} // namespace GL
} // namespace Msp
#define MSP_GL_SCENE_H_
#include <list>
+#include <msp/datafile/objectloader.h>
#include "renderable.h"
namespace Msp {
*/
class Scene: public Renderable
{
+public:
+ class Loader: public DataFile::CollectionObjectLoader<Scene>
+ {
+ public:
+ Loader(Scene &, Collection &);
+
+ private:
+ void object(const std::string &);
+ };
+
protected:
+ std::list<Renderable *> owned_data;
std::list<Culler *> cullers;
Scene() { }
+private:
+ Scene(const Scene &);
+ Scene &operator=(const Scene &);
public:
- virtual ~Scene() { }
+ virtual ~Scene();
virtual void add(const Renderable &) = 0;
virtual void remove(const Renderable &) = 0;