]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a Loader for Scene, and a matching Blender exporter
authorMikko Rasa <tdb@tdb.fi>
Sun, 17 Aug 2014 14:43:41 +0000 (17:43 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 17 Aug 2014 14:43:41 +0000 (17:43 +0300)
blender/io_mspgl/__init__.py
blender/io_mspgl/export_mesh.py
blender/io_mspgl/export_object.py
blender/io_mspgl/export_scene.py [new file with mode: 0644]
source/animatedobject.cpp
source/animatedobject.h
source/scene.cpp
source/scene.h

index 1e085baf9cf4559d9f85885c78174ef5310b2627..b7e14fdad19d0bae3ae027c31f67fb6f87ed38a4 100644 (file)
@@ -7,7 +7,7 @@ bl_info = {
 
 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])
 
@@ -96,7 +96,7 @@ class ExportMspGLObject(bpy.types.Operator, ExportMspGLMeshBase):
 
        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"),
@@ -143,10 +143,28 @@ class ExportMspGLArmature(bpy.types.Operator, ExportMspGLBase):
                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
 
index dbb3a269fcdab5f711bab6920da3f6f9b696e1ff..e429d7ae35ccd3c9daf4350e5decaf6e395084cb 100644 (file)
@@ -191,9 +191,10 @@ class MeshExporter:
 
                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 = []
@@ -203,7 +204,7 @@ class MeshExporter:
                                                        children.append(c)
                                objs += children
                                check = children
-               else:
+               elif objs is None:
                        objs = [context.active_object]
 
                if not objs:
index aad1c0876a40823bca2f1d4bc3ce5b7fe125ba41..d89afd05df667fb7c26d648a167bde38cc7ff8f8 100644 (file)
@@ -17,8 +17,11 @@ class ObjectExporter:
                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)
@@ -32,11 +35,11 @@ class ObjectExporter:
                        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:
diff --git a/blender/io_mspgl/export_scene.py b/blender/io_mspgl/export_scene.py
new file mode 100644 (file)
index 0000000..8f224fe
--- /dev/null
@@ -0,0 +1,57 @@
+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();
index 63a25112a769428374e37dd0634251b4f2c2c8b7..4be198a87fec6739957642e485db91baee036263 100644 (file)
@@ -48,5 +48,35 @@ void AnimatedObject::setup_render(Renderer &renderer, const Tag &) const
                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
index 6bcd37ce4b609dbecadece72bfc336bc75317827..4782951d10fb9207a77e26a6d32cff367a27c3db 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_ANIMATEDOBJECT_H_
 
 #include <vector>
+#include <msp/datafile/objectloader.h>
 #include "matrix.h"
 #include "objectinstance.h"
 
@@ -14,6 +15,19 @@ useful for displaying objects at a static position.
 */
 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;
index 3f0261f4d467af0c3bad85d1d01a572b51346420..f233a09b31ea39324324db15c11586b789e8be99 100644 (file)
@@ -1,3 +1,5 @@
+#include <msp/datafile/collection.h>
+#include "animatedobject.h"
 #include "culler.h"
 #include "renderer.h"
 #include "scene.h"
@@ -7,6 +9,12 @@ using namespace std;
 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);
@@ -39,5 +47,20 @@ bool Scene::cull(const Renderer &renderer, const Renderable &renderable) const
        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
index 10b1ab650b3322fc078ded30be7115bac689f6f5..687c581fe5d4070c27d6e62819be4a3f8bff48aa 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_SCENE_H_
 
 #include <list>
+#include <msp/datafile/objectloader.h>
 #include "renderable.h"
 
 namespace Msp {
@@ -16,12 +17,26 @@ InstancedScene and OrderedScene.
 */
 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;