diff options
32 files changed, 757 insertions, 371 deletions
diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index 1fc1d219f57..04e87a23ed1 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -9,10 +9,10 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib' BF_PYTHON = LIBDIR + '/python' -BF_PYTHON_VERSION = '2.5' +BF_PYTHON_VERSION = '2.6' BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = 'python' -BF_PYTHON_LIB = 'python25' +BF_PYTHON_LIB = 'python26' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' WITH_BF_OPENAL = True diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py index 0edc70a874b..739b02bcbb3 100644 --- a/release/scripts/export_obj.py +++ b/release/scripts/export_obj.py @@ -181,12 +181,89 @@ def copy_images(dest_dir): copyCount+=1 print '\tCopied %d images' % copyCount + +def test_nurbs_compat(ob): + if ob.type != 'Curve': + return False + + for nu in ob.data: + if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier + return True + + return False + +def write_nurb(file, ob, ob_mat): + tot_verts = 0 + cu = ob.data + + # use negative indices + Vector = Blender.Mathutils.Vector + for nu in cu: + + if nu.type==0: DEG_ORDER_U = 1 + else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct + + if nu.type==1: + print "\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported" + continue + + if nu.knotsV: + print "\tWarning, surface:", ob.name, "only poly and nurbs curves supported" + continue + + if len(nu) <= DEG_ORDER_U: + print "\tWarning, orderU is lower then vert count, skipping:", ob.name + continue + + pt_num = 0 + do_closed = (nu.flagU & 1) + do_endpoints = (do_closed==0) and (nu.flagU & 2) + + for pt in nu: + pt = Vector(pt[0], pt[1], pt[2]) * ob_mat + file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2])) + pt_num += 1 + tot_verts += pt_num + + file.write('g %s\n' % (fixName(ob.name))) # fixName(ob.getData(1)) could use the data name too + file.write('cstype bspline\n') # not ideal, hard coded + file.write('deg %d\n' % DEG_ORDER_U) # not used for curves but most files have it still + + curve_ls = [-(i+1) for i in xrange(pt_num)] + + # 'curv' keyword + if do_closed: + if DEG_ORDER_U == 1: + pt_num += 1 + curve_ls.append(-1) + else: + pt_num += DEG_ORDER_U + curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U] + + file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve + + # 'parm' keyword + tot_parm = (DEG_ORDER_U + 1) + pt_num + tot_parm_div = float(tot_parm-1) + parm_ls = [(i/tot_parm_div) for i in xrange(tot_parm)] + + if do_endpoints: # end points, force param + for i in xrange(DEG_ORDER_U+1): + parm_ls[i] = 0.0 + parm_ls[-(1+i)] = 1.0 + + file.write('parm u %s\n' % ' '.join( [str(i) for i in parm_ls] )) + + file.write('end\n') + + return tot_verts + def write(filename, objects,\ EXPORT_TRI=False, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_NORMALS_HQ=False,\ EXPORT_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ EXPORT_APPLY_MODIFIERS=True, EXPORT_ROTX90=True, EXPORT_BLEN_OBS=True,\ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False, EXPORT_KEEP_VERT_ORDER=False,\ -EXPORT_POLYGROUPS=False): +EXPORT_POLYGROUPS=False, EXPORT_CURVE_AS_NURBS=True): ''' Basic write function. The context and options must be alredy set This can be accessed externaly @@ -266,6 +343,17 @@ EXPORT_POLYGROUPS=False): # Get all meshes for ob_main in objects: for ob, ob_mat in BPyObject.getDerivedObjects(ob_main): + + # Nurbs curve support + if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob): + if EXPORT_ROTX90: + ob_mat = ob_mat * mat_xrot90 + + totverts += write_nurb(file, ob, ob_mat) + + continue + # end nurbs + # Will work for non meshes now! :) # getMeshFromObject(ob, container_mesh=None, apply_modifiers=True, vgroups=True, scn=None) me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, EXPORT_POLYGROUPS, scn) @@ -585,7 +673,7 @@ def write_ui(filename): EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS EXPORT_APPLY_MODIFIERS = Draw.Create(0) EXPORT_ROTX90 = Draw.Create(1) @@ -604,6 +692,7 @@ def write_ui(filename): EXPORT_GROUP_BY_MAT = Draw.Create(0) EXPORT_KEEP_VERT_ORDER = Draw.Create(1) EXPORT_POLYGROUPS = Draw.Create(0) + EXPORT_CURVE_AS_NURBS = Draw.Create(1) # Old UI @@ -693,7 +782,7 @@ def write_ui(filename): EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\ EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\ EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS Draw.Label('Context...', ui_x+9, ui_y+239, 220, 20) Draw.BeginAlign() @@ -726,6 +815,8 @@ def write_ui(filename): Draw.EndAlign() EXPORT_POLYGROUPS = Draw.Toggle('Polygroups', EVENT_REDRAW, ui_x+9, ui_y+95, 120, 20, EXPORT_POLYGROUPS.val, 'Export vertex groups as OBJ groups (one group per face approximation).') + EXPORT_CURVE_AS_NURBS = Draw.Toggle('Nurbs', EVENT_NONE, ui_x+139, ui_y+95, 100, 20, EXPORT_CURVE_AS_NURBS.val, 'Export 3D nurbs curves and polylines as OBJ curves, (bezier not supported).') + Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20) Draw.BeginAlign() @@ -779,6 +870,7 @@ def write_ui(filename): EXPORT_GROUP_BY_MAT = EXPORT_GROUP_BY_MAT.val EXPORT_KEEP_VERT_ORDER = EXPORT_KEEP_VERT_ORDER.val EXPORT_POLYGROUPS = EXPORT_POLYGROUPS.val + EXPORT_CURVE_AS_NURBS = EXPORT_CURVE_AS_NURBS.val base_name, ext = splitExt(filename) @@ -828,7 +920,7 @@ def write_ui(filename): EXPORT_COPY_IMAGES, EXPORT_APPLY_MODIFIERS,\ EXPORT_ROTX90, EXPORT_BLEN_OBS,\ EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER,\ - EXPORT_POLYGROUPS) + EXPORT_POLYGROUPS, EXPORT_CURVE_AS_NURBS) Blender.Set('curframe', orig_frame) diff --git a/release/scripts/flt_properties.py b/release/scripts/flt_properties.py index 4c841e9c0c0..b9d93b5f52d 100644 --- a/release/scripts/flt_properties.py +++ b/release/scripts/flt_properties.py @@ -1,4 +1,3 @@ -#!BPY # flt_properties.py. For setting default OpenFLight ID property types # Copyright (C) 2007 Blender Foundation # diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py index 31501173fda..d88f06a2a47 100644 --- a/release/scripts/import_obj.py +++ b/release/scripts/import_obj.py @@ -2,7 +2,7 @@ """ Name: 'Wavefront (.obj)...' -Blender: 248 +Blender: 249 Group: 'Import' Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.' """ @@ -40,7 +40,7 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- -from Blender import * +from Blender import Mesh, Draw, Window, Texture, Material, sys import bpy import BPyMesh import BPyImage @@ -166,12 +166,13 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_ del temp_mtl #Create new materials - for name in unique_materials.iterkeys(): - unique_materials[name]= bpy.data.materials.new(name) - - unique_material_images[name]= None, False # assign None to all material images to start with, add to later. + for name in unique_materials: # .keys() + if name != None: + unique_materials[name]= bpy.data.materials.new(name) + unique_material_images[name]= None, False # assign None to all material images to start with, add to later. unique_materials[None]= None + unique_material_images[None]= None, False for libname in material_libs: mtlpath= DIR + libname @@ -536,6 +537,98 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l me.addVertGroup(group_name) me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE) + +def create_nurbs(scn, context_nurbs, vert_loc, new_objects): + ''' + Add nurbs object to blender, only support one type at the moment + ''' + deg = context_nurbs.get('deg', (3,)) + curv_range = context_nurbs.get('curv_range', None) + curv_idx = context_nurbs.get('curv_idx', []) + parm_u = context_nurbs.get('parm_u', []) + parm_v = context_nurbs.get('parm_v', []) + name = context_nurbs.get('name', 'ObjNurb') + cstype = context_nurbs.get('cstype', None) + + if cstype == None: + print '\tWarning, cstype not found' + return + if cstype != 'bspline': + print '\tWarning, cstype is not supported (only bspline)' + return + if not curv_idx: + print '\tWarning, curv argument empty or not set' + return + if len(deg) > 1 or parm_v: + print '\tWarning, surfaces not supported' + return + + cu = bpy.data.curves.new(name, 'Curve') + cu.flag |= 1 # 3D curve + + nu = None + for pt in curv_idx: + + pt = vert_loc[pt] + pt = (pt[0], pt[1], pt[2], 1.0) + + if nu == None: + nu = cu.appendNurb(pt) + else: + nu.append(pt) + + nu.orderU = deg[0]+1 + + # get for endpoint flag from the weighting + if curv_range and len(parm_u) > deg[0]+1: + do_endpoints = True + for i in xrange(deg[0]+1): + + if abs(parm_u[i]-curv_range[0]) > 0.0001: + do_endpoints = False + break + + if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001: + do_endpoints = False + break + + else: + do_endpoints = False + + if do_endpoints: + nu.flagU |= 2 + + + # close + ''' + do_closed = False + if len(parm_u) > deg[0]+1: + for i in xrange(deg[0]+1): + #print curv_idx[i], curv_idx[-(i+1)] + + if curv_idx[i]==curv_idx[-(i+1)]: + do_closed = True + break + + if do_closed: + nu.flagU |= 1 + ''' + + ob = scn.objects.new(cu) + new_objects.append(ob) + + +def strip_slash(line_split): + if line_split[-1][-1]== '\\': + if len(line_split[-1])==1: + line_split.pop() # remove the \ item + else: + line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number + return True + return False + + + def get_float_func(filepath): ''' find the float function for this obj file @@ -561,6 +654,7 @@ def load_obj(filepath, SPLIT_OBJECTS= True, SPLIT_GROUPS= True, SPLIT_MATERIALS= True, + ROTATE_X90= True, IMAGE_SEARCH=True, POLYGROUPS=False): ''' @@ -590,6 +684,11 @@ def load_obj(filepath, context_smooth_group= None context_object= None context_vgroup = None + + # Nurbs + context_nurbs = {} + nurbs = [] + context_parm = '' # used by nurbs too but could be used elsewhere has_ngons= False # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0 @@ -604,7 +703,7 @@ def load_obj(filepath, # it means they are multiline- # since we use xreadline we cant skip to the next line # so we need to know weather - multi_line_face= False + context_multi_line= '' print '\tparsing obj file "%s"...' % filepath, time_sub= sys.time() @@ -627,12 +726,11 @@ def load_obj(filepath, # Handel faces lines (as faces) and the second+ lines of fa multiline face here # use 'f' not 'f ' because some objs (very rare have 'fo ' for faces) - elif line.startswith('f') or (line.startswith('l ') and CREATE_EDGES) or multi_line_face: + elif line.startswith('f') or context_multi_line == 'f': - if multi_line_face: + if context_multi_line: # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face line_split= line.split() - multi_line_face= False else: line_split= line[2:].split() @@ -648,14 +746,10 @@ def load_obj(filepath, context_object\ )) - if line_split[-1][-1]== '\\': - multi_line_face= True - if len(line_split[-1])==1: - line_split.pop() # remove the \ item - else: - line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number - - isline= line.startswith('l') + if strip_slash(line_split): + context_multi_line = 'f' + else: + context_multi_line = '' for v in line_split: obj_vert= v.split('/') @@ -672,24 +766,60 @@ def load_obj(filepath, face_vert_loc_indicies.append(vert_loc_index) - if not isline: - if len(obj_vert)>1 and obj_vert[1]: - # formatting for faces with normals and textures us - # loc_index/tex_index/nor_index - - vert_tex_index= int(obj_vert[1])-1 - # Make relative negative vert indicies absolute - if vert_tex_index < 0: - vert_tex_index= len(verts_tex) + vert_tex_index + 1 - - face_vert_tex_indicies.append(vert_tex_index) - else: - # dummy - face_vert_tex_indicies.append(0) + if len(obj_vert)>1 and obj_vert[1]: + # formatting for faces with normals and textures us + # loc_index/tex_index/nor_index + + vert_tex_index= int(obj_vert[1])-1 + # Make relative negative vert indicies absolute + if vert_tex_index < 0: + vert_tex_index= len(verts_tex) + vert_tex_index + 1 + + face_vert_tex_indicies.append(vert_tex_index) + else: + # dummy + face_vert_tex_indicies.append(0) if len(face_vert_loc_indicies) > 4: has_ngons= True + + elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'): + # very similar to the face load function above with some parts removed + if context_multi_line: + # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face + line_split= line.split() + + else: + line_split= line[2:].split() + face_vert_loc_indicies= [] + face_vert_tex_indicies= [] + + # Instance a face + faces.append((\ + face_vert_loc_indicies,\ + face_vert_tex_indicies,\ + context_material,\ + context_smooth_group,\ + context_object\ + )) + + if strip_slash(line_split): + context_multi_line = 'l' + else: + context_multi_line = '' + + isline= line.startswith('l') + + for v in line_split: + vert_loc_index= int(v)-1 + + # Make relative negative vert indicies absolute + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + face_vert_loc_indicies.append(vert_loc_index) + elif line.startswith('s'): if CREATE_SMOOTH_GROUPS: context_smooth_group= line_value(line.split()) @@ -720,6 +850,63 @@ def load_obj(filepath, unique_materials[context_material]= None elif line.startswith('mtllib'): # usemap or usemat material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line + + + # Nurbs support + elif line.startswith('cstype '): + context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline' + elif line.startswith('curv ') or context_multi_line == 'curv': + line_split= line.split() + + curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline + + if not context_multi_line: + context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2]) + line_split[0:3] = [] # remove first 3 items + + if strip_slash(line_split): + context_multi_line = 'curv' + else: + context_multi_line = '' + + + for i in line_split: + vert_loc_index = int(i)-1 + + if vert_loc_index < 0: + vert_loc_index= len(verts_loc) + vert_loc_index + 1 + + curv_idx.append(vert_loc_index) + + elif line.startswith('parm') or context_multi_line == 'parm': + line_split= line.split() + + if context_multi_line: + context_multi_line = '' + else: + context_parm = line_split[1] + line_split[0:2] = [] # remove first 2 + + if strip_slash(line_split): + context_multi_line = 'parm' + else: + context_multi_line = '' + + if context_parm.lower() == 'u': + context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] ) + elif context_parm.lower() == 'v': # surfaces not suported yet + context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] ) + # else: # may want to support other parm's ? + + elif line.startswith('deg '): + context_nurbs['deg']= [int(i) for i in line.split()[1:]] + elif line.startswith('end'): + # Add the nurbs curve + if context_object: + context_nurbs['name'] = context_object + nurbs.append(context_nurbs) + context_nurbs = {} + context_parm = '' ''' # How to use usemap? depricated? elif line.startswith('usema'): # usemap or usemat @@ -739,6 +926,8 @@ def load_obj(filepath, print '%.4f sec' % (time_new-time_sub) time_sub= time_new + if not ROTATE_X90: + verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc] # deselect all scn = bpy.data.scenes.active @@ -754,6 +943,11 @@ def load_obj(filepath, # Create meshes from the data, warning 'vertex_groups' wont support splitting create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname) + # nurbs support + for context_nurbs in nurbs: + create_nurbs(scn, context_nurbs, verts_loc, new_objects) + + axis_min= [ 1000000000]*3 axis_max= [-1000000000]*3 @@ -775,6 +969,11 @@ def load_obj(filepath, for ob in new_objects: ob.setSize(scale, scale, scale) + # Better rotate the vert locations + #if not ROTATE_X90: + # for ob in new_objects: + # ob.RotX = -1.570796326794896558 + time_new= sys.time() print '%.4f sec' % (time_new-time_sub) @@ -788,7 +987,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): if BPyMessages.Error_NoFile(filepath): return - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 CREATE_SMOOTH_GROUPS= Draw.Create(0) CREATE_FGONS= Draw.Create(1) @@ -800,6 +999,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): IMAGE_SEARCH= Draw.Create(1) POLYGROUPS= Draw.Create(0) KEEP_VERT_ORDER= Draw.Create(1) + ROTATE_X90= Draw.Create(1) # Get USER Options @@ -886,7 +1086,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): ui_x -= 165 ui_y -= 90 - global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER + global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90 Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21) Draw.BeginAlign() @@ -897,13 +1097,15 @@ def load_obj_ui(filepath, BATCH_LOAD= False): Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20) Draw.BeginAlign() - SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 70, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) - SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+79, ui_y+89, 70, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) - SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+149, ui_y+89, 70, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) + SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split) + SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split) + SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+119, ui_y+89, 60, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split) Draw.EndAlign() # Only used for user feedback - KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+229, ui_y+89, 110, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) + KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder) + + ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.') Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20) CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)') @@ -958,6 +1160,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): SPLIT_OBJECTS.val,\ SPLIT_GROUPS.val,\ SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ IMAGE_SEARCH.val,\ POLYGROUPS.val ) @@ -971,6 +1174,7 @@ def load_obj_ui(filepath, BATCH_LOAD= False): SPLIT_OBJECTS.val,\ SPLIT_GROUPS.val,\ SPLIT_MATERIALS.val,\ + ROTATE_X90.val,\ IMAGE_SEARCH.val,\ POLYGROUPS.val ) @@ -989,34 +1193,28 @@ if __name__=='__main__' and not DEBUG: else: Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj') - + # For testing compatibility ''' -# For testing compatibility else: # DEBUG ONLY TIME= sys.time() + DIR = '/fe/obj' import os print 'Searching for files' - os.system('find /fe/obj -iname "*.obj" > /tmp/temp3ds_list') - - print '...Done' - file= open('/tmp/temp3ds_list', 'rU') - lines= file.readlines() - file.close() - - def between(v,a,b): - if v <= max(a,b) and v >= min(a,b): - return True - return False - - for i, _obj in enumerate(lines): - if between(i, 0,20): - _obj= _obj[:-1] - print 'Importing', _obj, '\nNUMBER', i, 'of', len(lines) - _obj_file= _obj.split('/')[-1].split('\\')[-1] - newScn= bpy.data.scenes.new(_obj_file) + def fileList(path): + for dirpath, dirnames, filenames in os.walk(path): + for filename in filenames: + yield os.path.join(dirpath, filename) + + files = [f for f in fileList(DIR) if f.lower().endswith('.obj')] + files.sort() + + for i, obj_file in enumerate(files): + if 0 < i < 20: + print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files) + newScn= bpy.data.scenes.new(os.path.basename(obj_file)) newScn.makeCurrent() - load_obj(_obj, False) + load_obj(obj_file, False, IMAGE_SEARCH=0) print 'TOTAL TIME: %.6f' % (sys.time() - TIME) ''' diff --git a/release/scripts/textplugin_convert_ge.py b/release/scripts/textplugin_convert_ge.py index f3b44cdb14b..21e065bcfd7 100644 --- a/release/scripts/textplugin_convert_ge.py +++ b/release/scripts/textplugin_convert_ge.py @@ -718,7 +718,7 @@ def convert248to249(lines, log = True, logErrors = True, fileName = None): try: # Convert! func(lines, row, match.start(1), match.end(1), closure) - except ConversionError as e: + except ConversionError, e: # Insert a comment saying the conversion failed. print "ERROR: %sline %d, %s: %s\n" % ( fileIdStr, row + 1, attrName, e) diff --git a/release/scripts/wizard_bolt_factory.py b/release/scripts/wizard_bolt_factory.py index 6a280eccc58..2d653b211d5 100644 --- a/release/scripts/wizard_bolt_factory.py +++ b/release/scripts/wizard_bolt_factory.py @@ -8,7 +8,7 @@ Tooltip: 'Create models of various types of screw fasteners.' """ __author__ = " Aaron Keith (Spudmn) " -__version__ = "2.00 2009/05/22" +__version__ = "2.02 2009/06/10" __url__ = ["Author's site,http://sourceforge.net/projects/boltfactory/", "Blender,http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Misc/Bolt_Factory"] __bpydoc__ = """\ Bolt_Factory.py @@ -22,6 +22,13 @@ with default settings. History: + V2.02 10/06/09 by Aaron Keith + + -Added changes made by the Blender team. + + V2.01 26/05/09 by Aaron Keith + + - Fixed normal's on Lock Nut V2.00 22/05/09 by Aaron Keith @@ -2005,7 +2012,7 @@ def add_Nylon_Head(OUTSIDE_RADIUS,Z_LOCATION = 0): sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1)) return Move_Verts_Up_Z(sVerts,0),faces,Lowest_Z_Vert @@ -2059,7 +2066,7 @@ def add_Nylon_Part(OUTSIDE_RADIUS,Z_LOCATION = 0): sVerts,sFaces = SpinDup(verts,faces,360,DIV,'z') sVerts.extend(verts) #add the start verts to the Spin verts to complete the loop - faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV)) + faces.extend(Build_Face_List_Quads(FaceStart,Row-1,DIV,1)) return sVerts,faces,0 - Lowest_Z_Vert @@ -2594,8 +2601,8 @@ def Create_Tab(X1,Y1,X2,Y2,Title,Buttons): # X1,Y1 = Top Left X2,Y2 = Bottom Rig def Dispaly_Title_Bar(Y_POS,CONTROL_HEIGHT): CONTROL_WIDTH = 250 - Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V2.00",Model_Type) - + Create_Tab(3,Y_POS,CONTROL_WIDTH,Y_POS -CONTROL_HEIGHT,"Bolt Factory V2.02",Model_Type) + def Dispaly_Preset_Tab(Y_POS,CONTROL_HEIGHT): diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index c3555c9dd8a..da625b946ce 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -87,7 +87,7 @@ extern void count_displist(struct ListBase *lb, int *totvert, int *totface); extern void freedisplist(struct ListBase *lb); extern int displist_has_faces(struct ListBase *lb); -extern void makeDispListSurf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, int forRender); +extern void makeDispListSurf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, int forRender, int forOrco); extern void makeDispListCurveTypes(struct Scene *scene, struct Object *ob, int forOrco); extern void makeDispListMBall(struct Scene *scene, struct Object *ob); extern void shadeDispList(struct Scene *scene, struct Base *base); diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c index 27b78c6644c..eb3aefe7ee6 100644 --- a/source/blender/blenkernel/intern/booleanops.c +++ b/source/blender/blenkernel/intern/booleanops.c @@ -161,6 +161,7 @@ typedef struct { DerivedMesh *dm; int pos; int offset; + int flip; } FaceIt; static void FaceIt_Destruct(CSG_FaceIteratorDescriptor * iterator) @@ -187,9 +188,15 @@ static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face) MFace *mfaces = face_it->dm->getFaceArray(face_it->dm); MFace *mface = &mfaces[face_it->pos]; - face->vertex_index[0] = mface->v1; + /* reverse face vertices if necessary */ face->vertex_index[1] = mface->v2; + if( face_it->flip == 0 ) { + face->vertex_index[0] = mface->v1; face->vertex_index[2] = mface->v3; + } else { + face->vertex_index[2] = mface->v1; + face->vertex_index[0] = mface->v3; + } if (mface->v4) { face->vertex_index[3] = mface->v4; face->vertex_number = 4; @@ -213,7 +220,7 @@ static void FaceIt_Reset(CSG_IteratorPtr it) } static void FaceIt_Construct( - CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset) + CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset, Object *ob) { FaceIt *it; if (output == 0) return; @@ -228,6 +235,25 @@ static void FaceIt_Construct( it->offset = offset; it->pos = 0; + /* determine if we will need to reverse order of face vertices */ + if (ob->size[0] < 0.0f) { + if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) { + it->flip = 1; + } else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) { + it->flip = 1; + } else { + it->flip = 0; + } + } else { + if (ob->size[1] < 0.0f && ob->size[2] < 0.0f) { + it->flip = 0; + } else if (ob->size[1] >= 0.0f && ob->size[2] >= 0.0f) { + it->flip = 0; + } else { + it->flip = 1; + } + } + // assign iterator function pointers. output->Step = FaceIt_Step; output->Fill = FaceIt_Fill; @@ -425,7 +451,7 @@ static void BuildMeshDescriptors( struct CSG_VertexIteratorDescriptor * vertex_it) { VertexIt_Construct(vertex_it,dm, ob); - FaceIt_Construct(face_it,dm,face_offset); + FaceIt_Construct(face_it,dm,face_offset,ob); } static void FreeMeshDescriptors( diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index fe138407d54..736165a8a98 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1371,7 +1371,7 @@ static void displist_surf_indices(DispList *dl) } -void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender) +void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender, int forOrco) { ListBase *nubase; Nurb *nu; @@ -1388,7 +1388,8 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende else nubase= &cu->nurb; - curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); + if(!forOrco) + curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); for (nu=nubase->first; nu; nu=nu->next) { if(forRender || nu->hide==0) { @@ -1442,7 +1443,8 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende tex_space_curve(cu); } - curve_calc_modifiers_post(scene, ob, dispbase, forRender, originalVerts, deformedVerts); + if(!forOrco) + curve_calc_modifiers_post(scene, ob, dispbase, forRender, originalVerts, deformedVerts); } void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) @@ -1458,7 +1460,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) freedisplist(dispbase); if(ob->type==OB_SURF) { - makeDispListSurf(scene, ob, dispbase, 0); + makeDispListSurf(scene, ob, dispbase, 0, forOrco); } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 6ebd68e990f..3ef7b82864c 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -117,6 +117,72 @@ static struct DerivedMesh *NewBooleanDerivedMesh() {return NULL;} //XXX #include "BIF_meshlaplacian.h" +/* Utility */ + +static int is_last_displist(Object *ob) +{ + Curve *cu = ob->data; + static int curvecount=0, totcurve=0; + + if(curvecount == 0){ + DispList *dl; + + totcurve = 0; + for(dl=cu->disp.first; dl; dl=dl->next) + totcurve++; + } + + curvecount++; + + if(curvecount == totcurve){ + curvecount = 0; + return 1; + } + + return 0; +} + +static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco) +{ + DerivedMesh *dm= NULL; + + if(ob->type==OB_MESH) { + dm = CDDM_from_mesh((Mesh*)(ob->data), ob); + + if(vertexCos) { + CDDM_apply_vert_coords(dm, vertexCos); + //CDDM_calc_normals(dm); + } + + if(orco) + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); + } + else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) { + Object *tmpobj; + Curve *tmpcu; + + if(is_last_displist(ob)) { + /* copies object and modifiers (but not the data) */ + tmpobj= copy_object(ob); + tmpcu = (Curve *)tmpobj->data; + tmpcu->id.us--; + + /* copies the data */ + tmpobj->data = copy_curve((Curve *) ob->data); + + makeDispListCurveTypes(scene, tmpobj, 1); + nurbs_to_mesh(tmpobj); + + dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); + //CDDM_calc_normals(dm); + + free_libblock_us(&G.main->object, tmpobj); + } + } + + return dm; +} + /***/ static int noneModifier_isDisabled(ModifierData *md) @@ -6046,7 +6112,8 @@ static void surfaceModifier_freeData(ModifierData *md) MEM_freeN(surmd->bvhtree); } - surmd->dm->release(surmd->dm); + if(surmd->dm) + surmd->dm->release(surmd->dm); surmd->bvhtree = NULL; surmd->dm = NULL; @@ -6070,7 +6137,7 @@ static void surfaceModifier_deformVerts( /* if possible use/create DerivedMesh */ if(derivedData) surmd->dm = CDDM_copy(derivedData); - else if(ob->type==OB_MESH) surmd->dm = CDDM_from_mesh(ob->data, ob); + else surmd->dm = get_original_dm(md->scene, ob, NULL, 0); if(!ob->pd) { @@ -6242,70 +6309,6 @@ CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md) return dataMask; } -static int is_last_displist(Object *ob) -{ - Curve *cu = ob->data; - static int curvecount=0, totcurve=0; - - if(curvecount==0){ - DispList *dl; - - totcurve=0; - for(dl=cu->disp.first; dl; dl=dl->next){ - totcurve++; - } - } - - curvecount++; - - if(curvecount==totcurve){ - curvecount=0; - return 1; - } - - return 0; -} - -static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco) -{ - DerivedMesh *dm= NULL; - - if(ob->type==OB_MESH) { - dm = CDDM_from_mesh((Mesh*)(ob->data), ob); - - if(vertexCos) { - CDDM_apply_vert_coords(dm, vertexCos); - //CDDM_calc_normals(dm); - } - - if(orco) - DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob)); - } - else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) { - Object *tmpobj; - Curve *tmpcu; - - if(is_last_displist(ob)) { - /* copies object and modifiers (but not the data) */ - tmpobj= copy_object(ob); - tmpcu = (Curve *)tmpobj->data; - tmpcu->id.us--; - - /* copies the data */ - tmpobj->data = copy_curve((Curve *) ob->data); - - makeDispListCurveTypes(scene, tmpobj, 1); - nurbs_to_mesh(tmpobj); - - dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj); - //CDDM_calc_normals(dm); - - free_libblock_us(&G.main->object, tmpobj); - } - } - - return dm; -} /* saves the current emitter state for a particle system and calculates particles */ static void particleSystemModifier_deformVerts( diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index c0ef92b489e..596c27a14f5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1300,9 +1300,23 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive /* for hair, sort by origindex, allows optimizations in rendering */ /* however with virtual parents the children need to be in random order */ if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) { - COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX); - if(COMPARE_ORIG_INDEX) - qsort(index, totpart, sizeof(int), compare_orig_index); + if(from != PART_FROM_PARTICLE) { + COMPARE_ORIG_INDEX = NULL; + + if(from == PART_FROM_VERT) { + if(dm->numVertData) + COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX); + } + else { + if(dm->numFaceData) + COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX); + } + + if(COMPARE_ORIG_INDEX) { + qsort(index, totpart, sizeof(int), compare_orig_index); + COMPARE_ORIG_INDEX = NULL; + } + } } /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */ diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 0f2a6179964..bde4b561f26 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -294,9 +294,12 @@ int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) tf->pf->size, 0, &face); + if (err) return FALSE; + } + else { + err = TRUE; + return FALSE; } - else - err= TRUE; // Read the char freetypechar_to_vchar(face, charcode, vfont->data); diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 7fa26aa7572..6fce4fa990d 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -159,7 +159,7 @@ typedef struct Sequence { struct bSound *sound; /* the linked "bSound" object */ struct hdaudio *hdaudio; /* external hdaudio object */ float level, pan; /* level in dB (0=full), pan -1..1 */ - int curpos; /* last sample position in audio_fill() */ + int scenenr; /* for scene selection */ float strobe; void *effectdata; /* Struct pointer for effect settings */ @@ -170,8 +170,6 @@ typedef struct Sequence { int blend_mode; float blend_opacity; - int scenenr; /* for scene selection */ - int pad; } Sequence; typedef struct MetaStack { diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 199ff5dbb43..98e5819c0d3 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1857,8 +1857,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strand->totvert++; } else{ - sd.first = 0; - sd.time = time; sd.size = hasize; if(k==1){ @@ -1866,8 +1864,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem sd.time = 0.0f; VECSUB(loc0,loc1,loc); VECADD(loc0,loc1,loc0); + + render_new_particle(re, obr, psmd->dm, ma, &sd, loc1, loc0, seed); } + sd.first = 0; + sd.time = time; + if(k) render_new_particle(re, obr, psmd->dm, ma, &sd, loc, loc1, seed); @@ -2558,7 +2561,7 @@ static void init_render_surf(Render *re, ObjectRen *obr) if(need_orco) orcobase= orco= get_object_orco(re, ob); displist.first= displist.last= 0; - makeDispListSurf(re->scene, ob, &displist, 1); + makeDispListSurf(re->scene, ob, &displist, 1, 0); dl= displist.first; /* walk along displaylist and create rendervertices/-faces */ diff --git a/source/creator/creator.c b/source/creator/creator.c index 5ffce91ec2d..5617435049d 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -868,7 +868,7 @@ static void error_cb(char *err) static void mem_error_cb(char *errorStr) { - fprintf(stderr, "%s", errorStr); + fputs(errorStr, stderr); fflush(stderr); } diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 4ac28e36c48..a70790ef2a0 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -338,6 +338,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, ketsjiengine->SetCameraOverrideProjectionMatrix(projmat); ketsjiengine->SetCameraOverrideViewMatrix(viewmat); ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far); + ketsjiengine->SetCameraOverrideLens(v3d->lens); } // create a scene converter, create and convert the startingscene diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp index 17d1bf65ca4..ffff7185fe4 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp @@ -28,8 +28,6 @@ #include "GL/glew.h" -#include "DNA_scene_types.h" - #include "RAS_IRenderTools.h" #include "RAS_IRasterizer.h" #include "RAS_LightObject.h" @@ -41,6 +39,7 @@ #include "KX_BlenderMaterial.h" #include "KX_RayCast.h" #include "KX_IPhysicsController.h" +#include "KX_Light.h" #include "PHY_IPhysicsEnvironment.h" @@ -330,21 +329,12 @@ int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& view { // taken from blender source, incompatibility between Blender Object / GameObject KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo; - int scenelayer = ~0; float glviewmat[16]; unsigned int count; - float vec[4]; - - vec[3]= 1.0; + std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); - if(kxscene && kxscene->GetBlenderScene()) - scenelayer = kxscene->GetBlenderScene()->lay; - for(count=0; count<m_numgllights; count++) glDisable((GLenum)(GL_LIGHT0+count)); - - //std::vector<struct RAS_LightObject*> m_lights; - std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); viewmat.getValue(glviewmat); @@ -353,82 +343,14 @@ int KX_BlenderRenderTools::applyLights(int objectlayer, const MT_Transform& view for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit) { RAS_LightObject* lightdata = (*lit); - KX_Scene* lightscene = (KX_Scene*)lightdata->m_scene; - - /* only use lights in the same layer as the object */ - if(!(lightdata->m_layer & objectlayer)) - continue; - /* only use lights in the same scene, and in a visible layer */ - if(kxscene != lightscene || !(lightdata->m_layer & scenelayer)) - continue; - - vec[0] = (*(lightdata->m_worldmatrix))(0,3); - vec[1] = (*(lightdata->m_worldmatrix))(1,3); - vec[2] = (*(lightdata->m_worldmatrix))(2,3); - vec[3] = 1; - - if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) { - - vec[0] = (*(lightdata->m_worldmatrix))(0,2); - vec[1] = (*(lightdata->m_worldmatrix))(1,2); - vec[2] = (*(lightdata->m_worldmatrix))(2,2); - //vec[0]= base->object->obmat[2][0]; - //vec[1]= base->object->obmat[2][1]; - //vec[2]= base->object->obmat[2][2]; - vec[3]= 0.0; - glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); - } - else { - //vec[3]= 1.0; - glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); - glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0); - glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance); - // without this next line it looks backward compatible. - //attennuation still is acceptable - glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance)); - - if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) { - vec[0] = -(*(lightdata->m_worldmatrix))(0,2); - vec[1] = -(*(lightdata->m_worldmatrix))(1,2); - vec[2] = -(*(lightdata->m_worldmatrix))(2,2); - //vec[0]= -base->object->obmat[2][0]; - //vec[1]= -base->object->obmat[2][1]; - //vec[2]= -base->object->obmat[2][2]; - glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec); - glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0); - glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend); - } - else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0); - } - - if (lightdata->m_nodiffuse) - { - vec[0] = vec[1] = vec[2] = vec[3] = 0.0; - } else { - vec[0]= lightdata->m_energy*lightdata->m_red; - vec[1]= lightdata->m_energy*lightdata->m_green; - vec[2]= lightdata->m_energy*lightdata->m_blue; - vec[3]= 1.0; - } - glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec); - if (lightdata->m_nospecular) - { - vec[0] = vec[1] = vec[2] = vec[3] = 0.0; - } else if (lightdata->m_nodiffuse) { - vec[0]= lightdata->m_energy*lightdata->m_red; - vec[1]= lightdata->m_energy*lightdata->m_green; - vec[2]= lightdata->m_energy*lightdata->m_blue; - vec[3]= 1.0; - } - glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec); - glEnable((GLenum)(GL_LIGHT0+count)); + KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light; - count++; + if(kxlight->ApplyLight(kxscene, objectlayer, count)) + count++; } glPopMatrix(); return count; - } void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer) diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index a0d73c75d60..ea097ddff5b 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -209,6 +209,30 @@ static PyObject *listvalue_buffer_concat(PyObject * self, PyObject * other) return listval_new->NewProxy(true); /* python owns this list */ } +static int listvalue_buffer_contains(PyObject *self_v, PyObject *value) +{ + CListValue *self= static_cast<CListValue *>(BGE_PROXY_REF(self_v)); + + if (self==NULL) { + PyErr_SetString(PyExc_SystemError, "val in CList, "BGE_PROXY_ERROR_MSG); + return -1; + } + + if (PyString_Check(value)) { + if (self->FindValue((const char *)PyString_AsString(value))) { + return 1; + } + } + else if (BGE_PROXY_CHECK_TYPE(value)) { /* not dict like at all but this worked before __contains__ was used */ + CValue *item= static_cast<CValue *>(BGE_PROXY_REF(value)); + for (int i=0; i < self->GetCount(); i++) + if (self->GetValue(i) == item) // Com + return 1; + + } // not using CheckEqual + + return 0; +} static PySequenceMethods listvalue_as_sequence = { @@ -225,6 +249,7 @@ static PySequenceMethods listvalue_as_sequence = { NULL, /*sq_ass_item*/ NULL, /*sq_ass_slice*/ #endif + (objobjproc)listvalue_buffer_contains, /* sq_contains */ }; @@ -264,7 +289,9 @@ PyTypeObject CListValue::Type = { 0, py_base_getattro, py_base_setattro, - 0,0,0,0,0,0,0,0,0, + 0, + Py_TPFLAGS_DEFAULT, + 0,0,0,0,0,0,0, Methods }; @@ -499,7 +526,7 @@ PyObject* CListValue::Pyreverse() bool CListValue::CheckEqual(CValue* first,CValue* second) { bool result = false; - + CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second); if (eqval==NULL) @@ -528,7 +555,7 @@ PyObject* CListValue::Pyindex(PyObject *value) for (int i=0;i<numelem;i++) { CValue* elem = GetValue(i); - if (CheckEqual(checkobj,elem)) + if (checkobj==elem || CheckEqual(checkobj,elem)) { result = PyInt_FromLong(i); break; @@ -560,7 +587,7 @@ PyObject* CListValue::Pycount(PyObject* value) for (int i=0;i<numelem;i++) { CValue* elem = GetValue(i); - if (CheckEqual(checkobj,elem)) + if (checkobj==elem || CheckEqual(checkobj,elem)) { numfound ++; } diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 369c00782cc..c002dccefe4 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -113,8 +113,8 @@ typedef struct { if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \ { \ ShowDeprecationWarning_func(old_way, new_way); \ + \ WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \ - ShowDeprecationWarning_func(old_way, new_way); \ wlink.warn_done = true; \ wlink.link = NULL; \ \ diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp index c5c9dcc6c0f..24fca3feb8b 100644 --- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp +++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp @@ -29,8 +29,6 @@ #include "GL/glew.h" -#include "DNA_scene_types.h" - #include "RAS_IRenderTools.h" #include "RAS_IRasterizer.h" #include "RAS_LightObject.h" @@ -42,6 +40,7 @@ #include "KX_BlenderMaterial.h" #include "KX_RayCast.h" #include "KX_IPhysicsController.h" +#include "KX_Light.h" #include "PHY_IPhysicsEnvironment.h" @@ -387,21 +386,12 @@ int GPC_RenderTools::applyLights(int objectlayer, const MT_Transform& viewmat) { // taken from blender source, incompatibility between Blender Object / GameObject KX_Scene* kxscene = (KX_Scene*)m_auxilaryClientInfo; - int scenelayer = ~0; float glviewmat[16]; unsigned int count; - float vec[4]; - - vec[3]= 1.0; + std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); - if(kxscene && kxscene->GetBlenderScene()) - scenelayer = kxscene->GetBlenderScene()->lay; - for(count=0; count<m_numgllights; count++) glDisable((GLenum)(GL_LIGHT0+count)); - - //std::vector<struct RAS_LightObject*> m_lights; - std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin(); viewmat.getValue(glviewmat); @@ -410,82 +400,14 @@ int GPC_RenderTools::applyLights(int objectlayer, const MT_Transform& viewmat) for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit) { RAS_LightObject* lightdata = (*lit); - KX_Scene* lightscene = (KX_Scene*)lightdata->m_scene; - - /* only use lights in the same layer as the object */ - if(!(lightdata->m_layer & objectlayer)) - continue; - /* only use lights in the same scene, and in a visible layer */ - if(kxscene != lightscene || !(lightdata->m_layer & scenelayer)) - continue; - - vec[0] = (*(lightdata->m_worldmatrix))(0,3); - vec[1] = (*(lightdata->m_worldmatrix))(1,3); - vec[2] = (*(lightdata->m_worldmatrix))(2,3); - vec[3] = 1; - - if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) { - - vec[0] = (*(lightdata->m_worldmatrix))(0,2); - vec[1] = (*(lightdata->m_worldmatrix))(1,2); - vec[2] = (*(lightdata->m_worldmatrix))(2,2); - //vec[0]= base->object->obmat[2][0]; - //vec[1]= base->object->obmat[2][1]; - //vec[2]= base->object->obmat[2][2]; - vec[3]= 0.0; - glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); - } - else { - //vec[3]= 1.0; - glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec); - glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0); - glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance); - // without this next line it looks backward compatible. - //attennuation still is acceptable - glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance)); - - if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) { - vec[0] = -(*(lightdata->m_worldmatrix))(0,2); - vec[1] = -(*(lightdata->m_worldmatrix))(1,2); - vec[2] = -(*(lightdata->m_worldmatrix))(2,2); - //vec[0]= -base->object->obmat[2][0]; - //vec[1]= -base->object->obmat[2][1]; - //vec[2]= -base->object->obmat[2][2]; - glLightfv((GLenum)(GL_LIGHT0+count), GL_SPOT_DIRECTION, vec); - glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, lightdata->m_spotsize/2.0); - glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_EXPONENT, 128.0*lightdata->m_spotblend); - } - else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0); - } - - if (lightdata->m_nodiffuse) - { - vec[0] = vec[1] = vec[2] = vec[3] = 0.0; - } else { - vec[0]= lightdata->m_energy*lightdata->m_red; - vec[1]= lightdata->m_energy*lightdata->m_green; - vec[2]= lightdata->m_energy*lightdata->m_blue; - vec[3]= 1.0; - } - glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec); - if (lightdata->m_nospecular) - { - vec[0] = vec[1] = vec[2] = vec[3] = 0.0; - } else if (lightdata->m_nodiffuse) { - vec[0]= lightdata->m_energy*lightdata->m_red; - vec[1]= lightdata->m_energy*lightdata->m_green; - vec[2]= lightdata->m_energy*lightdata->m_blue; - vec[3]= 1.0; - } - glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec); - glEnable((GLenum)(GL_LIGHT0+count)); + KX_LightObject *kxlight = (KX_LightObject*)lightdata->m_light; - count++; + if(kxlight->ApplyLight(kxscene, objectlayer, count)) + count++; } glPopMatrix(); return count; - } void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index ba4d6e22872..40f6c99c03c 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -547,12 +547,15 @@ PyTypeObject KX_Camera::Type = { 0, 0, py_base_repr, - 0,0, + 0, + &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, py_base_getattro, py_base_setattro, - 0,0,0,0,0,0,0,0,0, + 0, + Py_TPFLAGS_DEFAULT, + 0,0,0,0,0,0,0, Methods }; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 7f417b325c8..b266095c715 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1287,7 +1287,7 @@ PyObject* KX_GameObject::PyGetPosition() return PyObjectFrom(NodeGetWorldPosition()); } -PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) +static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) { KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); const char *attr_str= PyString_AsString(item); @@ -1295,7 +1295,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) PyObject* pyconvert; if (self==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = gameOb[key]: KX_GameObject, "BGE_PROXY_ERROR_MSG); return NULL; } @@ -1321,7 +1321,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) } -int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) +static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) { KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); const char *attr_str= PyString_AsString(key); @@ -1329,7 +1329,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) PyErr_Clear(); if (self==NULL) { - PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "gameOb[key] = value: KX_GameObject, "BGE_PROXY_ERROR_MSG); return -1; } @@ -1409,11 +1409,40 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) return 0; /* success */ } -/* Cant set the len otherwise it can evaluate as false */ +static int Seq_Contains(PyObject *self_v, PyObject *value) +{ + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); + + if (self==NULL) { + PyErr_SetString(PyExc_SystemError, "val in gameOb: KX_GameObject, "BGE_PROXY_ERROR_MSG); + return -1; + } + + if(PyString_Check(value) && self->GetProperty(PyString_AsString(value))) + return 1; + + if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value)) + return 1; + + return 0; +} + + PyMappingMethods KX_GameObject::Mapping = { (lenfunc)NULL , /*inquiry mp_length */ - (binaryfunc)KX_GameObject::Map_GetItem, /*binaryfunc mp_subscript */ - (objobjargproc)KX_GameObject::Map_SetItem, /*objobjargproc mp_ass_subscript */ + (binaryfunc)Map_GetItem, /*binaryfunc mp_subscript */ + (objobjargproc)Map_SetItem, /*objobjargproc mp_ass_subscript */ +}; + +PySequenceMethods KX_GameObject::Sequence = { + NULL, /* Cant set the len otherwise it can evaluate as false */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + NULL, /* sq_item */ + NULL, /* sq_slice */ + NULL, /* sq_ass_item */ + NULL, /* sq_ass_slice */ + (objobjproc)Seq_Contains, /* sq_contains */ }; PyTypeObject KX_GameObject::Type = { @@ -1433,12 +1462,15 @@ PyTypeObject KX_GameObject::Type = { 0, 0, py_base_repr, - 0,0, + 0, + &Sequence, &Mapping, 0,0,0, py_base_getattro, py_base_setattro, - 0,0,0,0,0,0,0,0,0, + 0, + Py_TPFLAGS_DEFAULT, + 0,0,0,0,0,0,0, Methods }; @@ -2207,7 +2239,7 @@ PyObject* KX_GameObject::PyGetChildrenRecursive() PyObject* KX_GameObject::PyGetMesh(PyObject* args) { - ShowDeprecationWarning("getMesh()", "the meshes property"); + ShowDeprecationWarning("getMesh()", "the meshes property (now a list of meshes)"); int mesh = 0; @@ -2779,16 +2811,11 @@ PyObject* KX_GameObject::Pyget(PyObject *args) /* Matches python dict.has_key() */ PyObject* KX_GameObject::Pyhas_key(PyObject* value) { - if(PyString_Check(value) && GetProperty(PyString_AsString(value))) - Py_RETURN_TRUE; - - if (m_attr_dict && PyDict_GetItem(m_attr_dict, value)) - Py_RETURN_TRUE; - - Py_RETURN_FALSE; + // the ONLY error case is invalid data, this is checked by the macro'd static function + // that calls this one. but make sure Seq_Contains doesnt add extra errors later on. + return PyBool_FromLong(Seq_Contains((PyObject *)this, value)); } - /* --------------------------------------------------------------------- * Some stuff taken from the header * --------------------------------------------------------------------- */ diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index dbdea97031d..ff5c8a01e6e 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -917,10 +917,8 @@ public: static PyObject* pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); /* getitem/setitem */ - static Py_ssize_t Map_Len(PyObject* self); static PyMappingMethods Mapping; - static PyObject* Map_GetItem(PyObject *self_v, PyObject *item); - static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val); + static PySequenceMethods Sequence; private : diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index b30b79e7f23..a43ea59220b 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1078,6 +1078,11 @@ void KX_KetsjiEngine::SetCameraOverrideClipping(float near, float far) m_overrideCamFar = far; } +void KX_KetsjiEngine::SetCameraOverrideLens(float lens) +{ + m_overrideCamLens = lens; +} + void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport) { // In this function we make sure the rasterizer settings are upto @@ -1351,6 +1356,8 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene) KX_Camera* activecam = NULL; RAS_CameraData camdata = RAS_CameraData(); + if (override_camera) camdata.m_lens = m_overrideCamLens; + activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata); activecam->SetName("__default__cam__"); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 6fa379e551a..abba23ca376 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -129,6 +129,7 @@ private: MT_CmMatrix4x4 m_overrideCamViewMat; float m_overrideCamNear; float m_overrideCamFar; + float m_overrideCamLens; bool m_stereo; int m_curreye; @@ -253,6 +254,7 @@ public: void SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat); void SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat); void SetCameraOverrideClipping(float near, float far); + void SetCameraOverrideLens(float lens); /** * Sets display of all frames. diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp index fe575384a35..ae9e097a96e 100644 --- a/source/gameengine/Ketsji/KX_Light.cpp +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -35,6 +35,8 @@ #pragma warning (disable : 4786) #endif +#include "GL/glew.h" + #include "KX_Light.h" #include "KX_Camera.h" #include "RAS_IRasterizer.h" @@ -43,6 +45,7 @@ #include "KX_PyMath.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "GPU_material.h" KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, @@ -56,8 +59,8 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, m_rendertools(rendertools) { m_lightobj = lightobj; - m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); m_lightobj.m_scene = sgReplicationInfo; + m_lightobj.m_light = this; m_rendertools->AddLight(&m_lightobj); m_glsl = glsl; m_blenderscene = ((KX_Scene*)sgReplicationInfo)->GetBlenderScene(); @@ -84,12 +87,102 @@ CValue* KX_LightObject::GetReplica() replica->ProcessReplica(); - replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr(); + replica->m_lightobj.m_light = replica; m_rendertools->AddLight(&replica->m_lightobj); return replica; } +bool KX_LightObject::ApplyLight(KX_Scene *kxscene, int oblayer, int slot) +{ + KX_Scene* lightscene = (KX_Scene*)m_lightobj.m_scene; + float vec[4]; + int scenelayer = ~0; + + if(kxscene && kxscene->GetBlenderScene()) + scenelayer = kxscene->GetBlenderScene()->lay; + + /* only use lights in the same layer as the object */ + if(!(m_lightobj.m_layer & oblayer)) + return false; + /* only use lights in the same scene, and in a visible layer */ + if(kxscene != lightscene || !(m_lightobj.m_layer & scenelayer)) + return false; + + // lights don't get their openGL matrix updated, do it now + if(GetSGNode()->IsDirty()) + GetOpenGLMatrix(); + + MT_CmMatrix4x4& worldmatrix= *GetOpenGLMatrixPtr(); + + vec[0] = worldmatrix(0,3); + vec[1] = worldmatrix(1,3); + vec[2] = worldmatrix(2,3); + vec[3] = 1.0f; + + if(m_lightobj.m_type==RAS_LightObject::LIGHT_SUN) { + + vec[0] = worldmatrix(0,2); + vec[1] = worldmatrix(1,2); + vec[2] = worldmatrix(2,2); + //vec[0]= base->object->obmat[2][0]; + //vec[1]= base->object->obmat[2][1]; + //vec[2]= base->object->obmat[2][2]; + vec[3]= 0.0; + glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec); + } + else { + //vec[3]= 1.0; + glLightfv((GLenum)(GL_LIGHT0+slot), GL_POSITION, vec); + glLightf((GLenum)(GL_LIGHT0+slot), GL_CONSTANT_ATTENUATION, 1.0); + glLightf((GLenum)(GL_LIGHT0+slot), GL_LINEAR_ATTENUATION, m_lightobj.m_att1/m_lightobj.m_distance); + // without this next line it looks backward compatible. + //attennuation still is acceptable + glLightf((GLenum)(GL_LIGHT0+slot), GL_QUADRATIC_ATTENUATION, m_lightobj.m_att2/(m_lightobj.m_distance*m_lightobj.m_distance)); + + if(m_lightobj.m_type==RAS_LightObject::LIGHT_SPOT) { + vec[0] = -worldmatrix(0,2); + vec[1] = -worldmatrix(1,2); + vec[2] = -worldmatrix(2,2); + //vec[0]= -base->object->obmat[2][0]; + //vec[1]= -base->object->obmat[2][1]; + //vec[2]= -base->object->obmat[2][2]; + glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPOT_DIRECTION, vec); + glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, m_lightobj.m_spotsize/2.0); + glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_EXPONENT, 128.0*m_lightobj.m_spotblend); + } + else + glLightf((GLenum)(GL_LIGHT0+slot), GL_SPOT_CUTOFF, 180.0); + } + + if (m_lightobj.m_nodiffuse) { + vec[0] = vec[1] = vec[2] = vec[3] = 0.0; + } + else { + vec[0]= m_lightobj.m_energy*m_lightobj.m_red; + vec[1]= m_lightobj.m_energy*m_lightobj.m_green; + vec[2]= m_lightobj.m_energy*m_lightobj.m_blue; + vec[3]= 1.0; + } + + glLightfv((GLenum)(GL_LIGHT0+slot), GL_DIFFUSE, vec); + if(m_lightobj.m_nospecular) + { + vec[0] = vec[1] = vec[2] = vec[3] = 0.0; + } + else if (m_lightobj.m_nodiffuse) { + vec[0]= m_lightobj.m_energy*m_lightobj.m_red; + vec[1]= m_lightobj.m_energy*m_lightobj.m_green; + vec[2]= m_lightobj.m_energy*m_lightobj.m_blue; + vec[3]= 1.0; + } + + glLightfv((GLenum)(GL_LIGHT0+slot), GL_SPECULAR, vec); + glEnable((GLenum)(GL_LIGHT0+slot)); + + return true; +} + GPULamp *KX_LightObject::GetGPULamp() { if(m_glsl) @@ -200,12 +293,15 @@ PyTypeObject KX_LightObject::Type = { 0, 0, py_base_repr, - 0,0, + 0, + &KX_GameObject::Sequence, &KX_GameObject::Mapping, 0,0,0, py_base_getattro, py_base_setattro, - 0,0,0,0,0,0,0,0,0, + 0, + Py_TPFLAGS_DEFAULT, + 0,0,0,0,0,0,0, Methods }; diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index 35f25515e3b..358c705080a 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -54,7 +54,10 @@ public: virtual CValue* GetReplica(); RAS_LightObject* GetLightData() { return &m_lightobj;} - /* GLSL shadow */ + /* OpenGL Light */ + bool ApplyLight(KX_Scene *kxscene, int oblayer, int slot); + + /* GLSL Light */ struct GPULamp *GetGPULamp(); bool HasShadowBuffer(); int GetShadowLayer(); diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 5c02a2db646..c13271f66a5 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -112,7 +112,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame) return false; // actual audio device playing state - bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false; + bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false; if (m_pino) { @@ -194,7 +194,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame) } } // verify that the sound is still playing - isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false; + isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED && m_soundObject->GetPlaystate() != SND_INITIAL) ? true : false; if (isplaying) { diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index d22c09b4d3e..3e20203a4cc 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1016,14 +1016,21 @@ void CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torque } if (body) { - //workaround for incompatibility between 'DYNAMIC' game object, and angular factor - //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque - const btVector3& angFac = body->getAngularFactor(); - btVector3 tmpFac(0,0,1); - body->setAngularFactor(tmpFac); - body->applyTorque(torque); - body->setAngularFactor(angFac); - } + if (m_cci.m_bRigid) + { + body->applyTorque(torque); + } + else + { + //workaround for incompatibility between 'DYNAMIC' game object, and angular factor + //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque + const btVector3& angFac = body->getAngularFactor(); + btVector3 tmpFac(0,0,1); + body->setAngularFactor(tmpFac); + body->applyTorque(torque); + body->setAngularFactor(angFac); + } + } } } diff --git a/source/gameengine/Rasterizer/RAS_LightObject.h b/source/gameengine/Rasterizer/RAS_LightObject.h index 6b63a891981..b45a35e4266 100644 --- a/source/gameengine/Rasterizer/RAS_LightObject.h +++ b/source/gameengine/Rasterizer/RAS_LightObject.h @@ -39,8 +39,9 @@ struct RAS_LightObject LIGHT_NORMAL }; bool m_modified; - int m_layer; + int m_layer; void *m_scene; + void *m_light; float m_energy; float m_distance; @@ -55,7 +56,6 @@ struct RAS_LightObject float m_spotblend; LightType m_type; - MT_CmMatrix4x4* m_worldmatrix; bool m_nodiffuse; bool m_nospecular; diff --git a/tools/Blender.py b/tools/Blender.py index bb82f9caa1d..164a9d097e6 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -51,6 +51,7 @@ blenderdeps = [] # don't manipulate this one outside this module! possible_types = ['core'] # can be set in ie. SConstruct libs = {} +vcp = [] def getresources(): return resources @@ -406,7 +407,8 @@ class BlenderEnvironment(SConsEnvironment): SConsEnvironment.Default(self, res) resources.append(res) - def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None): + def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None): + global vcp if not self or not libname or not sources: print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC self.Exit() @@ -452,12 +454,24 @@ class BlenderEnvironment(SConsEnvironment): targetdir = '#'+targetdir lib = lenv.Library(target= targetdir, source=sources) SConsEnvironment.Default(self, lib) # we add to default target, because this way we get some kind of progress info during build + if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + #if targetdir[0] == '#': + # targetdir = targetdir[1:-1] + print "! ",targetdir+ '.vcproj' # + self['MSVSPROJECTSUFFIX'] + vcproject = self.MSVSProject(target = targetdir + '.vcproj', # + self['MSVSPROJECTSUFFIX'], + srcs = sources, + buildtarget = lib, + variant = 'Release', + auto_build_solution=0) + vcp.append(vcproject) + SConsEnvironment.Default(self, vcproject) else: print bc.WARNING+'Not building '+bc.ENDC+bc.OKGREEN+libname+bc.ENDC+' for '+bc.OKBLUE+'BF_QUICK'+bc.ENDC # note: libs is a global add_lib_to_dict(self, libs, libtype, libname, priority) def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''): + global vcp print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC lenv = self.Clone() if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'): @@ -495,6 +509,12 @@ class BlenderEnvironment(SConsEnvironment): brs = lenv.Command(f, prog, [bsc]) SConsEnvironment.Default(self, brs) SConsEnvironment.Default(self, prog) + if self['BF_MSVS'] and self['OURPLATFORM'] in ('win32-vc', 'win64-vc') and progname == 'blender': + print "! ",builddir + "/" + progname + '.sln' + sln = self.MSVSProject(target = builddir + "/" + progname + '.sln', + projects= vcp, + variant = 'Release') + SConsEnvironment.Default(self, sln) program_list.append(prog) if lenv['OURPLATFORM']=='darwin': lenv['BINARYKIND'] = binarykind diff --git a/tools/btools.py b/tools/btools.py index 7a71e1b678d..377a389941f 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -65,6 +65,7 @@ def validate_arguments(args, bc): 'WITH_BF_LCMS', 'BF_LCMS_LIB', 'WITH_BF_DOCS', 'BF_NUMJOBS', + 'BF_MSVS', ] # Have options here that scons expects to be lists @@ -363,7 +364,8 @@ def read_opts(cfg, args): (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)), ('BF_CONFIG', 'SCons python config file used to set default options', 'user_config.py'), - ('BF_NUMJOBS', 'Number of build processes to spawn', '1') + ('BF_NUMJOBS', 'Number of build processes to spawn', '1'), + ('BF_MSVS', 'Generate MSVS project files and solution', False) ) # end of opts.AddOptions() @@ -403,9 +405,13 @@ def NSIS_Installer(target=None, source=None, env=None): ns = open("00.sconsblender.nsi","r") + ns_cnt = str(ns.read()) ns.close() + # set Python version we compile against + ns_cnt = string.replace(ns_cnt, "[PYTHON_VERSION]", env['BF_PYTHON_VERSION']) + # do root rootlist = [] rootdir = os.listdir(inst_dir+"\\") |