3D Audio GSoC:
authorJoerg Mueller <nexyon@gmail.com>
Mon, 1 Aug 2011 11:44:20 +0000 (11:44 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Mon, 1 Aug 2011 11:44:20 +0000 (11:44 +0000)
Adds new speaker object type.

Notes:
* Needs some nice icons
* Quickily review by Joshua Leung (5 mins)
* Properties UI updated (with help of Thomans Dinges)
* Speakers have their own theme color
* No real audio functionality yet.
* Minor bug regarding lamps/lattices fixed in interface_templates.c

I personality tested:
* Creation, Deletion, Duplication
* Saving, Loading
* Library linking (incl. make local)
* Tracking
* Dope Sheet, Outliner
* Animation
* Drawing (incl. Theme)

54 files changed:
release/scripts/modules/bpy_types.py
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_data_speaker.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_scene.py
release/scripts/startup/bl_ui/space_dopesheet.py
release/scripts/startup/bl_ui/space_info.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/resources.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_relations.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_speaker_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_speaker.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_userdef.c

index 056899d..75b199d 100644 (file)
@@ -57,7 +57,7 @@ class Library(bpy_types.ID):
                 "curves", "grease_pencil", "groups", "images", \
                 "lamps", "lattices", "materials", "metaballs", \
                 "meshes", "node_groups", "objects", "scenes", \
-                "sounds", "textures", "texts", "fonts", "worlds"
+                "sounds", "speakers", "textures", "texts", "fonts", "worlds"
 
         return tuple(id_block for attr in attr_links for id_block in getattr(bpy.data, attr) if id_block.library == self)
 
index bf63c60..5fab3b7 100644 (file)
@@ -36,6 +36,7 @@ _modules = (
     "properties_data_mesh",
     "properties_data_metaball",
     "properties_data_modifier",
+    "properties_data_speaker",
     "properties_game",
     "properties_material",
     "properties_object_constraint",
diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py
new file mode 100644 (file)
index 0000000..45f2fa5
--- /dev/null
@@ -0,0 +1,129 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+import bpy
+from rna_prop_ui import PropertyPanel
+
+
+class DataButtonsPanel():
+    bl_space_type = 'PROPERTIES'
+    bl_region_type = 'WINDOW'
+    bl_context = "data"
+
+    @classmethod
+    def poll(cls, context):
+        engine = context.scene.render.engine
+        return context.speaker and (engine in cls.COMPAT_ENGINES)
+
+
+class DATA_PT_context_speaker(DataButtonsPanel, bpy.types.Panel):
+    bl_label = ""
+    bl_options = {'HIDE_HEADER'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+        speaker = context.speaker
+        space = context.space_data
+
+        split = layout.split(percentage=0.65)
+
+        if ob:
+            split.template_ID(ob, "data")
+        elif speaker:
+            split.template_ID(space, "pin_id")
+
+
+class DATA_PT_speaker(DataButtonsPanel, bpy.types.Panel):
+    bl_label = "Sound"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        speaker = context.speaker
+
+        split = layout.split(percentage=0.75)
+
+        split.template_ID(speaker, "sound", open="sound.open")
+        split.prop(speaker, "muted")
+
+        split = layout.split()
+
+        row = split.row()
+
+        row.prop(speaker, "volume")
+        row.prop(speaker, "pitch")
+
+
+class DATA_PT_distance(DataButtonsPanel, bpy.types.Panel):
+    bl_label = "Distance"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        speaker = context.speaker
+
+        split = layout.split()
+        col = split.column()
+
+        col.label("Volume:")
+        col.prop(speaker, "volume_min", text="Minimum")
+        col.prop(speaker, "volume_max", text="Maximum")
+        col.prop(speaker, "attenuation")
+
+        col = split.column()
+
+        col.label("Distance:")
+        col.prop(speaker, "distance_max", text="Maximum")
+        col.prop(speaker, "distance_reference", text="Reference")
+
+
+class DATA_PT_cone(DataButtonsPanel, bpy.types.Panel):
+    bl_label = "Cone"
+    COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        speaker = context.speaker
+
+        split = layout.split()
+        col = split.column()
+
+        col.label("Angle:")
+        col.prop(speaker, "cone_angle_outer", text="Outer")
+        col.prop(speaker, "cone_angle_inner", text="Inner")
+
+        col = split.column()
+
+        col.label("Volume:")
+        col.prop(speaker, "cone_volume_outer", text="Outer")
+
+
+class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
+    _context_path = "object.data"
+    _property_type = bpy.types.Speaker
+
+if __name__ == "__main__":  # only for live edit.
+    bpy.utils.register_module(__name__)
index aec9d88..a9310fc 100644 (file)
@@ -51,22 +51,24 @@ class SCENE_PT_audio(SceneButtonsPanel, bpy.types.Panel):
         layout = self.layout
         scene = context.scene
         rd = context.scene.render
-        
-        layout.prop(scene, "audio_distance_model")
-
-        layout.prop(scene, "audio_doppler_speed", text="Speed")
-        layout.prop(scene, "audio_doppler_factor")
 
         layout.prop(scene, "audio_volume")
-        layout.operator("sound.update_animation_flags")
         layout.operator("sound.bake_animation")
 
         split = layout.split()
 
         col = split.column()
-        col.prop(rd, "ffmpeg_audio_mixrate", text="Rate")
+
+        col.label("Listener:")
+        col.prop(scene, "audio_distance_model", text="")
+        col.prop(scene, "audio_doppler_speed", text="Speed")
+        col.prop(scene, "audio_doppler_factor", text="Doppler")
+
         col = split.column()
+
+        col.label("Format:")
         col.prop(rd, "ffmpeg_audio_channels", text="")
+        col.prop(rd, "ffmpeg_audio_mixrate", text="Rate")
 
 
 class SCENE_PT_unit(SceneButtonsPanel, bpy.types.Panel):
@@ -102,7 +104,6 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
         col = row.column(align=True)
         col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
         col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="")
-        col.menu("SCENE_MT_keying_set_specials", icon='DOWNARROW_HLT', text="")
 
         ks = scene.keying_sets.active
         if ks and ks.is_path_absolute:
@@ -121,14 +122,6 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
             col.prop(ks, "bl_options")
 
 
-class SCENE_MT_keying_set_specials(bpy.types.Menu):
-    bl_label = "Keying Set Specials"
-
-    def draw(self, context):
-        layout = self.layout
-        
-        layout.operator("anim.keying_set_import", text="Import From File")
-
 class SCENE_PT_keying_set_paths(SceneButtonsPanel, bpy.types.Panel):
     bl_label = "Active Keying Set"
 
@@ -233,36 +226,6 @@ class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, bpy.types.Panel):
 #  XXX, move operator to op/ dir
 
 
-class ANIM_OT_keying_set_import(bpy.types.Operator):
-    "Import Keying Set from a python script."
-    bl_idname = "anim.keying_set_import"
-    bl_label = "Import Keying Set from File"
-
-    filepath = bpy.props.StringProperty(name="File Path", description="Filepath to read file from.")
-    filter_folder = bpy.props.BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
-    filter_text = bpy.props.BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
-    filter_python = bpy.props.BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
-
-    def execute(self, context):
-        if not self.filepath:
-            raise Exception("Filepath not set.")
-        
-        f = open(self.filepath, "r")
-        if not f:
-            raise Exception("Could not open file.")
-        
-        # lazy way of loading and running this file...
-        exec(compile(f.read(), self.filepath, 'exec'))
-        
-        f.close()
-
-        return {'FINISHED'}
-
-    def invoke(self, context, event):
-        wm = context.window_manager
-        wm.fileselect_add(self)
-        return {'RUNNING_MODAL'}
-
 class ANIM_OT_keying_set_export(bpy.types.Operator):
     "Export Keying Set to a python script."
     bl_idname = "anim.keying_set_export"
index b4f196d..646a085 100644 (file)
@@ -86,6 +86,8 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
             row.prop(dopesheet, "show_armatures", text="")
         if bpy.data.particles:
             row.prop(dopesheet, "show_particles", text="")
+        if bpy.data.speakers:
+            row.prop(dopesheet, "show_speakers", text="")
 
 
 #######################################
index f66cee7..eba2581 100644 (file)
@@ -292,6 +292,9 @@ class INFO_MT_add(bpy.types.Menu):
         layout.operator_menu_enum("object.lamp_add", "type", text="Lamp", icon='OUTLINER_OB_LAMP')
         layout.separator()
 
+        layout.operator("object.speaker_add", text="Speaker", icon='SPEAKER')
+        layout.separator()
+
         layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY')
         layout.separator()
 
index a073f50..b332cd3 100644 (file)
@@ -73,6 +73,7 @@ set(SRC_DNA_INC
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_smoke_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sound_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_space_types.h
+       ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_speaker_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_text_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_texture_types.h
        ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_userdef_types.h
index df6a304..c25882d 100644 (file)
@@ -77,6 +77,7 @@ typedef struct Main {
        ListBase script;
        ListBase vfont;
        ListBase text;
+       ListBase speaker;
        ListBase sound;
        ListBase group;
        ListBase armature;
index a6b5c04..f9e01a5 100644 (file)
@@ -88,6 +88,11 @@ void make_local_lamp(struct Lamp *la);
 void free_camera(struct Camera *ca);
 void free_lamp(struct Lamp *la);
 
+void *add_speaker(const char *name);
+struct Speaker *copy_speaker(struct Speaker *spk);
+void make_local_speaker(struct Speaker *spk);
+void free_speaker(struct Speaker *spk);
+
 struct Object *add_only_object(int type, const char *name);
 struct Object *add_object(struct Scene *scene, int type);
 
index a3d0377..a43cdc8 100644 (file)
@@ -85,6 +85,7 @@ short id_type_can_have_animdata (ID *id)
                case ID_PA:
                case ID_MA: case ID_TE: case ID_NT:
                case ID_LA: case ID_CA: case ID_WO:
+               case ID_SPK:
                case ID_SCE:
                {
                        return 1;
@@ -787,7 +788,10 @@ void BKE_animdata_main_cb (Main *mainptr, ID_AnimData_Edit_Callback func, void *
        
        /* particles */
        ANIMDATA_IDS_CB(mainptr->particle.first);
-       
+
+       /* speakers */
+       ANIMDATA_IDS_CB(mainptr->speaker.first);
+
        /* objects */
        ANIMDATA_IDS_CB(mainptr->object.first);
        
@@ -865,7 +869,10 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
        
        /* particles */
        RENAMEFIX_ANIM_IDS(mainptr->particle.first);
-       
+
+       /* speakers */
+       RENAMEFIX_ANIM_IDS(mainptr->speaker.first);
+
        /* objects */
        RENAMEFIX_ANIM_IDS(mainptr->object.first); 
        
@@ -2309,6 +2316,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime)
        /* particles */
        EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
        
+       /* lamps */
+       EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM);
+
        /* objects */
                /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets 
                 * this tagged by Depsgraph on framechange. This optimisation means that objects
index e14983a..6083151 100644 (file)
@@ -2383,7 +2383,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
        if(id) {
                idtype= GS(id->name);
 
-               if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
+               if(ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
                        for(obt=bmain->object.first; obt; obt= obt->id.next) {
                                if(!(ob && obt == ob) && obt->data == id) {
                                        obt->recalc |= OB_RECALC_DATA;
index 8c8a693..e84a2a0 100644 (file)
@@ -73,7 +73,8 @@ static IDType idtypes[]= {
        { ID_SCE,               "Scene",        "scenes",               IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_SCR,               "Screen",       "screens",              0}, 
        { ID_SEQ,               "Sequence",     "sequences",    0}, /* not actually ID data */
-       { ID_SO,                "Sound",        "sounds",               IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_SPK,               "Speaker",      "speakers",             IDTYPE_FLAGS_ISLINKABLE},
+       { ID_SO,                "Sound",        "sounds",               IDTYPE_FLAGS_ISLINKABLE},
        { ID_TE,                "Texture",      "textures",             IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_TXT,               "Text",         "texts",                IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_VF,                "VFont",        "fonts",                IDTYPE_FLAGS_ISLINKABLE}, 
index a5da248..85f8799 100644 (file)
@@ -65,6 +65,7 @@
 #include "DNA_node_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_text_types.h"
 #include "DNA_vfont_types.h"
@@ -207,6 +208,9 @@ int id_make_local(ID *id, int test)
                case ID_CA:
                        if(!test) make_local_camera((Camera*)id);
                        return 1;
+               case ID_SPK:
+                       if(!test) make_local_speaker((Speaker*)id);
+                       return 1;
                case ID_IP:
                        return 0; /* deprecated */
                case ID_KE:
@@ -289,6 +293,9 @@ int id_copy(ID *id, ID **newid, int test)
                case ID_LA:
                        if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
                        return 1;
+               case ID_SPK:
+                       if(!test) *newid= (ID*)copy_speaker((Speaker*)id);
+                       return 1;
                case ID_CA:
                        if(!test) *newid= (ID*)copy_camera((Camera*)id);
                        return 1;
@@ -439,6 +446,8 @@ ListBase *which_libbase(Main *mainlib, short type)
                        return &(mainlib->text);
                case ID_SCRIPT:
                        return &(mainlib->script);
+               case ID_SPK:
+                       return &(mainlib->speaker);
                case ID_SO:
                        return &(mainlib->sound);
                case ID_GR:
@@ -523,7 +532,8 @@ int set_listbasepointers(Main *main, ListBase **lb)
        lb[a++]= &(main->latt);
        lb[a++]= &(main->lamp);
        lb[a++]= &(main->camera);
-       
+       lb[a++]= &(main->speaker);
+
        lb[a++]= &(main->text);
        lb[a++]= &(main->sound);
        lb[a++]= &(main->group);
@@ -615,6 +625,9 @@ static ID *alloc_libblock_notest(short type)
                case ID_SCRIPT:
                        //XXX id= MEM_callocN(sizeof(Script), "script");
                        break;
+               case ID_SPK:
+                       id= MEM_callocN(sizeof(Speaker), "speaker");
+                       break;
                case ID_SO:
                        id= MEM_callocN(sizeof(bSound), "sound");
                        break;
@@ -818,6 +831,9 @@ void free_libblock(ListBase *lb, void *idv)
                case ID_SCRIPT:
                        //XXX free_script((Script *)id);
                        break;
+               case ID_SPK:
+                       free_speaker((Speaker *)id);
+                       break;
                case ID_SO:
                        sound_free((bSound*)id);
                        break;
index 862d583..66bf4ea 100644 (file)
@@ -54,7 +54,9 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
 #include "DNA_space_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_world_types.h"
 
@@ -975,6 +977,99 @@ void free_lamp(Lamp *la)
        la->id.icon_id = 0;
 }
 
+void *add_speaker(const char *name)
+{
+       Speaker *spk;
+
+       spk=  alloc_libblock(&G.main->speaker, ID_SPK, name);
+
+       spk->attenuation = 1.0f;
+       spk->cone_angle_inner = 360.0f;
+       spk->cone_angle_outer = 360.0f;
+       spk->cone_volume_outer = 1.0f;
+       spk->distance_max = FLT_MAX;
+       spk->distance_reference = 1.0f;
+       spk->flag = 0;
+       spk->pitch = 1.0f;
+       spk->sound = NULL;
+       spk->volume = 1.0f;
+       spk->volume_max = 1.0f;
+       spk->volume_min = 0.0f;
+
+       return spk;
+}
+
+Speaker *copy_speaker(Speaker *spk)
+{
+       Speaker *spkn;
+
+       spkn= copy_libblock(spk);
+       if(spkn->sound)
+               spkn->sound->id.us++;
+
+       return spkn;
+}
+
+void make_local_speaker(Speaker *spk)
+{
+       Main *bmain= G.main;
+       Object *ob;
+       int local=0, lib=0;
+
+       /* - only lib users: do nothing
+               * - only local users: set flag
+               * - mixed: make copy
+               */
+
+       if(spk->id.lib==NULL) return;
+       if(spk->id.us==1) {
+               spk->id.lib= NULL;
+               spk->id.flag= LIB_LOCAL;
+               new_id(&bmain->speaker, (ID *)spk, NULL);
+               return;
+       }
+
+       ob= bmain->object.first;
+       while(ob) {
+               if(ob->data==spk) {
+                       if(ob->id.lib) lib= 1;
+                       else local= 1;
+               }
+               ob= ob->id.next;
+       }
+
+       if(local && lib==0) {
+               spk->id.lib= NULL;
+               spk->id.flag= LIB_LOCAL;
+               new_id(&bmain->speaker, (ID *)spk, NULL);
+       }
+       else if(local && lib) {
+               Speaker *spkn= copy_speaker(spk);
+               spkn->id.us= 0;
+
+               ob= bmain->object.first;
+               while(ob) {
+                       if(ob->data==spk) {
+
+                               if(ob->id.lib==NULL) {
+                                       ob->data= spkn;
+                                       spkn->id.us++;
+                                       spk->id.us--;
+                               }
+                       }
+                       ob= ob->id.next;
+               }
+       }
+}
+
+void free_speaker(Speaker *spk)
+{
+       if(spk->sound)
+               spk->sound->id.us--;
+
+       BKE_free_animdata((ID *)spk);
+}
+
 /* *************************************************** */
 
 static void *add_obdata_from_type(int type)
@@ -989,6 +1084,7 @@ static void *add_obdata_from_type(int type)
        case OB_LAMP: return add_lamp("Lamp");
        case OB_LATTICE: return add_lattice("Lattice");
        case OB_ARMATURE: return add_armature("Armature");
+       case OB_SPEAKER: return add_speaker("Speaker");
        case OB_EMPTY: return NULL;
        default:
                printf("add_obdata_from_type: Internal error, bad type: %d\n", type);
@@ -1008,6 +1104,7 @@ static const char *get_obdata_defname(int type)
        case OB_LAMP: return "Lamp";
        case OB_LATTICE: return "Lattice";
        case OB_ARMATURE: return "Armature";
+       case OB_SPEAKER: return "Speaker";
        case OB_EMPTY: return "Empty";
        default:
                printf("get_obdata_defname: Internal error, bad type: %d\n", type);
@@ -1051,7 +1148,7 @@ Object *add_only_object(int type, const char *name)
        ob->empty_drawtype= OB_PLAINAXES;
        ob->empty_drawsize= 1.0;
 
-       if(type==OB_CAMERA || type==OB_LAMP) {
+       if(type==OB_CAMERA || type==OB_LAMP || type==OB_SPEAKER) {
                ob->trackflag= OB_NEGZ;
                ob->upflag= OB_POSY;
        }
index 51cb4cc..0387e26 100644 (file)
@@ -85,6 +85,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_smoke_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_space_types.h"
 #include "DNA_vfont_types.h"
@@ -5566,6 +5567,37 @@ static void fix_relpaths_library(const char *basepath, Main *main)
        }
 }
 
+/* ************ READ SPEAKER ***************** */
+
+static void lib_link_speaker(FileData *fd, Main *main)
+{
+       Speaker *spk;
+
+       spk= main->speaker.first;
+       while(spk) {
+               if(spk->id.flag & LIB_NEEDLINK) {
+                       if (spk->adt) lib_link_animdata(fd, &spk->id, spk->adt);
+
+                       spk->sound= newlibadr(fd, spk->id.lib, spk->sound);
+                       if (spk->sound) {
+                               spk->sound->id.us++;
+                       }
+
+                       spk->id.flag -= LIB_NEEDLINK;
+               }
+               spk= spk->id.next;
+       }
+}
+
+static void direct_link_speaker(FileData *fd, Speaker *spk)
+{
+       spk->adt= newdataadr(fd, spk->adt);
+       direct_link_animdata(fd, spk->adt);
+
+       /*spk->sound= newdataadr(fd, spk->sound);
+       direct_link_sound(fd, spk->sound);*/
+}
+
 /* ************** READ SOUND ******************* */
 
 static void direct_link_sound(FileData *fd, bSound *sound)
@@ -5661,6 +5693,7 @@ static const char *dataname(short id_code)
                case ID_SCR: return "Data from SCR";
                case ID_VF: return "Data from VF";
                case ID_TXT     : return "Data from TXT";
+               case ID_SPK: return "Data from SPK";
                case ID_SO: return "Data from SO";
                case ID_NT: return "Data from NT";
                case ID_BR: return "Data from BR";
@@ -5805,6 +5838,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID
                case ID_CA:
                        direct_link_camera(fd, (Camera *)id);
                        break;
+               case ID_SPK:
+                       direct_link_speaker(fd, (Speaker *)id);
+                       break;
                case ID_SO:
                        direct_link_sound(fd, (bSound *)id);
                        break;
@@ -11796,6 +11832,7 @@ static void lib_link_all(FileData *fd, Main *main)
        lib_link_latt(fd, main);
        lib_link_text(fd, main);
        lib_link_camera(fd, main);
+       lib_link_speaker(fd, main);
        lib_link_sound(fd, main);
        lib_link_group(fd, main);
        lib_link_armature(fd, main);
@@ -12712,6 +12749,14 @@ static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
                expand_animdata(fd, mainvar, ca->adt);
 }
 
+static void expand_speaker(FileData *fd, Main *mainvar, Speaker *spk)
+{
+       expand_doit(fd, mainvar, spk->sound);
+
+       if (spk->adt)
+               expand_animdata(fd, mainvar, spk->adt);
+}
+
 static void expand_sound(FileData *fd, Main *mainvar, bSound *snd)
 {
        expand_doit(fd, mainvar, snd->ipo); // XXX depreceated - old animation system
@@ -12774,6 +12819,9 @@ static void expand_main(FileData *fd, Main *mainvar)
                                        case ID_CA:
                                                expand_camera(fd, mainvar, (Camera *)id);
                                                break;
+                                       case ID_SPK:
+                                               expand_speaker(fd, mainvar,(Speaker *)id);
+                                               break;
                                        case ID_SO:
                                                expand_sound(fd, mainvar, (bSound *)id);
                                                break;
index c9e7cd0..319657c 100644 (file)
@@ -123,6 +123,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "DNA_smoke_types.h"
 #include "DNA_space_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_text_types.h"
 #include "DNA_view3d_types.h"
@@ -2331,6 +2332,23 @@ static void write_texts(WriteData *wd, ListBase *idbase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
+static void write_speakers(WriteData *wd, ListBase *idbase)
+{
+       Speaker *spk;
+
+       spk= idbase->first;
+       while(spk) {
+               if(spk->id.us>0 || wd->current) {
+                       /* write LibData */
+                       writestruct(wd, ID_SPK, "Speaker", 1, spk);
+                       if (spk->id.properties) IDP_WriteProperty(spk->id.properties, wd);
+
+                       if (spk->adt) write_animdata(wd, spk->adt);
+               }
+               spk= spk->id.next;
+       }
+}
+
 static void write_sounds(WriteData *wd, ListBase *idbase)
 {
        bSound *sound;
@@ -2509,6 +2527,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
        write_keys     (wd, &mainvar->key);
        write_worlds   (wd, &mainvar->world);
        write_texts    (wd, &mainvar->text);
+       write_speakers (wd, &mainvar->speaker);
        write_sounds   (wd, &mainvar->sound);
        write_groups   (wd, &mainvar->group);
        write_armatures(wd, &mainvar->armature);
index 5e23b49..4296d40 100644 (file)
@@ -55,6 +55,7 @@
 #include "DNA_node_types.h"
 #include "DNA_world_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_speaker_types.h"
 
 #include "RNA_access.h"
 
@@ -584,7 +585,9 @@ static int acf_object_icon(bAnimListElem *ale)
                        return ICON_OUTLINER_OB_META;
                case OB_LATTICE: 
                        return ICON_OUTLINER_OB_LATTICE;
-               case OB_ARMATURE: 
+               case OB_SPEAKER:
+                       return ICON_SPEAKER;
+               case OB_ARMATURE:
                        return ICON_OUTLINER_OB_ARMATURE;
                case OB_FONT: 
                        return ICON_OUTLINER_OB_FONT;
@@ -2088,6 +2091,82 @@ static bAnimChannelType ACF_DSLAT=
        acf_dslat_setting_ptr                                   /* pointer for setting */
 };
 
+/* Speaker Expander  ------------------------------------------- */
+
+// TODO: just get this from RNA?
+static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
+{
+       return ICON_SPEAKER;
+}
+
+/* get the appropriate flag(s) for the setting when it is valid  */
+static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg)
+{
+       /* clear extra return data first */
+       *neg= 0;
+
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       return SPK_DS_EXPAND;
+
+               case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+                       return ADT_NLA_EVAL_OFF;
+
+               case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+                       *neg= 1;
+                       return ADT_CURVES_NOT_VISIBLE;
+
+               case ACHANNEL_SETTING_SELECT: /* selected */
+                       return ADT_UI_SELECTED;
+
+               default: /* unsupported */
+                       return 0;
+       }
+}
+
+/* get pointer to the setting */
+static void *acf_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+       Speaker *spk= (Speaker *)ale->data;
+
+       /* clear extra return data first */
+       *type= 0;
+
+       switch (setting) {
+               case ACHANNEL_SETTING_EXPAND: /* expanded */
+                       GET_ACF_FLAG_PTR(spk->flag);
+
+               case ACHANNEL_SETTING_SELECT: /* selected */
+               case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+               case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+                       if (spk->adt)
+                               GET_ACF_FLAG_PTR(spk->adt->flag)
+                       else
+                               return NULL;
+
+               default: /* unsupported */
+                       return NULL;
+       }
+}
+
+/* speaker expander type define */
+static bAnimChannelType ACF_DSSPK=
+{
+       "Speaker Expander",                             /* type name */
+
+       acf_generic_dataexpand_color,   /* backdrop color */
+       acf_generic_dataexpand_backdrop,/* backdrop */
+       acf_generic_indention_1,                /* indent level */
+       acf_generic_basic_offset,               /* offset */
+
+       acf_generic_idblock_name,               /* name */
+       acf_dsspk_icon,                                 /* icon */
+
+       acf_generic_dataexpand_setting_valid,   /* has setting */
+       acf_dsspk_setting_flag,                                 /* flag for setting */
+       acf_dsspk_setting_ptr                                   /* pointer for setting */
+};
+
 /* ShapeKey Entry  ------------------------------------------- */
 
 /* name for ShapeKey */
@@ -2370,7 +2449,8 @@ static void ANIM_init_channel_typeinfo_data (void)
                animchannelTypeInfo[type++]= &ACF_DSMESH;               /* Mesh Channel */
                animchannelTypeInfo[type++]= &ACF_DSTEX;                /* Texture Channel */
                animchannelTypeInfo[type++]= &ACF_DSLAT;                /* Lattice Channel */
-               
+               animchannelTypeInfo[type++]= &ACF_DSSPK;                /* Speaker Channel */
+
                animchannelTypeInfo[type++]= &ACF_SHAPEKEY;             /* ShapeKey */
                
                animchannelTypeInfo[type++]= &ACF_GPD;                  /* Grease Pencil Datablock */ 
index eee7fb0..8331001 100644 (file)
@@ -124,6 +124,7 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
                        case ANIMTYPE_DSMESH:
                        case ANIMTYPE_DSTEX:
                        case ANIMTYPE_DSLAT:
+                       case ANIMTYPE_DSSPK:
                        {
                                /* need to verify that this data is valid for now */
                                if (ale->adt) {
@@ -168,6 +169,7 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
                        case ANIMTYPE_DSARM:
                        case ANIMTYPE_DSMESH:
                        case ANIMTYPE_DSLAT:
+                       case ANIMTYPE_DSSPK:
                        {
                                /* need to verify that this data is valid for now */
                                if (ale && ale->adt) {
@@ -247,6 +249,7 @@ void ANIM_deselect_anim_channels (bAnimContext *ac, void *data, short datatype,
                                case ANIMTYPE_DSNTREE:
                                case ANIMTYPE_DSTEX:
                                case ANIMTYPE_DSLAT:
+                               case ANIMTYPE_DSSPK:
                                {
                                        if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
                                                sel= ACHANNEL_SETFLAG_CLEAR;
@@ -336,6 +339,7 @@ void ANIM_deselect_anim_channels (bAnimContext *ac, void *data, short datatype,
                        case ANIMTYPE_DSNTREE:
                        case ANIMTYPE_DSTEX:
                        case ANIMTYPE_DSLAT:
+                       case ANIMTYPE_DSSPK:
                        {
                                /* need to verify that this data is valid for now */
                                if (ale->adt) {
@@ -2071,6 +2075,7 @@ static int mouse_anim_channels (bAnimContext *ac, float UNUSED(x), int channel_i
                case ANIMTYPE_DSNTREE:
                case ANIMTYPE_DSTEX:
                case ANIMTYPE_DSLAT:
+               case ANIMTYPE_DSSPK:
                {
                        /* sanity checking... */
                        if (ale->adt) {
index 047a776..4927b0f 100644 (file)
@@ -67,6 +67,7 @@
 #include "DNA_sequence_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_world_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_object_types.h"
@@ -646,6 +647,19 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *own
                                ale->adt= BKE_animdata_from_id(data);
                        }       
                                break;
+                       case ANIMTYPE_DSSPK:
+                       {
+                               Speaker *spk= (Speaker *)data;
+                               AnimData *adt= spk->adt;
+
+                               ale->flag= FILTER_SPK_OBJD(spk);
+
+                               ale->key_data= (adt) ? adt->action : NULL;
+                               ale->datatype= ALE_ACT;
+
+                               ale->adt= BKE_animdata_from_id(data);
+                       }
+                               break;
                        case ANIMTYPE_DSSKEY:
                        {
                                Key *key= (Key *)data;
@@ -1608,6 +1622,14 @@ static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data,
                        expanded= FILTER_LATTICE_OBJD(lt);
                }
                        break;
+               case OB_SPEAKER: /* ---------- Speaker ----------- */
+               {
+                       Speaker *spk= (Speaker *)ob->data;
+
+                       type= ANIMTYPE_DSSPK;
+                       expanded= FILTER_SPK_OBJD(spk);
+               }
+                       break;
        }
        
        /* add object data animation channels */
index b774bc9..56bc377 100644 (file)
@@ -59,6 +59,7 @@
 #include "DNA_meta_types.h"
 #include "DNA_node_types.h"
 #include "DNA_particle_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_world_types.h"
 #include "DNA_gpencil_types.h"
 
index 0b99c25..3c4ca1a 100644 (file)
@@ -153,6 +153,7 @@ typedef enum eAnim_ChannelType {
        ANIMTYPE_DSMESH,
        ANIMTYPE_DSTEX,
        ANIMTYPE_DSLAT,
+       ANIMTYPE_DSSPK,
        
        ANIMTYPE_SHAPEKEY,
        
@@ -243,6 +244,7 @@ typedef enum eAnimFilter_Flags {
 #define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND))
 #define FILTER_MESH_OBJD(me) ((me->flag & ME_DS_EXPAND))
 #define FILTER_LATTICE_OBJD(lt) ((lt->flag & LT_DS_EXPAND))
+#define FILTER_SPK_OBJD(spk) ((spk->flag & SPK_DS_EXPAND))
        /* Variable use expanders */
 #define FILTER_NTREE_DATA(ntree) ((ntree->flag & NTREE_DS_EXPAND))
 #define FILTER_TEX_DATA(tex) ((tex->flag & TEX_DS_EXPAND))
index 2311aaf..2bc2aac 100644 (file)
@@ -204,6 +204,8 @@ enum {
        TH_STRIP_SELECT,
        
        TH_LAMP,
+
+       TH_SPEAKER,
        
        TH_NODE,
        TH_NODE_IN_OUT,
index 3d7d1bf..28bfbfb 100644 (file)
@@ -298,11 +298,13 @@ static const char *template_id_browse_tip(StructRNA *type)
                        case ID_MA: return "Browse Material to be linked";
                        case ID_TE: return "Browse Texture to be linked";
                        case ID_IM: return "Browse Image to be linked";
-                       case ID_LA: return "Browse Lattice Data to be linked";
+                       case ID_LT: return "Browse Lattice Data to be linked";
+                       case ID_LA: return "Browse Lamp Data to be linked";
                        case ID_CA: return "Browse Camera Data to be linked";
                        case ID_WO: return "Browse World Settings to be linked";
                        case ID_SCR: return "Choose Screen lay-out";
                        case ID_TXT: return "Browse Text to be linked";
+                       case ID_SPK: return "Browse Speaker Data to be linked";
                        case ID_SO: return "Browse Sound to be linked";
                        case ID_AR: return "Browse Armature data to be linked";
                        case ID_AC: return "Browse Action to be linked";
index 2465c73..1aa2fb3 100644 (file)
@@ -249,6 +249,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
                                cp= ts->wire; break;
                        case TH_LAMP:
                                cp= ts->lamp; break;
+                       case TH_SPEAKER:
+                               cp= ts->speaker; break;
                        case TH_SELECT:
                                cp= ts->select; break;
                        case TH_ACTIVE:
@@ -584,6 +586,7 @@ void ui_theme_init_default(void)
        SETCOLF(btheme->tv3d.grid,     0.251, 0.251, 0.251, 1.0);
        SETCOL(btheme->tv3d.wire,       0x0, 0x0, 0x0, 255);
        SETCOL(btheme->tv3d.lamp,       0, 0, 0, 40);
+       SETCOL(btheme->tv3d.speaker,    0, 0, 0, 255);
        SETCOL(btheme->tv3d.select, 241, 88, 0, 255);
        SETCOL(btheme->tv3d.active, 255, 170, 64, 255);
        SETCOL(btheme->tv3d.group,      8, 48, 8, 255);
index f5f97c6..48e138d 100644 (file)
@@ -44,6 +44,7 @@
 #include "DNA_object_fluidsim.h"
 #include "DNA_object_force.h"
 #include "DNA_scene_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_vfont_types.h"
 
 #include "BLI_math.h"
@@ -764,6 +765,40 @@ static int group_instance_add_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
+static int object_speaker_add_exec(bContext *C, wmOperator *op)
+{
+       Object *ob;
+       int enter_editmode;
+       unsigned int layer;
+       float loc[3], rot[3];
+
+       object_add_generic_invoke_options(C, op);
+       if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer))
+               return OPERATOR_CANCELLED;
+
+       ob= ED_object_add_type(C, OB_SPEAKER, loc, rot, FALSE, layer);
+
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_speaker_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Speaker";
+       ot->description = "Add a speaker object to the scene";
+       ot->idname= "OBJECT_OT_speaker_add";
+
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= object_speaker_add_exec;
+       ot->poll= ED_operator_objectmode;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       ED_object_add_generic_props(ot, FALSE);
+}
+
 /* only used as menu */
 void OBJECT_OT_group_instance_add(wmOperatorType *ot)
 {
@@ -1600,6 +1635,18 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
                                        id->us--;
                                }
                                break;
+                       case OB_SPEAKER:
+                               // AUD_XXX TODO: always duplicate Speakers on speaker object duplication?
+                               if(dupflag!=0) {
+                                       ID_NEW_US2(obn->data )
+                                       else {
+                                               obn->data= copy_speaker(obn->data);
+                                               didit= 1;
+                                       }
+                                       id->us--;
+                               }
+                               break;
+
                }
 
                /* check if obdata is copied */
index 801880f..c308d36 100644 (file)
@@ -116,6 +116,7 @@ void OBJECT_OT_armature_add(struct wmOperatorType *ot);
 void OBJECT_OT_lamp_add(struct wmOperatorType *ot);
 void OBJECT_OT_effector_add(struct wmOperatorType *ot);
 void OBJECT_OT_camera_add(struct wmOperatorType *ot);
+void OBJECT_OT_speaker_add(struct wmOperatorType *ot);
 void OBJECT_OT_group_instance_add(struct wmOperatorType *ot);
 
 void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot);
index ff9b133..8f00f92 100644 (file)
@@ -117,6 +117,7 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_armature_add);
        WM_operatortype_append(OBJECT_OT_lamp_add);
        WM_operatortype_append(OBJECT_OT_camera_add);
+       WM_operatortype_append(OBJECT_OT_speaker_add);
        WM_operatortype_append(OBJECT_OT_add);
        WM_operatortype_append(OBJECT_OT_add_named);
        WM_operatortype_append(OBJECT_OT_effector_add);
index f21241b..ab9c699 100644 (file)
@@ -45,6 +45,7 @@
 #include "DNA_meta_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_world_types.h"
 #include "DNA_object_types.h"
 
@@ -971,8 +972,8 @@ static int track_set_exec(bContext *C, wmOperator *op)
                                data->tar = obact;
                                ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
                                
-                               /* Lamp and Camera track differently by default */
-                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA)
+                               /* Lamp, Camera and Speaker track differently by default */
+                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER)
                                        data->trackflag = TRACK_nZ;
                        }
                }
@@ -990,8 +991,8 @@ static int track_set_exec(bContext *C, wmOperator *op)
                                data->tar = obact;
                                ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
                                
-                               /* Lamp and Camera track differently by default */
-                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA) {
+                               /* Lamp, Camera and Speaker track differently by default */
+                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) {
                                        data->reserved1 = TRACK_nZ;
                                        data->reserved2 = UP_Y;
                                }
@@ -1011,8 +1012,8 @@ static int track_set_exec(bContext *C, wmOperator *op)
                                data->tar = obact;
                                ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
                                
-                               /* Lamp and Camera track differently by default */
-                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA) {
+                               /* Lamp, Camera and Speaker track differently by default */
+                               if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) {
                                        data->trackflag = TRACK_nZ;
                                        data->lockflag = LOCK_Y;
                                }
@@ -1481,6 +1482,9 @@ static void single_obdata_users(Main *bmain, Scene *scene, int flag)
                                        ob->data= copy_armature(ob->data);
                                        armature_rebuild_pose(ob, ob->data);
                                        break;
+                               case OB_SPEAKER:
+                                       ob->data= copy_speaker(ob->data);
+                                       break;
                                default:
                                        if (G.f & G_DEBUG)
                                                printf("ERROR single_obdata_users: can't copy %s\n", id->name);
index f0a0bcf..8744ec5 100644 (file)
@@ -376,8 +376,8 @@ static int bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
 void SOUND_OT_bake_animation(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Bake animation";
-       ot->description= "Bakes the animation cache so that it's up to date";
+       ot->name= "Update animation cache";
+       ot->description= "Updates the audio animation cache so that it's up to date";
        ot->idname= "SOUND_OT_bake_animation";
 
        /* api callbacks */
index 8e1a4b2..35500ac 100644 (file)
@@ -44,6 +44,7 @@
 #include "DNA_node_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_world_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_brush_types.h"
 
 #include "BKE_context.h"
@@ -188,6 +189,7 @@ static int buttons_context_path_data(ButsContextPath *path, int type)
        else if(RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) return 1;
        else if(RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) return 1;
        else if(RNA_struct_is_a(ptr->type, &RNA_Lamp) && (type == -1 || type == OB_LAMP)) return 1;
+       else if(RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1;
        /* try to get an object in the path, no pinning supported here */
        else if(buttons_context_path_object(path)) {
                ob= path->ptr[path->len-1].data;
@@ -648,7 +650,7 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
 
 const char *buttons_context_dir[] = {
        "world", "object", "mesh", "armature", "lattice", "curve",
-       "meta_ball", "lamp", "camera", "material", "material_slot",
+       "meta_ball", "lamp", "speaker", "camera", "material", "material_slot",
        "texture", "texture_slot", "bone", "edit_bone", "pose_bone", "particle_system", "particle_system_editable",
        "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
 
@@ -701,6 +703,10 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                set_pointer_type(path, result, &RNA_Camera);
                return 1;
        }
+       else if(CTX_data_equals(member, "speaker")) {
+               set_pointer_type(path, result, &RNA_Speaker);
+               return 1;
+       }
        else if(CTX_data_equals(member, "material")) {
                set_pointer_type(path, result, &RNA_Material);
                return 1;
index 6736230..e245e19 100644 (file)
@@ -1127,7 +1127,7 @@ void filelist_from_main(struct FileList *filelist)
        if( filelist->dir[0]==0) {
                
                /* make directories */
-               filelist->numfiles= 23;
+               filelist->numfiles= 24;
                filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
                
                for(a=0; a<filelist->numfiles; a++) {
@@ -1157,6 +1157,7 @@ void filelist_from_main(struct FileList *filelist)
                filelist->filelist[20].relname= BLI_strdup("Armature");
                filelist->filelist[21].relname= BLI_strdup("Action");
                filelist->filelist[22].relname= BLI_strdup("NodeTree");
+               filelist->filelist[23].relname= BLI_strdup("Speaker");
                filelist_sort(filelist, FILE_SORT_ALPHA);
        }
        else {
index 677e818..b6de8e7 100644 (file)
@@ -146,6 +146,7 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
                        case ANIMTYPE_DSPART:
                        case ANIMTYPE_DSMBALL:
                        case ANIMTYPE_DSARM:
+                       case ANIMTYPE_DSSPK:
                        {
                                /* for these channels, we only do AnimData */
                                if (ale->id && ale->adt) {
index 5e81148..08a4de8 100644 (file)
@@ -180,6 +180,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
                case ANIMTYPE_DSMESH:
                case ANIMTYPE_DSTEX:
                case ANIMTYPE_DSLAT:
+               case ANIMTYPE_DSSPK:
                {
                        /* sanity checking... */
                        if (ale->adt) {
index 40a9f80..c2dda69 100644 (file)
@@ -1080,6 +1080,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
                                tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_FONT); break;
                        case OB_SURF: 
                                tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SURFACE); break;
+                       case OB_SPEAKER:
+                               tselem_draw_icon_uibut(&arg, ICON_SPEAKER); break;
                        case OB_EMPTY: 
                                tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_EMPTY); break;
                
@@ -1123,6 +1125,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
                                tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break;
                        case ID_IM:
                                tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break;
+                       case ID_SPK:
                        case ID_SO:
                                tselem_draw_icon_uibut(&arg, ICON_SPEAKER); break;
                        case ID_AR:
index 57ee2fe..4525ea9 100644 (file)
@@ -135,7 +135,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
                                                break;
                                                
                                        case ID_ME: case ID_CU: case ID_MB: case ID_LT:
-                                       case ID_LA: case ID_AR: case ID_CA:
+                                       case ID_LA: case ID_AR: case ID_CA: case ID_SPK:
                                        case ID_MA: case ID_TE: case ID_IP: case ID_IM:
                                        case ID_SO: case ID_KE: case ID_WO: case ID_AC:
                                        case ID_NLA: case ID_TXT: case ID_GR:
index 12d1865..0c6ef67 100644 (file)
@@ -50,6 +50,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_world_types.h"
 #include "DNA_sequence_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_object_types.h"
 
 #include "BLI_blenlib.h"
@@ -714,6 +715,13 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
                        }
                }
                        break;
+               case ID_SPK:
+                       {
+                               Speaker *spk= (Speaker *)id;
+
+                               outliner_add_element(soops, &te->subtree, spk->adt, te, TSE_ANIM_DATA, 0);
+                       }
+                       break;
                case ID_WO:
                {
                        World *wrld= (World *)id;
index e6889f4..86d3ddc 100644 (file)
@@ -45,6 +45,7 @@
 #include "DNA_meta_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_smoke_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_world_types.h"
 #include "DNA_armature_types.h"
 
@@ -1491,6 +1492,52 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob
        }
 }
 
+/* flag similar to draw_object() */
+static void drawspeaker(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int flag)
+{
+       //Speaker *spk = ob->data;
+
+       float vec[3];
+       int i, j;
+
+       glEnable(GL_BLEND);
+
+       for(j = 0; j < 3; j++)
+       {
+               vec[2] = .25f * j -.125f;
+
+               glBegin(GL_LINE_LOOP);
+               for(i = 0; i < 16; i++)
+               {
+                       vec[0] = cos(M_PI * i / 8.0f) * (j == 0 ? .5f : .25f);
+                       vec[1] = sin(M_PI * i / 8.0f) * (j == 0 ? .5f : .25f);
+                       glVertex3fv(vec);
+               }
+               glEnd();
+       }
+
+       for(j = 0; j < 4; j++)
+       {
+               vec[0] = (((j + 1) % 2) * (j - 1)) * .5f;
+               vec[1] = ((j % 2) * (j - 2)) * .5f;
+               glBegin(GL_LINE_STRIP);
+               for(i = 0; i < 3; i++)
+               {
+                       if(i == 1)
+                       {
+                               vec[0] *= .5f;
+                               vec[1] *= .5f;
+                       }
+
+                       vec[2] = .25f * i -.125f;
+                       glVertex3fv(vec);
+               }
+               glEnd();
+       }
+
+       glDisable(GL_BLEND);
+}
+
 static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel)
 {
        BPoint *bp = lt->def;
@@ -5759,6 +5806,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                else {
 
                        if(ob->type==OB_LAMP) UI_ThemeColor(TH_LAMP);
+                       else if(ob->type==OB_SPEAKER) UI_ThemeColor(TH_SPEAKER);
                        else UI_ThemeColor(TH_WIRE);
 
                        if((scene->basact)==base) {
@@ -6006,6 +6054,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0 || (rv3d->persp==RV3D_CAMOB && v3d->camera==ob)) /* special exception for active camera */
                                drawcamera(scene, v3d, rv3d, ob, flag);
                        break;
+               case OB_SPEAKER:
+                       if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0)
+                               drawspeaker(scene, v3d, rv3d, ob, flag);
+                       break;
                case OB_LATTICE:
                        if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) {
                                drawlattice(scene, v3d, ob);
index 4cf9f47..8fd9f49 100644 (file)
@@ -178,6 +178,7 @@ typedef struct PreviewImage {
 #define ID_SCRN                MAKE_ID2('S', 'N') /* (depreciated?) */
 #define ID_VF          MAKE_ID2('V', 'F') /* VectorFont */
 #define ID_TXT         MAKE_ID2('T', 'X') /* Text */
+#define ID_SPK         MAKE_ID2('S', 'K') /* Speaker */
 #define ID_SO          MAKE_ID2('S', 'O') /* Sound */
 #define ID_GR          MAKE_ID2('G', 'R') /* Group */
 #define ID_ID          MAKE_ID2('I', 'D') /* (internal use only) */
index 3ead485..88e6786 100644 (file)
@@ -552,6 +552,7 @@ typedef enum eDopeSheet_FilterFlag {
        ADS_FILTER_NOARM                        = (1<<18),
        ADS_FILTER_NONTREE                      = (1<<19),
        ADS_FILTER_NOTEX                        = (1<<20),
+       ADS_FILTER_NOSPK                        = (1<<21),
        
                /* NLA-specific filters */
        ADS_FILTER_NLA_NOACT            = (1<<25),      /* if the AnimData block has no NLA data, don't include to just show Action-line */
@@ -561,7 +562,7 @@ typedef enum eDopeSheet_FilterFlag {
        ADS_FILTER_BY_FCU_NAME          = (1<<27),      /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */
        
                /* combination filters (some only used at runtime) */
-       ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART|ADS_FILTER_NOARM)
+       ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM|ADS_FILTER_NOMAT|ADS_FILTER_NOLAM|ADS_FILTER_NOCUR|ADS_FILTER_NOPART|ADS_FILTER_NOARM|ADS_FILTER_NOSPK)
 } eDopeSheet_FilterFlag;       
 
 /* DopeSheet general flags */
index dfc7d42..ffa8209 100644 (file)
@@ -306,6 +306,8 @@ typedef struct DupliObject {
 #define OB_LAMP                        10
 #define OB_CAMERA              11
 
+#define OB_SPEAKER             12
+
 // #define OB_WAVE                     21
 #define OB_LATTICE             22
 
diff --git a/source/blender/makesdna/DNA_speaker_types.h b/source/blender/makesdna/DNA_speaker_types.h
new file mode 100644 (file)
index 0000000..50cb62c
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $Id$ 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Jörg Müller.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef DNA_SPEAKER_TYPES_H
+#define DNA_SPEAKER_TYPES_H
+
+/** \file DNA_speaker_types.h
+ *  \ingroup DNA
+ */
+
+#include "DNA_ID.h"
+
+struct AnimData;
+struct bSound;
+
+typedef struct Speaker {
+       ID id;
+       struct AnimData *adt;   /* animation data (must be immediately after id for utilities to use it) */ 
+
+       struct bSound *sound;
+
+       short flag;
+       short pad1[3];
+
+       // not animatable properties
+       float volume_max;
+       float volume_min;
+       float distance_max;
+       float distance_reference;
+       float attenuation;
+       float cone_angle_outer;
+       float cone_angle_inner;
+       float cone_volume_outer;
+
+       // animatable properties
+       float volume;
+       float pitch;
+} Speaker;
+
+/* **************** SPEAKER ********************* */
+
+/* flag */
+#define SPK_DS_EXPAND   (1<<0)
+#define SPK_MUTED       (1<<1)
+#define SPK_RELATIVE    (1<<2)
+
+#endif /* DNA_SPEAKER_TYPES_H */
+
index 4757c11..4cf744a 100644 (file)
@@ -197,7 +197,7 @@ typedef struct ThemeSpace {
        char grid[4]; 
        
        char wire[4], select[4];
-       char lamp[4];
+       char lamp[4], speaker[4], pad2[4];
        char active[4], group[4], group_active[4], transform[4];
        char vertex[4], vertex_select[4];
        char edge[4], edge_select[4];
index 80299d4..16d5935 100644 (file)
@@ -132,6 +132,7 @@ const char *includefiles[] = {
        "DNA_anim_types.h",
        "DNA_boid_types.h",
        "DNA_smoke_types.h",
+       "DNA_speaker_types.h",
 
        // empty string to indicate end of includefiles
        ""
@@ -1196,4 +1197,5 @@ int main(int argc, char ** argv)
 #include "DNA_anim_types.h"
 #include "DNA_boid_types.h"
 #include "DNA_smoke_types.h"
+#include "DNA_speaker_types.h"
 /* end of list */
index f5d73bd..2add02a 100644 (file)
@@ -463,6 +463,7 @@ extern StructRNA RNA_SpaceTimeline;
 extern StructRNA RNA_SpaceUVEditor;
 extern StructRNA RNA_SpaceUserPreferences;
 extern StructRNA RNA_SpaceView3D;
+extern StructRNA RNA_Speaker;
 extern StructRNA RNA_SpeedControlSequence;
 extern StructRNA RNA_Spline;
 extern StructRNA RNA_SplineIKConstraint;
index cb593e7..7d7c553 100644 (file)
@@ -78,6 +78,7 @@ set(DEFSRC
        rna_smoke.c
        rna_sound.c
        rna_space.c
+       rna_speaker.c
        rna_test.c
        rna_text.c
        rna_texture.c
index 7da538e..feb926f 100644 (file)
@@ -2461,6 +2461,7 @@ static RNAProcessItem PROCESS_ITEMS[]= {
        {"rna_sequencer.c", "rna_sequencer_api.c", RNA_def_sequencer},
        {"rna_smoke.c", NULL, RNA_def_smoke},
        {"rna_space.c", NULL, RNA_def_space},
+       {"rna_speaker.c", NULL, RNA_def_speaker},
        {"rna_test.c", NULL, RNA_def_test},
        {"rna_text.c", NULL, RNA_def_text},
        {"rna_timeline.c", NULL, RNA_def_timeline_marker},
index 3ce84e3..48b5592 100644 (file)
@@ -66,6 +66,7 @@ EnumPropertyItem id_type_items[] = {
        {ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""},
        {ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""},
        {ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""},
+       {ID_SPK, "SPEAKER", ICON_SPEAKER, "Speaker", ""},
        {ID_SO, "SOUND", ICON_PLAY_AUDIO, "Sound", ""},
        {ID_TXT, "TEXT", ICON_TEXT, "Text", ""},
        {ID_TE, "TEXTURE", ICON_TEXTURE_DATA, "Texture", ""},
@@ -136,6 +137,7 @@ short RNA_type_to_ID_code(StructRNA *type)
        if(RNA_struct_is_a(type, &RNA_ParticleSettings)) return ID_PA;
        if(RNA_struct_is_a(type, &RNA_Scene)) return ID_SCE;
        if(RNA_struct_is_a(type, &RNA_Screen)) return ID_SCR;
+       if(RNA_struct_is_a(type, &RNA_Speaker)) return ID_SPK;
        if(RNA_struct_is_a(type, &RNA_Sound)) return ID_SO;
        if(RNA_struct_is_a(type, &RNA_Text)) return ID_TXT;
        if(RNA_struct_is_a(type, &RNA_Texture)) return ID_TE;
@@ -169,6 +171,7 @@ StructRNA *ID_code_to_RNA_type(short idcode)
                case ID_PA: return &RNA_ParticleSettings;
                case ID_SCE: return &RNA_Scene;
                case ID_SCR: return &RNA_Screen;
+               case ID_SPK: return &RNA_Speaker;
                case ID_SO: return &RNA_Sound;
                case ID_TXT: return &RNA_Text;
                case ID_TE: return &RNA_Texture;
index 5258682..31a9d57 100644 (file)
@@ -416,6 +416,12 @@ static void rna_def_dopesheet(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Display Node", "Include visualization of Node related Animation data");
        RNA_def_property_ui_icon(prop, ICON_NODETREE, 0);
        RNA_def_property_update(prop, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
+
+       prop= RNA_def_property(srna, "show_speakers", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOSPK);
+       RNA_def_property_ui_text(prop, "Display Speaker", "Include visualization of Speaker related Animation data");
+       RNA_def_property_ui_icon(prop, ICON_SPEAKER, 0);
+       RNA_def_property_update(prop, NC_ANIMATION|ND_ANIMCHAN|NA_EDITED, NULL);
 }
 
 static void rna_def_action_group(BlenderRNA *brna)
index 9175806..f0028fb 100644 (file)
@@ -168,6 +168,7 @@ void RNA_def_sensor(struct BlenderRNA *brna);
 void RNA_def_sequencer(struct BlenderRNA *brna);
 void RNA_def_smoke(struct BlenderRNA *brna);
 void RNA_def_space(struct BlenderRNA *brna);
+void RNA_def_speaker(struct BlenderRNA *brna);
 void RNA_def_test(struct BlenderRNA *brna);
 void RNA_def_text(struct BlenderRNA *brna);
 void RNA_def_texture(struct BlenderRNA *brna);
@@ -279,6 +280,7 @@ void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop);
+void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop);
 void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop);
index bb13a3b..021aa96 100644 (file)
@@ -187,6 +187,12 @@ static void rna_Main_text_begin(CollectionPropertyIterator *iter, PointerRNA *pt
        rna_iterator_listbase_begin(iter, &bmain->text, NULL);
 }
 
+static void rna_Main_speaker_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+       Main *bmain= (Main*)ptr->data;
+       rna_iterator_listbase_begin(iter, &bmain->speaker, NULL);
+}
+
 static void rna_Main_sound_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
        Main *bmain= (Main*)ptr->data;
@@ -297,6 +303,7 @@ void RNA_def_main(BlenderRNA *brna)
                {"shape_keys", "Key", "rna_Main_key_begin", "Shape Keys", "Shape Key datablocks.", NULL},
                {"scripts", "ID", "rna_Main_script_begin", "Scripts", "Script datablocks (DEPRECATED).", NULL},
                {"texts", "Text", "rna_Main_text_begin", "Texts", "Text datablocks.", RNA_def_main_texts},
+               {"speakers", "Speaker", "rna_Main_speaker_begin", "Speakers", "Speaker datablocks.", RNA_def_main_speakers},
                {"sounds", "Sound", "rna_Main_sound_begin", "Sounds", "Sound datablocks.", RNA_def_main_sounds},
                {"armatures", "Armature", "rna_Main_armature_begin", "Armatures", "Armature datablocks.", RNA_def_main_armatures},
                {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks.", RNA_def_main_actions},
index 8ac620c..7b95129 100644 (file)
@@ -71,6 +71,7 @@
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
+#include "DNA_speaker_types.h"
 #include "DNA_text_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_group_types.h"
@@ -147,6 +148,9 @@ Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const cha
                        case ID_LA:
                                type= OB_LAMP;
                                break;
+                       case ID_SPK:
+                               type= OB_SPEAKER;
+                               break;
                        case ID_CA:
                                type= OB_CAMERA;
                                break;
@@ -406,6 +410,22 @@ void rna_Main_groups_remove(Main *bmain, Group *group)
        /* XXX python now has invalid pointer? */
 }
 
+Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name)
+{
+       Speaker *speaker= add_speaker(name);
+       id_us_min(&speaker->id);
+       return speaker;
+}
+void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker *speaker)
+{
+       if(ID_REAL_USERS(speaker) <= 0)
+               free_libblock(&bmain->speaker, speaker);
+       else
+               BKE_reportf(reports, RPT_ERROR, "Speaker \"%s\" must have zero users to be removed, found %d.", speaker->id.name+2, ID_REAL_USERS(speaker));
+
+       /* XXX python now has invalid pointer? */
+}
+
 Text *rna_Main_texts_new(Main *UNUSED(bmain), const char *name)
 {
        return add_empty_text(name);
@@ -502,6 +522,7 @@ void rna_Main_groups_tag(Main *bmain, int value) { tag_main_lb(&bmain->group, va
 void rna_Main_shape_keys_tag(Main *bmain, int value) { tag_main_lb(&bmain->key, value); }
 void rna_Main_scripts_tag(Main *bmain, int value) { tag_main_lb(&bmain->script, value); }
 void rna_Main_texts_tag(Main *bmain, int value) { tag_main_lb(&bmain->text, value); }
+void rna_Main_speakers_tag(Main *bmain, int value) { tag_main_lb(&bmain->speaker, value); }
 void rna_Main_sounds_tag(Main *bmain, int value) { tag_main_lb(&bmain->sound, value); }
 void rna_Main_armatures_tag(Main *bmain, int value) { tag_main_lb(&bmain->armature, value); }
 void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, value); }
@@ -1076,6 +1097,37 @@ void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop)
        parm= RNA_def_boolean(func, "value", 0, "Value", "");
        RNA_def_property_flag(parm, PROP_REQUIRED);
 }
+
+void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop)
+{
+       StructRNA *srna;
+       FunctionRNA *func;
+       PropertyRNA *parm;
+
+       RNA_def_property_srna(cprop, "BlendDataSpeakers");
+       srna= RNA_def_struct(brna, "BlendDataSpeakers", NULL);
+       RNA_def_struct_sdna(srna, "Main");
+       RNA_def_struct_ui_text(srna, "Main Speakers", "Collection of speakers");
+
+       func= RNA_def_function(srna, "new", "rna_Main_speakers_new");
+       RNA_def_function_ui_description(func, "Add a new speaker to the main database");
+       parm= RNA_def_string(func, "name", "Speaker", 0, "", "New name for the datablock.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       /* return type */
+       parm= RNA_def_pointer(func, "speaker", "Speaker", "", "New speaker datablock.");
+       RNA_def_function_return(func, parm);
+
+       func= RNA_def_function(srna, "remove", "rna_Main_speakers_remove");
+       RNA_def_function_flag(func, FUNC_USE_REPORTS);
+       RNA_def_function_ui_description(func, "Remove a speaker from the current blendfile.");
+       parm= RNA_def_pointer(func, "speaker", "Speaker", "", "Speaker to remove.");
+       RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
+
+       func= RNA_def_function(srna, "tag", "rna_Main_speakers_tag");
+       parm= RNA_def_boolean(func, "value", 0, "Value", "");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
 void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop)
 {
        StructRNA *srna;
index 76bbfcb..3371f19 100644 (file)
@@ -115,6 +115,7 @@ EnumPropertyItem object_type_items[] = {
        {0, "", 0, NULL, NULL},
        {OB_CAMERA, "CAMERA", 0, "Camera", ""},
        {OB_LAMP, "LAMP", 0, "Lamp", ""},
+       {OB_SPEAKER, "SPEAKER", 0, "Speaker", ""},
        {0, NULL, 0, NULL, NULL}};
 
 EnumPropertyItem object_type_curve_items[] = {
@@ -365,6 +366,7 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr)
                case OB_CAMERA: return &RNA_Camera;
                case OB_LATTICE: return &RNA_Lattice;
                case OB_ARMATURE: return &RNA_Armature;
+               case OB_SPEAKER: return &RNA_Speaker;
                default: return &RNA_ID;
        }
 }
diff --git a/source/blender/makesrna/intern/rna_speaker.c b/source/blender/makesrna/intern/rna_speaker.c
new file mode 100644 (file)
index 0000000..60208de
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Jörg Müller.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/makesrna/intern/rna_speaker.c
+ *  \ingroup RNA
+ */
+
+
+#include <stdlib.h>
+
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "DNA_speaker_types.h"
+#include "DNA_sound_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_depsgraph.h"
+#include "BKE_main.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+
+#else
+
+static void rna_def_speaker(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna= RNA_def_struct(brna, "Speaker", "ID");
+       RNA_def_struct_ui_text(srna, "Speaker", "Speaker datablock for 3D audio speaker objects");
+       RNA_def_struct_ui_icon(srna, ICON_SPEAKER);
+
+       prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_MUTED);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Mute", "Mutes the speaker.");
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       /* This shouldn't be changed actually, hiding it!
+       prop= RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_RELATIVE);
+       RNA_def_property_ui_text(prop, "Relative", "Whether the source is relative to the camera or not.");
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");*/
+
+       prop= RNA_def_property(srna, "sound", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "sound");
+       RNA_def_property_struct_type(prop, "Sound");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Sound", "Sound datablock used by this speaker.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_sound_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "volume_max", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "volume_max");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Maximum Volume", "Maximum volume, no matter how near the object is.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_max_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "volume_min", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "volume_min");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Minimum Volume", "Minimum volume, no matter how far away the object is.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_min_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "distance_max", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "distance_max");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_text(prop, "Maximum Distance", "Maximum distance for volume calculation, no matter how far away the object is.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_distance_max_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "distance_reference", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "distance_reference");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_text(prop, "Reference Distance", "Reference distance at which volume is 100 %.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_distance_reference_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "attenuation");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, FLT_MAX);
+       RNA_def_property_ui_text(prop, "Attenuation", "How strong the distance affects volume, depending on distance model.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_attenuation_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "cone_angle_outer", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "cone_angle_outer");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, 360.0f);
+       RNA_def_property_ui_text(prop, "Outer Cone Angle", "Outer angle of the cone in degrees, outside this cone the volume is the outer cone volume, between inner and outer cone the volume is interpolated.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_angle_outer_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "cone_angle_inner", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "cone_angle_inner");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, 360.0f);
+       RNA_def_property_ui_text(prop, "Inner Cone Angle", "Inner angle of the cone in degrees, inside the cone the volume is 100 %.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_angle_inner_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "cone_volume_outer", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "cone_volume_outer");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Outer Cone Volume", "Volume outside the outer cone.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_volume_outer_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "volume");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Volume", "How loud the sound is.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       prop= RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "pitch");
+       RNA_def_property_range(prop, 0.1f, 10.0f);
+       RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound.");
+       // RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_pitch_set", NULL);
+       // RNA_def_property_update(prop, 0, "rna_Speaker_update");
+
+       /* common */
+       rna_def_animdata_common(srna);
+}
+
+
+void RNA_def_speaker(BlenderRNA *brna)
+{
+       rna_def_speaker(brna);
+}
+
+#endif
+
index 4a4b712..36a6762 100644 (file)
@@ -919,6 +919,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Lamp", "");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
 
+       prop= RNA_def_property(srna, "speaker", PROP_FLOAT, PROP_COLOR_GAMMA);
+       RNA_def_property_array(prop, 3);
+       RNA_def_property_ui_text(prop, "Speaker", "");
+       RNA_def_property_update(prop, 0, "rna_userdef_update");
+
        prop= RNA_def_property(srna, "object_selected", PROP_FLOAT, PROP_COLOR_GAMMA);
        RNA_def_property_float_sdna(prop, NULL, "select");
        RNA_def_property_array(prop, 3);