Mesh Face Info Select addon: added wiki link
[blender-addons-contrib.git] / space_view3d_game_props_visualiser.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21
22 bl_info = {
23     'name': 'Game Property Visualiser',
24     'author': 'Bartius Crouch/Vilem Novak',
25     'version': (2,5),
26     'blender': (2, 5, 3),
27     'location': 'View3D > Properties panel > Display tab',
28     'description': 'Display the game properties next to selected objects '\
29         'in the 3d-view',
30     'warning': 'Script is returning errors',
31     'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Game_Property_Visualiser',
32     'tracker_url': 'http://projects.blender.org/tracker/?func=detail&aid=22607&group_id=153&atid=468',
33     'category': '3D View'}
34
35 """
36 Displays game properties next to selected objects(under name)
37
38 How to use:
39     just toggle the button 'Visualise game props' in the right side panel
40 """
41
42 import bgl
43 import blf
44 import bpy
45 import mathutils
46
47
48 # calculate locations and store them as ID property in the mesh
49 def calc_callback(self, context):
50     # polling
51     if context.mode == 'EDIT_MESH':
52         return
53     
54     # get screen information
55     mid_x = context.region.width/2.0
56     mid_y = context.region.height/2.0
57     width = context.region.width
58     height = context.region.height
59     
60     # get matrices
61     view_mat = context.space_data.region_3d.perspective_matrix
62
63     ob_mat = context.active_object.matrix_world
64     total_mat = view_mat*ob_mat
65     
66     # calculate location info
67     texts = []
68     
69     # uncomment 2 lines below, to enable live updating of the selection
70     #ob=context.active_object
71     for ob in context.selected_objects:
72         locs = []
73         ob_mat = ob.matrix_world
74         total_mat = view_mat*ob_mat
75  
76         for p in ob.game.properties:
77             d=0.0#{'data':p.name+':'+str(p.value)}
78             # print (d)
79             locs.append([ mathutils.Vector([0,0,0]).resize_4d()])
80     
81     
82         for loc in locs:
83     
84             vec = loc[0]*total_mat # order is important
85             # dehomogenise
86             vec = mathutils.Vector((vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3]))
87             x = int(mid_x + vec[0]*width/2.0)
88             y = int(mid_y + vec[1]*height/2.0)
89             texts+=[x, y]
90         
91
92     # store as ID property in mesh
93     #print (texts)
94     context.scene['GamePropsVisualiser'] = texts
95
96
97 # draw in 3d-view
98 def draw_callback(self, context):
99     # polling
100     if context.mode == 'EDIT_MESH':
101         return
102     # retrieving ID property data
103     try:
104         #print(context.scene['GamePropsVisualiser'])
105         texts = context.scene['GamePropsVisualiser']
106         
107     except:
108         return
109     if not texts:
110         return
111     
112     # draw
113     i=0
114
115     blf.size(0, 12, 72)
116    
117         
118     bgl.glColor3f(1.0,1.0,1.0)
119     for ob in bpy.context.selected_objects:
120         for pi,p in enumerate(ob.game.properties):
121             blf.position(0, texts[i], texts[i+1]-(pi+1)*14, 0)
122             if p.type=='FLOAT':
123                 t=p.name+':  '+ str('%g'% p.value)
124             else:    
125                 t=p.name+':  '+ str(p.value)
126             blf.draw(0, t)
127             i+=2
128
129
130 # operator
131 class GamePropertyVisualiser(bpy.types.Operator):
132     bl_idname = "view3d.game_props_visualiser"
133     bl_label = "Game Properties Visualiser"
134     bl_description = "Toggle the visualisation of game properties"
135     
136     @classmethod
137     def poll(cls, context):
138         return context.mode!='EDIT_MESH'
139     
140     def modal(self, context, event):
141         context.area.tag_redraw()
142
143         # removal of callbacks when operator is called again
144         #print(context.scene.display_game_properties)
145         if context.scene.display_game_properties == -1:
146            # print('deinit2')
147
148             context.scene.display_game_properties = 0
149             context.region.callback_remove(self.handle1)
150             context.region.callback_remove(self.handle2)
151             context.scene.display_game_properties = 0
152             
153             return {'FINISHED'}
154         
155         return {'PASS_THROUGH'}
156     
157     def invoke(self, context, event):
158         if context.area.type == 'VIEW_3D':
159             print(context.scene.display_game_properties)
160             if context.scene.display_game_properties == 0 or context.scene.display_game_properties == -1:
161                 print('init')
162                 # operator is called for the first time, start everything
163                 context.scene.display_game_properties = 1
164                 context.window_manager.modal_handler_add(self)
165                 self.handle1 = context.region.callback_add(calc_callback,
166                     (self, context), 'POST_VIEW')
167                 self.handle2 = context.region.callback_add(draw_callback,
168                     (self, context), 'POST_PIXEL')
169                 return {'RUNNING_MODAL'}
170             else:
171                 # operator is called again, stop displaying
172                 context.scene.display_game_properties = -1
173                 #print(dir(self))
174                 #
175                 return {'RUNNING_MODAL'}
176         else:
177             self.report({'WARNING'}, "View3D not found, can't run operator")
178             return {'CANCELLED'}
179
180
181 # defining the panel
182 def menu_func(self, context):
183     col = self.layout.column(align=True)
184     col.operator(GamePropertyVisualiser.bl_idname, text="Visualise game props")
185     self.layout.separator()
186
187
188 def register():
189     bpy.types.Scene.display_game_properties = bpy.props.IntProperty(name='Visualise Game Poperties')
190     bpy.types.VIEW3D_PT_view3d_display.prepend(menu_func)
191
192 def unregister():
193     del bpy.types.Scene.display_game_properties
194     bpy.types.VIEW3D_PT_view3d_display.remove(menu_func)
195
196 if __name__ == "__main__":
197     register()