diff options
31 files changed, 467 insertions, 264 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0264cf38086..2e1e76f288a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -929,38 +929,18 @@ if(UNIX AND NOT APPLE) if(WITH_CYCLES_OSL) set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation") - - message(STATUS "CYCLES_OSL = ${CYCLES_OSL}") - - # TODO(sergey): Move to dedicated FindOpenShadingLanguage.cmake - find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib) - find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib) - find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib) - find_path(OSL_INCLUDE_DIR OSL/oslclosure.h PATHS ${CYCLES_OSL}/include) - find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin) - if(EXISTS ${OSL_INCLUDE_DIR}) - file(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MAJOR - REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+[0-9]+.*$") - file(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MINOR - REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+[0-9]+.*$") - string(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+([.0-9]+).*" - "\\1" OSL_LIBRARY_VERSION_MAJOR ${OSL_LIBRARY_VERSION_MAJOR}) - string(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+([.0-9]+).*" - "\\1" OSL_LIBRARY_VERSION_MINOR ${OSL_LIBRARY_VERSION_MINOR}) - endif() - - if(${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6") - # Note: --whole-archive is needed to force loading of all symbols in liboslexec, - # otherwise LLVM is missing the osl_allocate_closure_component function - list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -Wl,--whole-archive ${OSL_LIB_EXEC} -Wl,--no-whole-archive ${OSL_LIB_QUERY}) - else() - list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY}) - endif() - - if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER) - set(OSL_FOUND TRUE) + if(NOT OSL_ROOT) + set(OSL_ROOT ${CYCLES_OSL}) + endif() + find_package_wrapper(OpenShadingLanguage) + if(OSL_FOUND) + if(${OSL_LIBRARY_VERSION_MAJOR} EQUAL "1" AND ${OSL_LIBRARY_VERSION_MINOR} LESS "6") + # Note: --whole-archive is needed to force loading of all symbols in liboslexec, + # otherwise LLVM is missing the osl_allocate_closure_component function + set(OSL_LIBRARIES ${OSL_OSLCOMP_LIBRARY} -Wl,--whole-archive ${OSL_OSLEXEC_LIBRARY} -Wl,--no-whole-archive ${OSL_OSLQUERY_LIBRARY}) + endif() else() - message(STATUS "OSL not found") + message(STATUS "OSL not found, disabling it from Cycles") set(WITH_CYCLES_OSL OFF) endif() endif() diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index d7f56781f38..026d5e4f861 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -146,7 +146,7 @@ def schedule_build(name, hour, minute=0): "blender-addons": {"repository": "", "branch": "master"}, "blender-addons-contrib": {"repository": "", "branch": "master"}, "scons": {"repository": "", "branch": "master"}, - "lib svn": {"repository": "", "branch": "master"}}, + "lib svn": {"repository": "", "branch": "trunk"}}, branch=current_branch, builderNames=[name], hour=hour, diff --git a/build_files/cmake/Modules/FindOpenShadingLanguage.cmake b/build_files/cmake/Modules/FindOpenShadingLanguage.cmake new file mode 100644 index 00000000000..824d0f90597 --- /dev/null +++ b/build_files/cmake/Modules/FindOpenShadingLanguage.cmake @@ -0,0 +1,98 @@ +# - Find OpenShadingLanguage library +# Find the native OpenShadingLanguage includes and library +# This module defines +# OSL_INCLUDE_DIRS, where to find OSL headers, Set when +# OSL_INCLUDE_DIR is found. +# OSL_LIBRARIES, libraries to link against to use OSL. +# OSL_ROOT_DIR, the base directory to search for OSL. +# This can also be an environment variable. +# OSL_COMPILER, full path to OSL script compiler. +# OSL_FOUND, if false, do not try to use OSL. +# OSL_LIBRARY_VERSION_MAJOR, OSL_LIBRARY_VERSION_MINOR, the major +# and minor versions of OSL library if found. +# +#============================================================================= +# Copyright 2014 Blender Foundation. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# If OSL_ROOT_DIR was defined in the environment, use it. +IF(NOT OSL_ROOT_DIR AND NOT $ENV{OSL_ROOT_DIR} STREQUAL "") + SET(OSL_ROOT_DIR $ENV{OSL_ROOT_DIR}) +ENDIF() + +SET(_osl_FIND_COMPONENTS + oslcomp + oslexec + oslquery +) + +SET(_osl_SEARCH_DIRS + ${OSL_ROOT_DIR} + /usr/local + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt/lib/osl +) + +FIND_PATH(OSL_INCLUDE_DIR + NAMES + OSL/oslversion.h + HINTS + ${_osl_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +SET(_osl_LIBRARIES) +FOREACH(COMPONENT ${_osl_FIND_COMPONENTS}) + STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT) + + FIND_LIBRARY(OSL_${UPPERCOMPONENT}_LIBRARY + NAMES + ${COMPONENT} + HINTS + ${_osl_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib + ) + LIST(APPEND _osl_LIBRARIES "${OSL_${UPPERCOMPONENT}_LIBRARY}") +ENDFOREACH() + +FIND_PROGRAM(OSL_COMPILER oslc + HINTS ${_osl_SEARCH_DIRS} + PATH_SUFFIXES bin) + +# handle the QUIETLY and REQUIRED arguments and set OSL_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSL DEFAULT_MSG _osl_LIBRARIES OSL_INCLUDE_DIR OSL_COMPILER) + +IF(OSL_FOUND) + SET(OSL_LIBRARIES ${_osl_LIBRARIES}) + SET(OSL_INCLUDE_DIRS ${OSL_INCLUDE_DIR}) + + FILE(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MAJOR + REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+[0-9]+.*$") + FILE(STRINGS "${OSL_INCLUDE_DIR}/OSL/oslversion.h" OSL_LIBRARY_VERSION_MINOR + REGEX "^[ \t]*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+[0-9]+.*$") + STRING(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MAJOR[ \t]+([.0-9]+).*" + "\\1" OSL_LIBRARY_VERSION_MAJOR ${OSL_LIBRARY_VERSION_MAJOR}) + STRING(REGEX REPLACE ".*#define[ \t]+OSL_LIBRARY_VERSION_MINOR[ \t]+([.0-9]+).*" + "\\1" OSL_LIBRARY_VERSION_MINOR ${OSL_LIBRARY_VERSION_MINOR}) +ENDIF(OSL_FOUND) + +MARK_AS_ADVANCED( + OSL_INCLUDE_DIR +) +FOREACH(COMPONENT ${_osl_FIND_COMPONENTS}) + STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT) + MARK_AS_ADVANCED(OSL_${UPPERCOMPONENT}_LIBRARY) +ENDFOREACH() diff --git a/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst b/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst index 9340d33f8a9..631075363ca 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_VehicleWrapper.rst @@ -11,22 +11,25 @@ base class --- :class:`PyObjectPlus` TODO - description - .. method:: addWheel(wheel, attachPos, attachDir, axleDir, suspensionRestLength, wheelRadius, hasSteering) + .. method:: addWheel(wheel, attachPos, downDir, axleDir, suspensionRestLength, wheelRadius, hasSteering) Add a wheel to the vehicle :arg wheel: The object to use as a wheel. - :type wheel: :class:`KX_GameObject` or a KX_GameObject name - :arg attachPos: The position that this wheel will attach to. + :type wheel: :class:`KX_GameObject` or a :class:`KX_GameObject` name + :arg attachPos: The position to attach the wheel, relative to the chassis object center. :type attachPos: vector of 3 floats - :arg attachDir: The direction this wheel points. - :type attachDir: vector of 3 floats - :arg axleDir: The direction of this wheels axle. + :arg downDir: The direction vector pointing down to where the vehicle should collide with the floor. + :type downDir: vector of 3 floats + :arg axleDir: The axis the wheel rotates around, relative to the chassis. :type axleDir: vector of 3 floats - :arg suspensionRestLength: TODO - Description + :arg suspensionRestLength: The length of the suspension when no forces are being applied. :type suspensionRestLength: float - :arg wheelRadius: The size of the wheel. + :arg wheelRadius: The radius of the wheel (half the diameter). :type wheelRadius: float + :arg hasSteering: True if the wheel should turn with steering, typically used in front wheels. + :type hasSteering: boolean + .. method:: applyBraking(force, wheelIndex) @@ -38,6 +41,7 @@ base class --- :class:`PyObjectPlus` :arg wheelIndex: index of the wheel where the force needs to be applied :type wheelIndex: integer + .. method:: applyEngineForce(force, wheelIndex) Apply an engine force to the specified wheel @@ -48,6 +52,7 @@ base class --- :class:`PyObjectPlus` :arg wheelIndex: index of the wheel where the force needs to be applied :type wheelIndex: integer + .. method:: getConstraintId() Get the constraint ID diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 9561885525f..20dced2fe00 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -591,16 +591,16 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg, const ShaderClosure #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif - float m_eta = sc->data2; + float m_eta = sc->data2, fresnel; bool inside; - fresnel_dielectric(m_eta, m, I, &R, &T, + fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); - if(!inside) { + if(!inside && fresnel != 1.0f) { *omega_in = T; #ifdef __RAY_DIFFERENTIALS__ @@ -945,16 +945,16 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals *kg, const ShaderCl #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif - float m_eta = sc->data2; + float m_eta = sc->data2, fresnel; bool inside; - fresnel_dielectric(m_eta, m, I, &R, &T, + fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); - if(!inside) { + if(!inside && fresnel != 1.0f) { *omega_in = T; #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h index c96ac62fafa..02a06941afa 100644 --- a/intern/cycles/kernel/closure/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -67,13 +67,14 @@ ccl_device int bsdf_refraction_sample(const ShaderClosure *sc, float3 Ng, float3 float3 dRdx, dRdy, dTdx, dTdy; #endif bool inside; - fresnel_dielectric(m_eta, N, I, &R, &T, + float fresnel; + fresnel = fresnel_dielectric(m_eta, N, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy, #endif &inside); - if(!inside) { + if(!inside && fresnel != 1.0f) { /* Some high number for MIS. */ *pdf = 1e6f; *eval = make_float3(1e6f, 1e6f, 1e6f); diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h index 3a4b20e61aa..d3297e05c67 100644 --- a/intern/cycles/kernel/geom/geom_motion_triangle.h +++ b/intern/cycles/kernel/geom/geom_motion_triangle.h @@ -130,6 +130,9 @@ ccl_device_inline float3 motion_triangle_refine(KernelGlobals *kg, ShaderData *s #ifdef __INTERSECTION_REFINE__ if(isect->object != OBJECT_NONE) { + if(UNLIKELY(t == 0.0f)) { + return P; + } #ifdef __OBJECT_MOTION__ Transform tfm = sd->ob_itfm; #else diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h index e77e220c919..4233ff15c86 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h @@ -58,6 +58,12 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, Transform ob_tfm; #endif +#ifndef __KERNEL_SSE41__ + if(!isfinite(P.x)) { + return false; + } +#endif + #if BVH_FEATURE(BVH_INSTANCING) int num_hits_in_instance = 0; #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h index ef1754e711c..62598115fa3 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h @@ -61,6 +61,12 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, Transform ob_tfm; #endif +#ifndef __KERNEL_SSE41__ + if(!isfinite(P.x)) { + return 0; + } +#endif + ssef tnear(0.0f), tfar(isect_t); sse3f idir4(ssef(idir.x), ssef(idir.y), ssef(idir.z)); diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h index 64da51360de..99d2fb20837 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h @@ -66,6 +66,12 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, Transform ob_tfm; #endif +#ifndef __KERNEL_SSE41__ + if(!isfinite(P.x)) { + return false; + } +#endif + isect->t = ray->t; isect->u = 0.0f; isect->v = 0.0f; diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h index a2a8d1a20ab..2c396e99fc4 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h @@ -57,6 +57,12 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, Transform ob_tfm; #endif +#ifndef __KERNEL_SSE41__ + if(!isfinite(P.x)) { + return false; + } +#endif + isect->t = ray->t; isect->u = 0.0f; isect->v = 0.0f; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index fb02af1be20..dda790ea700 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -185,6 +185,17 @@ static void clean_paths(Main *main) } } +static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene) +{ + wmWindow *win; + for (win = wm->windows.first; win; win = win->next) { + if (win->screen->scene == scene) { + return true; + } + } + return false; +} + /* context matching */ /* handle no-ui case */ @@ -228,24 +239,54 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* no load screens? */ if (mode != LOAD_UI) { + /* Logic for 'track_undo_scene' is to keep using the scene which the active screen has, + * as long as the scene associated with the undo operation is visible in one of the open windows. + * + * - 'curscreen->scene' - scene the user is currently looking at. + * - 'bfd->curscene' - scene undo-step was created in. + * + * This means users can have 2+ windows open and undo in both without screens switching. + * But if they close one of the screens, + * undo will ensure that the scene being operated on will be activated + * (otherwise we'd be undoing on an off-screen scene which isn't acceptable). + * see: T43424 + */ + bool track_undo_scene; + /* comes from readfile.c */ SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); SWAP(ListBase, G.main->script, bfd->main->script); - /* we re-use current screen */ curscreen = CTX_wm_screen(C); - /* but use new Scene pointer */ - curscene = bfd->curscene; + + track_undo_scene = (mode == LOAD_UNDO && curscreen && bfd->main->wm.first); + if (track_undo_scene) { + curscene = curscreen->scene; + } + else { + /* but use new Scene pointer */ + curscene = bfd->curscene; + } + if (curscene == NULL) curscene = bfd->main->scene.first; /* empty file, we add a scene to make Blender work */ if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); - + /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ /* clear_global will free G.main, here we can still restore pointers */ blo_lib_link_screen_restore(bfd->main, curscreen, curscene); + curscene = curscreen->scene; + + if (track_undo_scene) { + wmWindowManager *wm = bfd->main->wm.first; + if (wm_scene_is_visible(wm, bfd->curscene) == false) { + curscene = bfd->curscene; + curscreen->scene = curscene; + } + } } /* free G.main Main database */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index a5691d6fef3..fa4f9c6ed52 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -378,7 +378,8 @@ bool id_copy(ID *id, ID **newid, bool test) case ID_WM: return false; /* can't be copied from here */ case ID_GD: - return false; /* not implemented */ + if (!test) *newid = (ID *)gpencil_data_duplicate((bGPdata *)id, false); + return true; case ID_MSK: if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id); return true; diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 3bf5c4cc47e..aaf54b82f32 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -438,6 +438,10 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) new_shape = rigidbody_get_shape_trimesh_from_mesh(ob); break; } + /* use box shape if we can't fall back to old shape */ + if (new_shape == NULL && rbo->physics_shape == NULL) { + new_shape = RB_shape_new_box(size[0], size[1], size[2]); + } /* assign new collision shape if creation was successful */ if (new_shape) { if (rbo->physics_shape) @@ -445,11 +449,6 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild) rbo->physics_shape = new_shape; RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo)); } - /* use box shape if we can't fall back to old shape */ - else if (rbo->physics_shape == NULL) { - rbo->shape = RB_SHAPE_BOX; - rigidbody_validate_sim_shape(ob, true); - } } /* --------------------- */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 46c1ae7fb61..f61bcf2dfd2 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -910,16 +910,39 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_node_socket_interface(wd, ntree, sock); } -static void current_screen_compat(Main *mainvar, bScreen **screen) +/** + * Take care using 'use_active_win', since we wont want the currently active window + * to change which scene renders (currently only used for undo). + */ +static void current_screen_compat(Main *mainvar, bScreen **r_screen, bool use_active_win) { wmWindowManager *wm; - wmWindow *window; + wmWindow *window = NULL; /* find a global current screen in the first open window, to have * a reasonable default for reading in older versions */ wm = mainvar->wm.first; - window = (wm) ? wm->windows.first : NULL; - *screen = (window) ? window->screen : NULL; + + if (wm) { + if (use_active_win) { + /* write the active window into the file, needed for multi-window undo T43424 */ + for (window = wm->windows.first; window; window = window->next) { + if (window->active) { + break; + } + } + + /* fallback */ + if (window == NULL) { + window = wm->windows.first; + } + } + else { + window = wm->windows.first; + } + } + + *r_screen = (window) ? window->screen : NULL; } typedef struct RenderInfo { @@ -938,7 +961,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) RenderInfo data; /* XXX in future, handle multiple windows with multiple screens? */ - current_screen_compat(mainvar, &curscreen); + current_screen_compat(mainvar, &curscreen, false); if (curscreen) curscene = curscreen->scene; for (sce= mainvar->scene.first; sce; sce= sce->id.next) { @@ -3456,6 +3479,7 @@ static void write_linestyles(WriteData *wd, ListBase *idbase) * - for undofile, curscene needs to be saved */ static void write_global(WriteData *wd, int fileflags, Main *mainvar) { + const bool is_undo = (wd->current != NULL); FileGlobal fg; bScreen *screen; char subvstr[8]; @@ -3465,7 +3489,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) memset(fg.filename, 0, sizeof(fg.filename)); memset(fg.build_hash, 0, sizeof(fg.build_hash)); - current_screen_compat(mainvar, &screen); + current_screen_compat(mainvar, &screen, is_undo); /* XXX still remap G */ fg.curscreen= screen; diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 4e08ada9738..7c53896b969 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -479,7 +479,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) unsigned int layer; float dia; float loc[3], rot[3]; - float mat[4][4], scale_mat[4][4]; + float mat[4][4]; WM_operator_view3d_unit_defaults(C, op); @@ -531,8 +531,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); dia = RNA_float_get(op->ptr, "radius"); - scale_m4_fl(scale_mat, dia); - mul_m4_m4m4(mat, scale_mat, mat); + mul_mat3_m4_fl(mat, dia); nu = add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index e6f6644fd24..c03766a95e1 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -999,7 +999,7 @@ static void gp_session_validatebuffer(tGPsdata *p) } /* (re)init new painting data */ -static int gp_session_initdata(bContext *C, tGPsdata *p) +static bool gp_session_initdata(bContext *C, tGPsdata *p) { bGPdata **gpd_ptr = NULL; ScrArea *curarea = CTX_wm_area(C); @@ -1082,7 +1082,13 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) case SPACE_CLIP: { SpaceClip *sc = curarea->spacedata.first; + MovieClip *clip = ED_space_clip_get_clip(sc); + if (clip == NULL) { + p->status = GP_STATUS_ERROR; + return false; + } + /* set the current area */ p->sa = curarea; p->ar = ar; @@ -1097,13 +1103,18 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->custom_color[3] = 0.9f; if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { - MovieClip *clip = ED_space_clip_get_clip(sc); int framenr = ED_space_clip_get_clip_frame_number(sc); MovieTrackingTrack *track = BKE_tracking_track_get_active(&clip->tracking); - MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); - - p->imat[3][0] -= marker->pos[0]; - p->imat[3][1] -= marker->pos[1]; + MovieTrackingMarker *marker = track ? BKE_tracking_marker_get(track, framenr) : NULL; + + if (marker) { + p->imat[3][0] -= marker->pos[0]; + p->imat[3][1] -= marker->pos[1]; + } + else { + p->status = GP_STATUS_ERROR; + return false; + } } invert_m4_m4(p->mat, p->imat); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 128febdc5f9..590ab1d694d 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -892,6 +892,7 @@ void uiTemplateGameStates(uiLayout *layout, struct PointerRNA *ptr, const char * void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *userptr, int compact); void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, int color_management); void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser); +void uiTemplateImageInfo(uiLayout *layout, struct bContext *C, Image *ima, ImageUser *iuser); void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C); void UI_but_func_operator_search(uiBut *but); void uiTemplateOperatorSearch(uiLayout *layout); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 56ab27821d7..5ac991cbd94 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3570,8 +3570,7 @@ void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop); - uiItemL(layout, IFACE_("Input Color Space:"), ICON_NONE); - uiItemR(layout, &colorspace_settings_ptr, "name", 0, "", ICON_NONE); + uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE); } void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr, const char *propname) diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index a2160df1e63..6ce5e8a304b 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -422,7 +422,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) { Object *obedit; BMEditMesh *em; - float mat[4][4], scale_mat[4][4]; + float mat[4][4]; float loc[3], rot[3]; float dia; bool enter_editmode; @@ -434,8 +434,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Suzanne"), &dia, mat, &was_editmode, loc, rot, layer); dia = RNA_float_get(op->ptr, "radius"); - scale_m4_fl(scale_mat, dia); - mul_m4_m4m4(mat, scale_mat, mat); + mul_mat3_m4_fl(mat, dia); em = BKE_editmesh_from_object(obedit); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 98e0a176b0e..57611930e99 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -591,7 +591,7 @@ void file_draw_list(const bContext *C, ARegion *ar) if (params->display == FILE_SHORTDISPLAY) { sx += (int)layout->column_widths[COLUMN_NAME] + column_space; - if (!(file->type & S_IFDIR)) { + if ((BLI_is_dir(file->path) == false) && file->size[0]) { file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_SIZE] + column_space; } @@ -620,7 +620,7 @@ void file_draw_list(const bContext *C, ARegion *ar) file_draw_string(sx, sy, file->time, layout->column_widths[COLUMN_TIME], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_TIME] + column_space; - if (!(file->type & S_IFDIR)) { + if ((BLI_is_dir(file->path) == false) && file->size[0]) { file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); sx += (int)layout->column_widths[COLUMN_SIZE] + column_space; } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index a8d714b9f30..fb3c140fddf 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -64,6 +64,7 @@ #include "image_intern.h" #define B_NOP -1 +#define MAX_IMAGE_INFO_LEN 128 /* proto */ @@ -640,8 +641,6 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact) { -#define MAX_INFO_LEN 128 - PropertyRNA *prop; PointerRNA imaptr; RNAUpdateCb *cb; @@ -650,7 +649,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char Scene *scene = CTX_data_scene(C); uiLayout *row, *split, *col; uiBlock *block; - char str[MAX_INFO_LEN]; + char str[MAX_IMAGE_INFO_LEN]; void *lock; @@ -687,14 +686,14 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char uiLayoutSetContextPointer(layout, "edit_image_user", userptr); if (!compact) - uiTemplateID(layout, C, ptr, propname, "IMAGE_OT_new", "IMAGE_OT_open", NULL); + uiTemplateID(layout, C, ptr, propname, ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL); if (ima) { UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL); if (ima->source == IMA_SRC_VIEWER) { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN); + image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN); BKE_image_release_ibuf(ima, ibuf, lock); uiItemL(layout, ima->id.name + 2, ICON_NONE); @@ -763,10 +762,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char } else if (ima->source != IMA_SRC_GENERATED) { if (compact == 0) { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN); - BKE_image_release_ibuf(ima, ibuf, lock); - uiItemL(layout, str, ICON_NONE); + uiTemplateImageInfo(layout, C, ima, iuser); } } @@ -791,7 +787,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char if (has_alpha) { col = uiLayoutColumn(layout, false); uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE); - uiItemR(col, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE); + row = uiLayoutRow(col, false); + uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_alpha")); + uiItemR(row, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE); } if (ima->source == IMA_SRC_MOVIE) { @@ -861,8 +859,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char } MEM_freeN(cb); - -#undef MAX_INFO_LEN } void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_management) @@ -982,6 +978,24 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser } } +void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser) +{ + ImBuf *ibuf; + char str[MAX_IMAGE_INFO_LEN]; + void *lock; + + if (!ima || !iuser) + return; + + ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); + + image_info(CTX_data_scene(C), iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN); + BKE_image_release_ibuf(ima, ibuf, lock); + uiItemL(layout, str, ICON_NONE); +} + +#undef MAX_IMAGE_INFO_LEN + void image_buttons_register(ARegionType *UNUSED(art)) { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index d78d50c2584..e10ecd8c613 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -703,10 +703,10 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE); } - col = uiLayoutColumn(layout, false); - - if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) + if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) { + col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE); + } } static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -839,10 +839,51 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin uiLayoutSetContextPointer(layout, "image_user", &iuserptr); uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); + + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); + uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); +} - node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); +static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + Image *ima = imaptr.data; + + uiLayoutSetContextPointer(layout, "image_user", &iuserptr); + uiTemplateID(layout, C, ptr, "image", ima ? NULL : "IMAGE_OT_new", "IMAGE_OT_open", NULL); + + if (!ima) + return; + + uiItemR(layout, &imaptr, "source", 0, IFACE_("Source"), ICON_NONE); + + if (!(ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER))) { + uiLayout *row = uiLayoutRow(layout, true); + + if (ima->packedfile) + uiItemO(row, "", ICON_PACKAGE, "image.unpack"); + else + uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); + + row = uiLayoutRow(row, true); + uiLayoutSetEnabled(row, ima->packedfile == NULL); + uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); + uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); + } + + /* multilayer? */ + if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) { + uiTemplateImageLayers(layout, C, ima, iuserptr.data); + } + else if (ima->source != IMA_SRC_GENERATED) { + uiTemplateImageInfo(layout, C, ima, iuserptr.data); + } + + uiItemR(layout, ptr, "color_space", 0, IFACE_("Color Space"), ICON_NONE); + uiItemR(layout, ptr, "projection", 0, IFACE_("Projection"), ICON_NONE); } static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1116,6 +1157,7 @@ static void node_shader_set_butfunc(bNodeType *ntype) break; case SH_NODE_TEX_ENVIRONMENT: ntype->draw_buttons = node_shader_buts_tex_environment; + ntype->draw_buttons_ex = node_shader_buts_tex_environment_ex; break; case SH_NODE_TEX_GRADIENT: ntype->draw_buttons = node_shader_buts_tex_gradient; diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index c5ac67a6033..91a09708e1d 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -58,6 +58,7 @@ #include "UI_resources.h" #include "UI_view2d.h" +#include "UI_interface.h" #include "ED_space_api.h" #include "ED_markers.h" @@ -90,13 +91,12 @@ static void time_draw_sfra_efra(Scene *scene, View2D *v2d) fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax); } -#define CACHE_DRAW_HEIGHT 3.0f - static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene) { PTCacheID *pid; ListBase pidlist; SpaceTimeCache *stc = stime->caches.first; + const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize); float yoffs = 0.f; if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob)) @@ -172,7 +172,7 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene) glPushMatrix(); glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0); - glScalef(1.0, CACHE_DRAW_HEIGHT, 0.0); + glScalef(1.0, cache_draw_height, 0.0); switch (pid->type) { case PTCACHE_TYPE_SOFTBODY: @@ -230,7 +230,7 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene) glPopMatrix(); - yoffs += CACHE_DRAW_HEIGHT; + yoffs += cache_draw_height; stc = stc->next; } diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index ccb80fac05d..1b69eab8e28 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -753,19 +753,8 @@ PyMODINIT_FUNC initConstraintPythonBinding() PyObject *d; PyObject *item; - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "PhysicsConstraints" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); - - m = PyModule_Create(&PhysicsConstraints_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m); - } + m = PyModule_Create(&PhysicsConstraints_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m); // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 652dad581b0..70d1aed88a0 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1577,21 +1577,11 @@ PyMODINIT_FUNC initGameLogicPythonBinding() gUseVisibilityTemp=false; PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */ - - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "GameLogic" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); - // Create the module and add the functions - m = PyModule_Create(&GameLogic_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m); - } - + + m = PyModule_Create(&GameLogic_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameLogic_module_def.m_name, m); + + // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -2116,7 +2106,6 @@ PyMODINIT_FUNC initBGE(void) PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); Py_INCREF(submodule); - /* GameTypes is initted *after* in initPyTypes() */ PyModule_AddObject(mod, "types", (submodule = initGameTypesPythonBinding())); PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); Py_INCREF(submodule); @@ -2196,8 +2185,6 @@ PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv) initPySysObjects(maggie); - PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); - /* mathutils types are used by the BGE even if we don't import them */ { PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0); @@ -2212,7 +2199,7 @@ PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv) } #endif - initPyTypes(); + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); first_time = false; @@ -2254,7 +2241,9 @@ PyObject *initGamePythonScripting(Main *maggie) { /* no need to Py_SetProgramName, it was already taken care of in BPY_python_start */ - PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); + bpy_import_main_set(maggie); + + initPySysObjects(maggie); #ifdef WITH_AUDASPACE /* accessing a SoundActuator's sound results in a crash if aud is not initialized... */ @@ -2264,11 +2253,7 @@ PyObject *initGamePythonScripting(Main *maggie) } #endif - initPyTypes(); - - bpy_import_main_set(maggie); - - initPySysObjects(maggie); + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); PyObjectPlus::NullDeprecationWarning(); @@ -2342,20 +2327,9 @@ PyMODINIT_FUNC initRasterizerPythonBinding() PyObject *m; PyObject *d; - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "Rasterizer" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); + m = PyModule_Create(&Rasterizer_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m); - // Create the module and add the functions - m = PyModule_Create(&Rasterizer_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), Rasterizer_module_def.m_name, m); - } // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -2478,19 +2452,8 @@ PyMODINIT_FUNC initGameKeysPythonBinding() PyObject *m; PyObject *d; - /* Use existing module where possible */ - m = PyImport_ImportModule( "GameKeys" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); - - // Create the module and add the functions - m = PyModule_Create(&GameKeys_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m); - } + m = PyModule_Create(&GameKeys_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m); // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 5c1ad56147e..828fd62f205 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -163,23 +163,34 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a #define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, NULL, i) #define PyType_Ready_AttrPtr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, n::AttributesPtr, i) -void initPyTypes(void) + + +PyDoc_STRVAR(GameTypes_module_documentation, +"This module provides access to the game engine data types." +); +static struct PyModuleDef GameTypes_module_def = { + PyModuleDef_HEAD_INIT, + "GameTypes", /* m_name */ + GameTypes_module_documentation, /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + + +PyMODINIT_FUNC initGameTypesPythonBinding(void) { + PyObject *m; + PyObject *dict; -/* - * initPyObjectPlusType(BL_ActionActuator::Parents); - * ..... - */ + m = PyModule_Create(&GameTypes_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameTypes_module_def.m_name, m); - /* Use existing module where possible */ - PyObject *mod = initGameTypesPythonBinding(); + dict = PyModule_GetDict(m); - /* For now just do PyType_Ready */ - PyObject *dict = PyModule_GetDict(mod); - PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod); - Py_DECREF(mod); - - for (int init_getset= 1; init_getset > -1; init_getset--) { /* run twice, once to init the getsets another to run PyType_Ready */ PyType_Ready_Attr(dict, BL_ActionActuator, init_getset); PyType_Ready_Attr(dict, BL_Shader, init_getset); @@ -269,42 +280,6 @@ void initPyTypes(void) KX_GameObject_Mathutils_Callback_Init(); KX_ObjectActuator_Mathutils_Callback_Init(); #endif -} - - -PyDoc_STRVAR(GameTypes_module_documentation, -"This module provides access to the game engine data types." -); -static struct PyModuleDef GameTypes_module_def = { - PyModuleDef_HEAD_INIT, - "GameTypes", /* m_name */ - GameTypes_module_documentation, /* m_doc */ - 0, /* m_size */ - NULL, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - - -PyMODINIT_FUNC initGameTypesPythonBinding(void) -{ - PyObject *m; - - /* Use existing module where possible */ - m = PyImport_ImportModule( "GameTypes" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); - - // Create the module and add the functions - m = PyModule_Create(&GameTypes_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), GameTypes_module_def.m_name, m); - } return m; } diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.h b/source/gameengine/Ketsji/KX_PythonInitTypes.h index 4d7d26f7fb2..cfc49a1dc93 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.h +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.h @@ -34,7 +34,6 @@ #ifdef WITH_PYTHON #include <Python.h> -void initPyTypes(void); PyMODINIT_FUNC initGameTypesPythonBinding(void); #endif diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 535ed5ed39a..d10e51a491a 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -53,6 +53,22 @@ KX_VehicleWrapper::~KX_VehicleWrapper() #ifdef WITH_PYTHON + +static bool raise_exc_wheel(PHY_IVehicle* vehicle, int i, const char *method) +{ + if ( i < 0 || i >= vehicle->GetNumWheels() ) { + PyErr_Format(PyExc_ValueError, + "%s(...): wheel index %d out of range (0 to %d).", method, i, vehicle->GetNumWheels()-1); + return -1; + } else { + return 0; + } +} + +#define WHEEL_INDEX_CHECK_OR_RETURN(i, method) \ + if (raise_exc_wheel(m_vehicle, i, method) == -1) { return NULL; } (void)0 + + PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args) { @@ -67,22 +83,37 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args) KX_GameObject *gameOb; if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false, "vehicle.addWheel(...): KX_VehicleWrapper (first argument)")) return NULL; - if (gameOb->GetSGNode()) { PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode()); - /* TODO - no error checking here! - bad juju */ MT_Vector3 attachPos,attachDir,attachAxle; - PyVecTo(pylistPos,attachPos); - PyVecTo(pylistDir,attachDir); - PyVecTo(pylistAxleDir,attachAxle); + if(!PyVecTo(pylistPos,attachPos)) { + PyErr_SetString(PyExc_AttributeError, + "addWheel(...) Unable to add wheel. attachPos must be a vector with 3 elements."); + return NULL; + } + if(!PyVecTo(pylistDir,attachDir)) { + PyErr_SetString(PyExc_AttributeError, + "addWheel(...) Unable to add wheel. downDir must be a vector with 3 elements."); + return NULL; + } + if(!PyVecTo(pylistAxleDir,attachAxle)) { + PyErr_SetString(PyExc_AttributeError, + "addWheel(...) Unable to add wheel. axleDir must be a vector with 3 elements."); + return NULL; + } //someone reverse some conventions inside Bullet (axle winding) attachAxle = -attachAxle; - printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering); + if(wheelRadius<=0) { + PyErr_SetString(PyExc_AttributeError, + "addWheel(...) Unable to add wheel. wheelRadius must be positive."); + return NULL; + } + m_vehicle->AddWheel(motionState,attachPos,attachDir,attachAxle,suspensionRestLength,wheelRadius,hasSteering); } @@ -93,8 +124,6 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args) } - - PyObject *KX_VehicleWrapper::PyGetWheelPosition(PyObject *args) { @@ -103,6 +132,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelPosition(PyObject *args) if (PyArg_ParseTuple(args,"i:getWheelPosition",&wheelIndex)) { float position[3]; + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelPosition"); + m_vehicle->GetWheelPosition(wheelIndex,position[0],position[1],position[2]); MT_Vector3 pos(position[0],position[1],position[2]); return PyObjectFrom(pos); @@ -115,6 +146,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelRotation(PyObject *args) int wheelIndex; if (PyArg_ParseTuple(args,"i:getWheelRotation",&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelRotation"); + return PyFloat_FromDouble(m_vehicle->GetWheelRotation(wheelIndex)); } return NULL; @@ -126,6 +159,8 @@ PyObject *KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject *args) if (PyArg_ParseTuple(args,"i:getWheelOrientationQuaternion",&wheelIndex)) { float orn[4]; + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "getWheelOrientationQuaternion"); + m_vehicle->GetWheelOrientationQuaternion(wheelIndex,orn[0],orn[1],orn[2],orn[3]); MT_Quaternion quatorn(orn[0],orn[1],orn[2],orn[3]); MT_Matrix3x3 ornmat(quatorn); @@ -148,7 +183,6 @@ PyObject *KX_VehicleWrapper::PyGetConstraintId(PyObject *args) } - PyObject *KX_VehicleWrapper::PyApplyEngineForce(PyObject *args) { float force; @@ -156,6 +190,8 @@ PyObject *KX_VehicleWrapper::PyApplyEngineForce(PyObject *args) if (PyArg_ParseTuple(args,"fi:applyEngineForce",&force,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "applyEngineForce"); + force *= -1.f;//someone reverse some conventions inside Bullet (axle winding) m_vehicle->ApplyEngineForce(force,wheelIndex); } @@ -172,6 +208,8 @@ PyObject *KX_VehicleWrapper::PySetTyreFriction(PyObject *args) if (PyArg_ParseTuple(args,"fi:setTyreFriction",&wheelFriction,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setTyreFriction"); + m_vehicle->SetWheelFriction(wheelFriction,wheelIndex); } else { @@ -187,6 +225,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionStiffness(PyObject *args) if (PyArg_ParseTuple(args,"fi:setSuspensionStiffness",&suspensionStiffness,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionStiffness"); + m_vehicle->SetSuspensionStiffness(suspensionStiffness,wheelIndex); } else { @@ -202,6 +242,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionDamping(PyObject *args) if (PyArg_ParseTuple(args,"fi:setSuspensionDamping",&suspensionDamping,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionDamping"); + m_vehicle->SetSuspensionDamping(suspensionDamping,wheelIndex); } else { return NULL; @@ -216,6 +258,8 @@ PyObject *KX_VehicleWrapper::PySetSuspensionCompression(PyObject *args) if (PyArg_ParseTuple(args,"fi:setSuspensionCompression",&suspensionCompression,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSuspensionCompression"); + m_vehicle->SetSuspensionCompression(suspensionCompression,wheelIndex); } else { return NULL; @@ -230,6 +274,8 @@ PyObject *KX_VehicleWrapper::PySetRollInfluence(PyObject *args) if (PyArg_ParseTuple(args,"fi:setRollInfluence",&rollInfluence,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setRollInfluence"); + m_vehicle->SetRollInfluence(rollInfluence,wheelIndex); } else { @@ -246,6 +292,8 @@ PyObject *KX_VehicleWrapper::PyApplyBraking(PyObject *args) if (PyArg_ParseTuple(args,"fi:applyBraking",&braking,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "applyBraking"); + m_vehicle->ApplyBraking(braking,wheelIndex); } else { @@ -255,8 +303,6 @@ PyObject *KX_VehicleWrapper::PyApplyBraking(PyObject *args) } - - PyObject *KX_VehicleWrapper::PySetSteeringValue(PyObject *args) { float steeringValue; @@ -264,6 +310,8 @@ PyObject *KX_VehicleWrapper::PySetSteeringValue(PyObject *args) if (PyArg_ParseTuple(args,"fi:setSteeringValue",&steeringValue,&wheelIndex)) { + WHEEL_INDEX_CHECK_OR_RETURN(wheelIndex, "setSteeringValue"); + m_vehicle->SetSteeringValue(steeringValue,wheelIndex); } else { @@ -316,17 +364,11 @@ PyMethodDef KX_VehicleWrapper::Methods[] = { {"setSteeringValue",(PyCFunction) KX_VehicleWrapper::sPySetSteeringValue, METH_VARARGS}, {"applyEngineForce",(PyCFunction) KX_VehicleWrapper::sPyApplyEngineForce, METH_VARARGS}, {"applyBraking",(PyCFunction) KX_VehicleWrapper::sPyApplyBraking, METH_VARARGS}, - {"setTyreFriction",(PyCFunction) KX_VehicleWrapper::sPySetTyreFriction, METH_VARARGS}, - {"setSuspensionStiffness",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionStiffness, METH_VARARGS}, - {"setSuspensionDamping",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionDamping, METH_VARARGS}, - {"setSuspensionCompression",(PyCFunction) KX_VehicleWrapper::sPySetSuspensionCompression, METH_VARARGS}, - {"setRollInfluence",(PyCFunction) KX_VehicleWrapper::sPySetRollInfluence, METH_VARARGS}, - {NULL,NULL} //Sentinel }; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index c43a3f782a7..f450e3ac12f 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -174,26 +174,27 @@ public: virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - posX = trans.getOrigin().x(); - posY = trans.getOrigin().y(); - posZ = trans.getOrigin().z(); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) + { + btVector3 origin = m_vehicle->getWheelTransformWS(wheelIndex).getOrigin(); + + posX = origin.x(); + posY = origin.y(); + posZ = origin.z(); + } } + virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - btQuaternion quat = trans.getRotation(); - btMatrix3x3 orn2(quat); - - quatX = trans.getRotation().x(); - quatY = trans.getRotation().y(); - quatZ = trans.getRotation().z(); - quatW = trans.getRotation()[3]; - - - //printf("test"); - + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) + { + btQuaternion quat = m_vehicle->getWheelTransformWS(wheelIndex).getRotation(); + quatX = quat.x(); + quatY = quat.y(); + quatZ = quat.z(); + quatW = quat.w(); + } } virtual float GetWheelRotation(int wheelIndex) const @@ -205,8 +206,8 @@ public: btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); rotation = info.m_rotation; } - return rotation; + return rotation; } @@ -223,12 +224,16 @@ public: virtual void SetSteeringValue(float steering,int wheelIndex) { - m_vehicle->setSteeringValue(steering,wheelIndex); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { + m_vehicle->setSteeringValue(steering,wheelIndex); + } } virtual void ApplyEngineForce(float force,int wheelIndex) { - m_vehicle->applyEngineForce(force,wheelIndex); + if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { + m_vehicle->applyEngineForce(force,wheelIndex); + } } virtual void ApplyBraking(float braking,int wheelIndex) diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 50b973d76f3..6c9294873a6 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -191,20 +191,9 @@ PyMODINIT_FUNC initVideoTexturePythonBinding(void) if (PyType_Ready(&TextureType) < 0) return NULL; - /* Use existing module where possible - * be careful not to init any runtime vars after this */ - m = PyImport_ImportModule( "VideoTexture" ); - if (m) { - Py_DECREF(m); - return m; - } - else { - PyErr_Clear(); - - m = PyModule_Create(&VideoTexture_module_def); - PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m); - } - + m = PyModule_Create(&VideoTexture_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), VideoTexture_module_def.m_name, m); + if (m == NULL) return NULL; |