Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2011-12-20 21:24:20 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2011-12-20 21:24:20 +0400
commit921b2ee2d44ed87363198d7bfa89bb7116b0818b (patch)
tree3e04fd777b5c32f4814357ff9d18289ee072c962
parent1dc74acc123721d366e3628663ed029db5761e4d (diff)
parent738fdc7b6f43c3e1e838bd4239b36340fa4c2e0f (diff)
Merging r42723 through r42769 from trunk into soc-2011-tomato
-rw-r--r--CMakeLists.txt6
-rw-r--r--SConstruct4
-rw-r--r--build_files/scons/config/win32-mingw-config.py2
-rw-r--r--build_files/scons/config/win32-vc-config.py2
-rw-r--r--intern/cycles/app/cycles_test.cpp19
-rw-r--r--intern/cycles/blender/addon/engine.py6
-rw-r--r--intern/cycles/blender/blender_camera.cpp25
-rw-r--r--intern/cycles/blender/blender_session.cpp23
-rw-r--r--intern/cycles/blender/blender_sync.h1
-rw-r--r--intern/cycles/device/device.h1
-rw-r--r--intern/cycles/device/device_cpu.cpp12
-rw-r--r--intern/cycles/device/device_cuda.cpp12
-rw-r--r--intern/cycles/device/device_opencl.cpp10
-rw-r--r--intern/cycles/kernel/kernel.cl8
-rw-r--r--intern/cycles/kernel/kernel.cpp8
-rw-r--r--intern/cycles/kernel/kernel.cu8
-rw-r--r--intern/cycles/kernel/kernel.h12
-rw-r--r--intern/cycles/kernel/kernel_camera.h8
-rw-r--r--intern/cycles/kernel/kernel_film.h5
-rw-r--r--intern/cycles/kernel/kernel_optimized.cpp8
-rw-r--r--intern/cycles/kernel/kernel_path.h14
-rw-r--r--intern/cycles/kernel/kernel_random.h14
-rw-r--r--intern/cycles/kernel/kernel_types.h25
-rw-r--r--intern/cycles/render/buffers.cpp42
-rw-r--r--intern/cycles/render/buffers.h49
-rw-r--r--intern/cycles/render/camera.cpp11
-rw-r--r--intern/cycles/render/nodes.cpp1
-rw-r--r--intern/cycles/render/session.cpp75
-rw-r--r--intern/cycles/render/session.h18
-rw-r--r--intern/cycles/render/tile.cpp18
-rw-r--r--intern/cycles/render/tile.h8
-rw-r--r--intern/cycles/util/util_math.h5
-rw-r--r--intern/cycles/util/util_transform.h18
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm19
-rw-r--r--release/scripts/startup/bl_operators/wm.py22
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py85
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py9
-rw-r--r--release/scripts/startup/bl_ui/space_logic.py4
-rw-r--r--release/scripts/startup/bl_ui/space_text.py2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h6
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_texture.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c65
-rw-r--r--source/blender/blenkernel/intern/modifier.c9
-rw-r--r--source/blender/blenkernel/intern/node.c47
-rw-r--r--source/blender/blenkernel/intern/texture.c4
-rw-r--r--source/blender/blenlib/BLI_dynstr.h11
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c13
-rw-r--r--source/blender/blenloader/intern/readfile.c112
-rw-r--r--source/blender/editors/include/ED_mesh.h13
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/mesh/editface.c226
-rw-r--r--source/blender/editors/mesh/meshtools.c222
-rw-r--r--source/blender/editors/object/object_modifier.c4
-rw-r--r--source/blender/editors/screen/screen_ops.c32
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c6
-rw-r--r--source/blender/editors/space_node/node_buttons.c3
-rw-r--r--source/blender/editors/space_node/node_draw.c12
-rw-r--r--source/blender/editors/space_text/text_ops.c1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c35
-rw-r--r--source/blender/editors/space_view3d/drawobject.c78
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_world_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_scene.c14
-rw-r--r--source/blender/makesrna/intern/rna_world.c1
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c6
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c56
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c58
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c74
-rw-r--r--source/blender/nodes/shader/node_shader_util.c2
-rw-r--r--source/blender/python/intern/bpy_rna.c4
-rw-r--r--source/blender/python/mathutils/mathutils.c15
-rw-r--r--source/blender/python/mathutils/mathutils.h5
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c18
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c18
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c342
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h22
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c18
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c54
-rw-r--r--source/blender/render/intern/source/external_engine.c5
-rw-r--r--source/blender/render/intern/source/render_texture.c6
-rw-r--r--source/creator/CMakeLists.txt1
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h166
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp3
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp179
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h3
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp182
-rw-r--r--source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h1
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp13
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.h1
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h6
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp16
-rw-r--r--source/tests/CMakeLists.txt5
-rw-r--r--source/tests/bl_pyapi_mathutils.py109
99 files changed, 1699 insertions, 1257 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index af111c27f4f..371b7eb0896 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -723,11 +723,7 @@ elseif(WIN32)
set(GETTEXT_LIBRARIES gnu_gettext)
endif()
- if(CMAKE_CL_64)
- set(PNG_LIBRARIES libpng)
- else()
- set(PNG_LIBRARIES libpng_st)
- endif()
+ set(PNG_LIBRARIES libpng)
set(JPEG_LIBRARIES libjpeg)
set(PNG "${LIBDIR}/png")
diff --git a/SConstruct b/SConstruct
index d8db597d1c6..1a038278404 100644
--- a/SConstruct
+++ b/SConstruct
@@ -726,10 +726,6 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
# For MinGW and linuxcross static linking will be used
dllsources += ['${LCGDIR}/gettext/lib/gnu_gettext.dll']
- #currently win64-vc doesn't appear to have libpng.dll
- if env['OURPLATFORM'] != 'win64-vc':
- dllsources += ['${BF_PNG_LIBPATH}/libpng.dll']
-
dllsources += ['${BF_ZLIB_LIBPATH}/zlib.dll']
# Used when linking to libtiff was dynamic
# keep it here until compilation on all platform would be ok
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index bc2bbbba07a..6e65e093a46 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -64,7 +64,7 @@ BF_JPEG_LIB = 'liblibjpeg'
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
WITH_BF_PNG = True
-BF_PNG = LIBDIR + 'gcc/png'
+BF_PNG = LIBDIR + '/gcc/png'
BF_PNG_INC = '${BF_PNG}/include'
BF_PNG_LIB = 'png'
BF_PNG_LIBPATH = '${BF_PNG}/lib'
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index a2e3d11c244..53ac9937885 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -72,7 +72,7 @@ BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
WITH_BF_PNG = True
BF_PNG = LIBDIR + '/png'
BF_PNG_INC = '${BF_PNG}/include'
-BF_PNG_LIB = 'libpng_st'
+BF_PNG_LIB = 'libpng'
BF_PNG_LIBPATH = '${BF_PNG}/lib'
WITH_BF_TIFF = True
diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp
index 27e53ded6db..83816727404 100644
--- a/intern/cycles/app/cycles_test.cpp
+++ b/intern/cycles/app/cycles_test.cpp
@@ -82,10 +82,21 @@ static void session_print_status()
session_print(status);
}
+static BufferParams session_buffer_params()
+{
+ BufferParams buffer_params;
+ buffer_params.width = options.width;
+ buffer_params.height = options.height;
+ buffer_params.full_width = options.width;
+ buffer_params.full_height = options.height;
+
+ return buffer_params;
+}
+
static void session_init()
{
options.session = new Session(options.session_params);
- options.session->reset(options.width, options.height, options.session_params.samples);
+ options.session->reset(session_buffer_params(), options.session_params.samples);
options.session->scene = options.scene;
if(options.session_params.background && !options.quiet)
@@ -151,7 +162,7 @@ static void display_info(Progress& progress)
static void display()
{
- options.session->draw(options.width, options.height);
+ options.session->draw(session_buffer_params());
display_info(options.session->progress);
}
@@ -162,13 +173,13 @@ static void resize(int width, int height)
options.height= height;
if(options.session)
- options.session->reset(options.width, options.height, options.session_params.samples);
+ options.session->reset(session_buffer_params(), options.session_params.samples);
}
void keyboard(unsigned char key)
{
if(key == 'r')
- options.session->reset(options.width, options.height, options.session_params.samples);
+ options.session->reset(session_buffer_params(), options.session_params.samples);
else if(key == 27) // escape
options.session->progress.set_cancel("Cancelled");
}
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 2fedd2c0afa..60b77b23f25 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -62,11 +62,7 @@ def render(engine):
def update(engine, data, scene):
import bcycles
- if scene.render.use_border:
- engine.report({'ERROR'}, "Border rendering not supported yet")
- free(engine)
- else:
- bcycles.sync(engine.session)
+ bcycles.sync(engine.session)
def draw(engine, region, v3d, rv3d):
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 2a2c2a7c643..9777de14b1e 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -207,6 +207,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* transform, note the blender camera points along the negative z-axis */
cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
+ cam->matrix = transform_clear_scale(cam->matrix);
/* set update flag */
if(cam->modified(prevcam))
@@ -286,5 +287,29 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int
blender_camera_sync(scene->camera, &bcam, width, height);
}
+BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height)
+{
+ BufferParams params;
+
+ params.full_width = width;
+ params.full_height = height;
+
+ /* border render */
+ BL::RenderSettings r = b_scene.render();
+
+ if(!b_rv3d && r.use_border()) {
+ params.full_x = r.border_min_x()*width;
+ params.full_y = r.border_min_y()*height;
+ params.width = (int)(r.border_max_x()*width) - params.full_x;
+ params.height = (int)(r.border_max_y()*height) - params.full_y;
+ }
+ else {
+ params.width = width;
+ params.height = height;
+ }
+
+ return params;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 4433b1e24f9..1803dd36beb 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -100,7 +100,9 @@ void BlenderSession::create_session()
session->set_pause(BlenderSync::get_session_pause(b_scene, background));
/* start rendering */
- session->reset(width, height, session_params.samples);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+
+ session->reset(buffer_params, session_params.samples);
session->start();
}
@@ -135,7 +137,10 @@ void BlenderSession::write_render_result()
if(!pixels)
return;
- struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+ int w = buffer_params.width, h = buffer_params.height;
+
+ struct RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, 0, 0, w, h);
PointerRNA rrptr;
RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
BL::RenderResult rr(rrptr);
@@ -188,8 +193,10 @@ void BlenderSession::synchronize()
session->scene->mutex.unlock();
/* reset if needed */
- if(scene->need_reset())
- session->reset(width, height, session_params.samples);
+ if(scene->need_reset()) {
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+ session->reset(buffer_params, session_params.samples);
+ }
}
bool BlenderSession::draw(int w, int h)
@@ -225,7 +232,9 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if(reset) {
SessionParams session_params = BlenderSync::get_session_params(b_scene, background);
- session->reset(width, height, session_params.samples);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+
+ session->reset(buffer_params, session_params.samples);
}
}
@@ -233,7 +242,9 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
- return !session->draw(width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_rv3d, width, height);
+
+ return !session->draw(buffer_params);
}
void BlenderSession::get_status(string& status, string& substatus)
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 83c7f70fd59..824904cd81d 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -62,6 +62,7 @@ public:
static SceneParams get_scene_params(BL::Scene b_scene, bool background);
static SessionParams get_session_params(BL::Scene b_scene, bool background);
static bool get_session_pause(BL::Scene b_scene, bool background);
+ static BufferParams get_buffer_params(BL::Scene b_scene, BL::RegionView3D b_rv3d, int width, int height);
private:
/* sync */
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 5b87b11b6b8..be6a3f144ed 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -60,6 +60,7 @@ public:
device_ptr buffer;
int sample;
int resolution;
+ int offset, stride;
device_ptr displace_input;
device_ptr displace_offset;
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 990b7cb94b0..a45a4fb69f6 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -162,7 +162,8 @@ public:
if(system_cpu_support_optimized()) {
for(int y = task.y; y < task.y + task.h; y++) {
for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y);
+ kernel_cpu_optimized_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state,
+ task.sample, x, y, task.offset, task.stride);
if(tasks.worker_cancel())
break;
@@ -173,7 +174,8 @@ public:
{
for(int y = task.y; y < task.y + task.h; y++) {
for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state, task.sample, x, y);
+ kernel_cpu_path_trace(kg, (float4*)task.buffer, (unsigned int*)task.rng_state,
+ task.sample, x, y, task.offset, task.stride);
if(tasks.worker_cancel())
break;
@@ -192,14 +194,16 @@ public:
if(system_cpu_support_optimized()) {
for(int y = task.y; y < task.y + task.h; y++)
for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y);
+ kernel_cpu_optimized_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer,
+ task.sample, task.resolution, x, y, task.offset, task.stride);
}
else
#endif
{
for(int y = task.y; y < task.y + task.h; y++)
for(int x = task.x; x < task.x + task.w; x++)
- kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer, task.sample, task.resolution, x, y);
+ kernel_cpu_tonemap(kg, (uchar4*)task.rgba, (float4*)task.buffer,
+ task.sample, task.resolution, x, y, task.offset, task.stride);
}
}
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 177c90ba2df..dfa2fcb2322 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -520,6 +520,12 @@ public:
cuda_assert(cuParamSeti(cuPathTrace, offset, task.h))
offset += sizeof(task.h);
+ cuda_assert(cuParamSeti(cuPathTrace, offset, task.offset))
+ offset += sizeof(task.offset);
+
+ cuda_assert(cuParamSeti(cuPathTrace, offset, task.stride))
+ offset += sizeof(task.stride);
+
cuda_assert(cuParamSetSize(cuPathTrace, offset))
/* launch kernel: todo find optimal size, cache config for fermi */
@@ -581,6 +587,12 @@ public:
cuda_assert(cuParamSeti(cuFilmConvert, offset, task.h))
offset += sizeof(task.h);
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.offset))
+ offset += sizeof(task.offset);
+
+ cuda_assert(cuParamSeti(cuFilmConvert, offset, task.stride))
+ offset += sizeof(task.stride);
+
cuda_assert(cuParamSetSize(cuFilmConvert, offset))
/* launch kernel: todo find optimal size, cache config for fermi */
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 8eaaebc6629..3a1d3032d6e 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -191,7 +191,7 @@ public:
{
char version[256];
- int major, minor, req_major = 1, req_minor = 1;
+ int major, minor, req_major = 1, req_minor = 0;
clGetPlatformInfo(cpPlatform, CL_PLATFORM_VERSION, sizeof(version), &version, NULL);
@@ -541,6 +541,8 @@ public:
cl_int d_w = task.w;
cl_int d_h = task.h;
cl_int d_sample = task.sample;
+ cl_int d_offset = task.offset;
+ cl_int d_stride = task.stride;
/* sample arguments */
int narg = 0;
@@ -559,6 +561,8 @@ public:
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_y), (void*)&d_y);
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_w), (void*)&d_w);
ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_h), (void*)&d_h);
+ ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_offset), (void*)&d_offset);
+ ciErr |= clSetKernelArg(ckPathTraceKernel, narg++, sizeof(d_stride), (void*)&d_stride);
opencl_assert(ciErr);
@@ -611,6 +615,8 @@ public:
cl_int d_h = task.h;
cl_int d_sample = task.sample;
cl_int d_resolution = task.resolution;
+ cl_int d_offset = task.offset;
+ cl_int d_stride = task.stride;
/* sample arguments */
int narg = 0;
@@ -630,6 +636,8 @@ public:
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_y), (void*)&d_y);
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_w), (void*)&d_w);
ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_h), (void*)&d_h);
+ ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_offset), (void*)&d_offset);
+ ciErr |= clSetKernelArg(ckFilmConvertKernel, narg++, sizeof(d_stride), (void*)&d_stride);
opencl_assert(ciErr);
diff --git a/intern/cycles/kernel/kernel.cl b/intern/cycles/kernel/kernel.cl
index c00bc3fe957..90eb7a2513f 100644
--- a/intern/cycles/kernel/kernel.cl
+++ b/intern/cycles/kernel/kernel.cl
@@ -36,7 +36,7 @@ __kernel void kernel_ocl_path_trace(
#include "kernel_textures.h"
int sample,
- int sx, int sy, int sw, int sh)
+ int sx, int sy, int sw, int sh, int offset, int stride)
{
KernelGlobals kglobals, *kg = &kglobals;
@@ -50,7 +50,7 @@ __kernel void kernel_ocl_path_trace(
int y = sy + get_global_id(1);
if(x < sx + sw && y < sy + sh)
- kernel_path_trace(kg, buffer, rng_state, sample, x, y);
+ kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
}
__kernel void kernel_ocl_tonemap(
@@ -63,7 +63,7 @@ __kernel void kernel_ocl_tonemap(
#include "kernel_textures.h"
int sample, int resolution,
- int sx, int sy, int sw, int sh)
+ int sx, int sy, int sw, int sh, int offset, int stride)
{
KernelGlobals kglobals, *kg = &kglobals;
@@ -77,7 +77,7 @@ __kernel void kernel_ocl_tonemap(
int y = sy + get_global_id(1);
if(x < sx + sw && y < sy + sh)
- kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y);
+ kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
}
/*__kernel void kernel_ocl_displace(__global uint4 *input, __global float3 *offset, int sx)
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index 52a3852aa01..b4c3839dbd0 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -204,16 +204,16 @@ void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t
/* Path Tracing */
-void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y)
+void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
{
- kernel_path_trace(kg, buffer, rng_state, sample, x, y);
+ kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
}
/* Tonemapping */
-void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y)
+void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
{
- kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y);
+ kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
}
/* Displacement */
diff --git a/intern/cycles/kernel/kernel.cu b/intern/cycles/kernel/kernel.cu
index 75415a00b00..71fc7ac3197 100644
--- a/intern/cycles/kernel/kernel.cu
+++ b/intern/cycles/kernel/kernel.cu
@@ -26,22 +26,22 @@
#include "kernel_path.h"
#include "kernel_displace.h"
-extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh)
+extern "C" __global__ void kernel_cuda_path_trace(float4 *buffer, uint *rng_state, int sample, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
if(x < sx + sw && y < sy + sh)
- kernel_path_trace(NULL, buffer, rng_state, sample, x, y);
+ kernel_path_trace(NULL, buffer, rng_state, sample, x, y, offset, stride);
}
-extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh)
+extern "C" __global__ void kernel_cuda_tonemap(uchar4 *rgba, float4 *buffer, int sample, int resolution, int sx, int sy, int sw, int sh, int offset, int stride)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int y = sy + blockDim.y*blockIdx.y + threadIdx.y;
if(x < sx + sw && y < sy + sh)
- kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y);
+ kernel_film_tonemap(NULL, rgba, buffer, sample, resolution, x, y, offset, stride);
}
extern "C" __global__ void kernel_cuda_displace(uint4 *input, float3 *offset, int sx)
diff --git a/intern/cycles/kernel/kernel.h b/intern/cycles/kernel/kernel.h
index 700ee49c5f2..78247504b39 100644
--- a/intern/cycles/kernel/kernel.h
+++ b/intern/cycles/kernel/kernel.h
@@ -36,13 +36,17 @@ bool kernel_osl_use(KernelGlobals *kg);
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height);
-void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y);
-void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y);
+void kernel_cpu_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state,
+ int sample, int x, int y, int offset, int stride);
+void kernel_cpu_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
+ int sample, int resolution, int x, int y, int offset, int stride);
void kernel_cpu_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i);
#ifdef WITH_OPTIMIZED_KERNEL
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y);
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y);
+void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state,
+ int sample, int x, int y, int offset, int stride);
+void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer,
+ int sample, int resolution, int x, int y, int offset, int stride);
void kernel_cpu_optimized_displace(KernelGlobals *kg, uint4 *input, float3 *offset, int i);
#endif
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 9cdc2f1f865..2dbdd076891 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -74,8 +74,8 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
ray->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
ray->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
- ray->dD.dx = normalize(Ddiff + kernel_data.cam.dx) - normalize(Ddiff);
- ray->dD.dy = normalize(Ddiff + kernel_data.cam.dy) - normalize(Ddiff);
+ ray->dD.dx = normalize(Ddiff + float4_to_float3(kernel_data.cam.dx)) - normalize(Ddiff);
+ ray->dD.dy = normalize(Ddiff + float4_to_float3(kernel_data.cam.dy)) - normalize(Ddiff);
#endif
#ifdef __CAMERA_CLIPPING__
@@ -107,8 +107,8 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
#ifdef __RAY_DIFFERENTIALS__
/* ray differential */
- ray->dP.dx = kernel_data.cam.dx;
- ray->dP.dy = kernel_data.cam.dy;
+ ray->dP.dx = float4_to_float3(kernel_data.cam.dx);
+ ray->dP.dy = float4_to_float3(kernel_data.cam.dy);
ray->dD.dx = make_float3(0.0f, 0.0f, 0.0f);
ray->dD.dy = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h
index 4373701452e..cd8acc9647a 100644
--- a/intern/cycles/kernel/kernel_film.h
+++ b/intern/cycles/kernel/kernel_film.h
@@ -48,10 +48,9 @@ __device uchar4 film_float_to_byte(float4 color)
return result;
}
-__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y)
+__device void kernel_film_tonemap(KernelGlobals *kg, __global uchar4 *rgba, __global float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
{
- int w = kernel_data.cam.width;
- int index = x + y*w;
+ int index = offset + x + y*stride;
float4 irradiance = buffer[index];
float4 float_result = film_map(kg, irradiance, sample);
diff --git a/intern/cycles/kernel/kernel_optimized.cpp b/intern/cycles/kernel/kernel_optimized.cpp
index 85a2b798a62..ea43e01ab58 100644
--- a/intern/cycles/kernel/kernel_optimized.cpp
+++ b/intern/cycles/kernel/kernel_optimized.cpp
@@ -35,16 +35,16 @@ CCL_NAMESPACE_BEGIN
/* Path Tracing */
-void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y)
+void kernel_cpu_optimized_path_trace(KernelGlobals *kg, float4 *buffer, unsigned int *rng_state, int sample, int x, int y, int offset, int stride)
{
- kernel_path_trace(kg, buffer, rng_state, sample, x, y);
+ kernel_path_trace(kg, buffer, rng_state, sample, x, y, offset, stride);
}
/* Tonemapping */
-void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y)
+void kernel_cpu_optimized_tonemap(KernelGlobals *kg, uchar4 *rgba, float4 *buffer, int sample, int resolution, int x, int y, int offset, int stride)
{
- kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y);
+ kernel_film_tonemap(kg, rgba, buffer, sample, resolution, x, y, offset, stride);
}
/* Displacement */
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index c609f6f13fe..05707f31352 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -34,7 +34,7 @@
CCL_NAMESPACE_BEGIN
#ifdef __MODIFY_TP__
-__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int sample)
+__device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global float3 *buffer, int x, int y, int offset, int stride, int sample)
{
/* modify throughput to influence path termination probability, to avoid
darker regions receiving fewer samples than lighter regions. also RGB
@@ -45,7 +45,7 @@ __device float3 path_terminate_modified_throughput(KernelGlobals *kg, __global f
const float minL = 0.1f;
if(sample >= minsample) {
- float3 L = buffer[x + y*kernel_data.cam.width];
+ float3 L = buffer[offset + x + y*stride];
float3 Lmin = make_float3(minL, minL, minL);
float correct = (float)(sample+1)/(float)sample;
@@ -379,7 +379,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
return make_float4(L.x, L.y, L.z, 1.0f - Ltransparent);
}
-__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y)
+__device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __global uint *rng_state, int sample, int x, int y, int offset, int stride)
{
/* initialize random numbers */
RNG rng;
@@ -387,7 +387,7 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl
float filter_u;
float filter_v;
- path_rng_init(kg, rng_state, sample, &rng, x, y, &filter_u, &filter_v);
+ path_rng_init(kg, rng_state, sample, &rng, x, y, offset, stride, &filter_u, &filter_v);
/* sample camera ray */
Ray ray;
@@ -399,7 +399,7 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl
/* integrate */
#ifdef __MODIFY_TP__
- float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, sample);
+ float3 throughput = path_terminate_modified_throughput(kg, buffer, x, y, offset, stride, sample);
float4 L = kernel_path_integrate(kg, &rng, sample, ray, throughput)/throughput;
#else
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
@@ -407,14 +407,14 @@ __device void kernel_path_trace(KernelGlobals *kg, __global float4 *buffer, __gl
#endif
/* accumulate result in output buffer */
- int index = x + y*kernel_data.cam.width;
+ int index = offset + x + y*stride;
if(sample == 0)
buffer[index] = L;
else
buffer[index] += L;
- path_rng_end(kg, rng_state, rng, x, y);
+ path_rng_end(kg, rng_state, rng, x, y, offset, stride);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index ba97ab3e3b6..41301ebd3dc 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -123,7 +123,7 @@ __device_inline float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dime
#endif
}
-__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
+__device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy)
{
#ifdef __SOBOL_FULL_SCREEN__
uint px, py;
@@ -138,7 +138,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state,
*fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x;
*fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y;
#else
- *rng = rng_state[x + y*kernel_data.cam.width];
+ *rng = rng_state[offset + x + y*stride];
*rng ^= kernel_data.integrator.seed;
@@ -147,7 +147,7 @@ __device_inline void path_rng_init(KernelGlobals *kg, __global uint *rng_state,
#endif
}
-__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y)
+__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride)
{
/* nothing to do */
}
@@ -163,10 +163,10 @@ __device float path_rng(KernelGlobals *kg, RNG *rng, int sample, int dimension)
return (float)*rng * (1.0f/(float)0xFFFFFFFF);
}
-__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, float *fx, float *fy)
+__device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sample, RNG *rng, int x, int y, int offset, int stride, float *fx, float *fy)
{
/* load state */
- *rng = rng_state[x + y*kernel_data.cam.width];
+ *rng = rng_state[offset + x + y*stride];
*rng ^= kernel_data.integrator.seed;
@@ -174,10 +174,10 @@ __device void path_rng_init(KernelGlobals *kg, __global uint *rng_state, int sam
*fy = path_rng(kg, rng, sample, PRNG_FILTER_V);
}
-__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y)
+__device void path_rng_end(KernelGlobals *kg, __global uint *rng_state, RNG rng, int x, int y, int offset, int stride)
{
/* store state for next sample */
- rng_state[x + y*kernel_data.cam.width] = rng;
+ rng_state[offset + x + y*stride] = rng;
}
#endif
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index d9bd645b16d..ea73f87a8a5 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -295,29 +295,24 @@ typedef struct ShaderData {
#endif
} ShaderData;
-/* Constrant Kernel Data */
+/* Constrant Kernel Data
+ *
+ * These structs are passed from CPU to various devices, and the struct layout
+ * must match exactly. Structs are padded to ensure 16 byte alignment, and we
+ * do not use float3 because its size may not be the same on all devices. */
typedef struct KernelCamera {
/* type */
int ortho;
- int pad;
-
- /* size */
- int width, height;
+ int pad1, pad2, pad3;
/* matrices */
Transform cameratoworld;
Transform rastertocamera;
/* differentials */
- float3 dx;
-#ifndef WITH_OPENCL
- float pad1;
-#endif
- float3 dy;
-#ifndef WITH_OPENCL
- float pad2;
-#endif
+ float4 dx;
+ float4 dy;
/* depth of field */
float aperturesize;
@@ -358,10 +353,6 @@ typedef struct KernelBackground {
typedef struct KernelSunSky {
/* sun direction in spherical and cartesian */
float theta, phi, pad3, pad4;
- float3 dir;
-#ifndef WITH_OPENCL
- float pad;
-#endif
/* perez function parameters */
float zenith_Y, zenith_x, zenith_y, pad2;
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index acdddb475d0..29141b25b59 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -36,8 +36,6 @@ CCL_NAMESPACE_BEGIN
RenderBuffers::RenderBuffers(Device *device_)
{
device = device_;
- width = 0;
- height = 0;
}
RenderBuffers::~RenderBuffers()
@@ -58,24 +56,23 @@ void RenderBuffers::device_free()
}
}
-void RenderBuffers::reset(Device *device, int width_, int height_)
+void RenderBuffers::reset(Device *device, BufferParams& params_)
{
- width = width_;
- height = height_;
+ params = params_;
/* free existing buffers */
device_free();
/* allocate buffer */
- buffer.resize(width, height);
+ buffer.resize(params.width, params.height);
device->mem_alloc(buffer, MEM_READ_WRITE);
device->mem_zero(buffer);
/* allocate rng state */
- rng_state.resize(width, height);
+ rng_state.resize(params.width, params.height);
- uint *init_state = rng_state.resize(width, height);
- int x, y;
+ uint *init_state = rng_state.resize(params.width, params.height);
+ int x, y, width = params.width, height = params.height;
for(x=0; x<width; x++)
for(y=0; y<height; y++)
@@ -92,11 +89,11 @@ float4 *RenderBuffers::copy_from_device(float exposure, int sample)
device->mem_copy_from(buffer, 0, buffer.memory_size());
- float4 *out = new float4[width*height];
+ float4 *out = new float4[params.width*params.height];
float4 *in = (float4*)buffer.data_pointer;
float scale = 1.0f/(float)sample;
- for(int i = width*height - 1; i >= 0; i--) {
+ for(int i = params.width*params.height - 1; i >= 0; i--) {
float4 rgba = in[i]*scale;
rgba.x = rgba.x*exposure;
@@ -117,8 +114,6 @@ float4 *RenderBuffers::copy_from_device(float exposure, int sample)
DisplayBuffer::DisplayBuffer(Device *device_)
{
device = device_;
- width = 0;
- height = 0;
draw_width = 0;
draw_height = 0;
transparent = true; /* todo: determine from background */
@@ -137,28 +132,27 @@ void DisplayBuffer::device_free()
}
}
-void DisplayBuffer::reset(Device *device, int width_, int height_)
+void DisplayBuffer::reset(Device *device, BufferParams& params_)
{
draw_width = 0;
draw_height = 0;
- width = width_;
- height = height_;
+ params = params_;
/* free existing buffers */
device_free();
/* allocate display pixels */
- rgba.resize(width, height);
+ rgba.resize(params.width, params.height);
device->pixels_alloc(rgba);
}
-void DisplayBuffer::draw_set(int width_, int height_)
+void DisplayBuffer::draw_set(int width, int height)
{
- assert(width_ <= width && height_ <= height);
+ assert(width <= params.width && height <= params.height);
- draw_width = width_;
- draw_height = height_;
+ draw_width = width;
+ draw_height = height;
}
void DisplayBuffer::draw_transparency_grid()
@@ -175,11 +169,11 @@ void DisplayBuffer::draw_transparency_grid()
};
glColor4ub(50, 50, 50, 255);
- glRectf(0, 0, width, height);
+ glRectf(0, 0, params.width, params.height);
glEnable(GL_POLYGON_STIPPLE);
glColor4ub(55, 55, 55, 255);
glPolygonStipple(checker_stipple_sml);
- glRectf(0, 0, width, height);
+ glRectf(0, 0, params.width, params.height);
glDisable(GL_POLYGON_STIPPLE);
}
@@ -189,7 +183,7 @@ void DisplayBuffer::draw(Device *device)
if(transparent)
draw_transparency_grid();
- device->draw_pixels(rgba, 0, draw_width, draw_height, width, height, transparent);
+ device->draw_pixels(rgba, 0, draw_width, draw_height, params.width, params.height, transparent);
}
}
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index d5eb8d7fa2f..66bd03c8893 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -30,12 +30,49 @@ CCL_NAMESPACE_BEGIN
class Device;
struct float4;
+/* Buffer Parameters
+ Size of render buffer and how it fits in the full image (border render). */
+
+class BufferParams {
+public:
+ /* width/height of the physical buffer */
+ int width;
+ int height;
+
+ /* offset into and width/height of the full buffer */
+ int full_x;
+ int full_y;
+ int full_width;
+ int full_height;
+
+ BufferParams()
+ {
+ width = 0;
+ height = 0;
+
+ full_x = 0;
+ full_y = 0;
+ full_width = 0;
+ full_height = 0;
+ }
+
+ bool modified(const BufferParams& params)
+ {
+ return !(full_x == params.full_x
+ && full_y == params.full_y
+ && width == params.width
+ && height == params.height
+ && full_width == params.full_width
+ && full_height == params.full_height);
+ }
+};
+
/* Render Buffers */
class RenderBuffers {
public:
- /* buffer dimensions */
- int width, height;
+ /* buffer parameters */
+ BufferParams params;
/* float buffer */
device_vector<float4> buffer;
/* random number generator state */
@@ -46,7 +83,7 @@ public:
RenderBuffers(Device *device);
~RenderBuffers();
- void reset(Device *device, int width, int height);
+ void reset(Device *device, BufferParams& params);
float4 *copy_from_device(float exposure, int sample);
protected:
@@ -62,8 +99,8 @@ protected:
class DisplayBuffer {
public:
- /* buffer dimensions */
- int width, height;
+ /* buffer parameters */
+ BufferParams params;
/* dimensions for how much of the buffer is actually ready for display.
with progressive render we can be using only a subset of the buffer.
if these are zero, it means nothing can be drawn yet */
@@ -78,7 +115,7 @@ public:
DisplayBuffer(Device *device);
~DisplayBuffer();
- void reset(Device *device, int width, int height);
+ void reset(Device *device, BufferParams& params);
void write(Device *device, const string& filename);
void draw_set(int width, int height);
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index e88c0a388bc..a83ae81844c 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -72,8 +72,9 @@ void Camera::update()
if(!need_update)
return;
+ /* ndc to raster */
Transform screentocamera;
- Transform ndctoraster = transform_scale((float)width, (float)height, 1.0f);
+ Transform ndctoraster = transform_scale(width, height, 1.0f);
/* raster to screen */
Transform screentoraster = ndctoraster *
@@ -148,13 +149,9 @@ void Camera::device_update(Device *device, DeviceScene *dscene)
/* type */
kcam->ortho = ortho;
- /* size */
- kcam->width = width;
- kcam->height = height;
-
/* store differentials */
- kcam->dx = dx;
- kcam->dy = dy;
+ kcam->dx = float3_to_float4(dx);
+ kcam->dy = float3_to_float4(dy);
/* clipping */
kcam->nearclip = nearclip;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 7d873221cd6..81d156a079d 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -273,7 +273,6 @@ static void sky_texture_precompute(KernelSunSky *ksunsky, float3 dir, float turb
ksunsky->theta = theta;
ksunsky->phi = phi;
- ksunsky->dir = dir;
float theta2 = theta*theta;
float theta3 = theta*theta*theta;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 42b4a2bb7e4..26c4dbfbb7a 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -51,8 +51,6 @@ Session::Session(const SessionParams& params_)
sample = 0;
delayed_reset.do_reset = false;
- delayed_reset.w = 0;
- delayed_reset.h = 0;
delayed_reset.samples = 0;
display_outdated = false;
@@ -108,7 +106,7 @@ bool Session::ready_to_reset()
/* GPU Session */
-void Session::reset_gpu(int w, int h, int samples)
+void Session::reset_gpu(BufferParams& buffer_params, int samples)
{
/* block for buffer acces and reset immediately. we can't do this
in the thread, because we need to allocate an OpenGL buffer, and
@@ -119,7 +117,7 @@ void Session::reset_gpu(int w, int h, int samples)
display_outdated = true;
reset_time = time_dt();
- reset_(w, h, samples);
+ reset_(buffer_params, samples);
gpu_need_tonemap = false;
gpu_need_tonemap_cond.notify_all();
@@ -127,7 +125,7 @@ void Session::reset_gpu(int w, int h, int samples)
pause_cond.notify_all();
}
-bool Session::draw_gpu(int w, int h)
+bool Session::draw_gpu(BufferParams& buffer_params)
{
/* block for buffer access */
thread_scoped_lock display_lock(display->mutex);
@@ -136,7 +134,7 @@ bool Session::draw_gpu(int w, int h)
if(gpu_draw_ready) {
/* then verify the buffers have the expected size, so we don't
draw previous results in a resized window */
- if(w == display->width && h == display->height) {
+ if(!buffer_params.modified(display->params)) {
/* for CUDA we need to do tonemapping still, since we can
only access GL buffers from the main thread */
if(gpu_need_tonemap) {
@@ -261,15 +259,14 @@ void Session::run_gpu()
/* CPU Session */
-void Session::reset_cpu(int w, int h, int samples)
+void Session::reset_cpu(BufferParams& buffer_params, int samples)
{
thread_scoped_lock reset_lock(delayed_reset.mutex);
display_outdated = true;
reset_time = time_dt();
- delayed_reset.w = w;
- delayed_reset.h = h;
+ delayed_reset.params = buffer_params;
delayed_reset.samples = samples;
delayed_reset.do_reset = true;
device->task_cancel();
@@ -277,7 +274,7 @@ void Session::reset_cpu(int w, int h, int samples)
pause_cond.notify_all();
}
-bool Session::draw_cpu(int w, int h)
+bool Session::draw_cpu(BufferParams& buffer_params)
{
thread_scoped_lock display_lock(display->mutex);
@@ -285,7 +282,7 @@ bool Session::draw_cpu(int w, int h)
if(display->draw_ready()) {
/* then verify the buffers have the expected size, so we don't
draw previous results in a resized window */
- if(w == display->width && h == display->height) {
+ if(!buffer_params.modified(display->params)) {
display->draw(device);
if(display_outdated && (time_dt() - reset_time) > params.text_timeout)
@@ -306,7 +303,7 @@ void Session::run_cpu()
thread_scoped_lock buffers_lock(buffers->mutex);
thread_scoped_lock display_lock(display->mutex);
- reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples);
+ reset_(delayed_reset.params, delayed_reset.samples);
delayed_reset.do_reset = false;
}
@@ -389,7 +386,7 @@ void Session::run_cpu()
if(delayed_reset.do_reset) {
/* reset rendering if request from main thread */
delayed_reset.do_reset = false;
- reset_(delayed_reset.w, delayed_reset.h, delayed_reset.samples);
+ reset_(delayed_reset.params, delayed_reset.samples);
}
else if(need_tonemap) {
/* tonemap only if we do not reset, we don't we don't
@@ -438,23 +435,23 @@ void Session::run()
progress.set_update();
}
-bool Session::draw(int w, int h)
+bool Session::draw(BufferParams& buffer_params)
{
if(device_use_gl)
- return draw_gpu(w, h);
+ return draw_gpu(buffer_params);
else
- return draw_cpu(w, h);
+ return draw_cpu(buffer_params);
}
-void Session::reset_(int w, int h, int samples)
+void Session::reset_(BufferParams& buffer_params, int samples)
{
- if(w != buffers->width || h != buffers->height) {
+ if(buffer_params.modified(buffers->params)) {
gpu_draw_ready = false;
- buffers->reset(device, w, h);
- display->reset(device, w, h);
+ buffers->reset(device, buffer_params);
+ display->reset(device, buffer_params);
}
- tile_manager.reset(w, h, samples);
+ tile_manager.reset(buffer_params, samples);
start_time = time_dt();
preview_time = 0.0;
@@ -462,12 +459,12 @@ void Session::reset_(int w, int h, int samples)
sample = 0;
}
-void Session::reset(int w, int h, int samples)
+void Session::reset(BufferParams& buffer_params, int samples)
{
if(device_use_gl)
- reset_gpu(w, h, samples);
+ reset_gpu(buffer_params, samples);
else
- reset_cpu(w, h, samples);
+ reset_cpu(buffer_params, samples);
}
void Session::set_samples(int samples)
@@ -514,14 +511,18 @@ void Session::update_scene()
progress.set_status("Updating Scene");
- /* update camera if dimensions changed for progressive render */
+ /* update camera if dimensions changed for progressive render. the camera
+ knows nothing about progressive or cropped rendering, it just gets the
+ image dimensions passed in */
Camera *cam = scene->camera;
- int w = tile_manager.state.width;
- int h = tile_manager.state.height;
-
- if(cam->width != w || cam->height != h) {
- cam->width = w;
- cam->height = h;
+ float progressive_x = tile_manager.state.width/(float)tile_manager.params.width;
+ float progressive_y = tile_manager.state.height/(float)tile_manager.params.height;
+ int width = tile_manager.params.full_width*progressive_x;
+ int height = tile_manager.params.full_height*progressive_y;
+
+ if(width != cam->width || height != cam->height) {
+ cam->width = width;
+ cam->height = height;
cam->tag_update();
}
@@ -573,14 +574,16 @@ void Session::path_trace(Tile& tile)
/* add path trace task */
DeviceTask task(DeviceTask::PATH_TRACE);
- task.x = tile.x;
- task.y = tile.y;
+ task.x = tile_manager.state.full_x + tile.x;
+ task.y = tile_manager.state.full_y + tile.y;
task.w = tile.w;
task.h = tile.h;
task.buffer = buffers->buffer.device_pointer;
task.rng_state = buffers->rng_state.device_pointer;
task.sample = tile_manager.state.sample;
task.resolution = tile_manager.state.resolution;
+ task.offset = -(tile_manager.state.full_x + tile_manager.state.full_y*tile_manager.state.width);
+ task.stride = tile_manager.state.width;
device->task_add(task);
}
@@ -590,14 +593,16 @@ void Session::tonemap()
/* add tonemap task */
DeviceTask task(DeviceTask::TONEMAP);
- task.x = 0;
- task.y = 0;
+ task.x = tile_manager.state.full_x;
+ task.y = tile_manager.state.full_y;
task.w = tile_manager.state.width;
task.h = tile_manager.state.height;
task.rgba = display->rgba.device_pointer;
task.buffer = buffers->buffer.device_pointer;
task.sample = tile_manager.state.sample;
task.resolution = tile_manager.state.resolution;
+ task.offset = -(tile_manager.state.full_x + tile_manager.state.full_y*tile_manager.state.width);
+ task.stride = tile_manager.state.width;
if(task.w > 0 && task.h > 0) {
device->task_add(task);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index ce7f420096a..89979b8c451 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -19,6 +19,7 @@
#ifndef __SESSION_H__
#define __SESSION_H__
+#include "buffers.h"
#include "device.h"
#include "tile.h"
@@ -27,6 +28,7 @@
CCL_NAMESPACE_BEGIN
+class BufferParams;
class Device;
class DeviceScene;
class DisplayBuffer;
@@ -106,11 +108,11 @@ public:
~Session();
void start();
- bool draw(int w, int h);
+ bool draw(BufferParams& params);
void wait();
bool ready_to_reset();
- void reset(int w, int h, int samples);
+ void reset(BufferParams& params, int samples);
void set_samples(int samples);
void set_pause(bool pause);
@@ -118,7 +120,7 @@ protected:
struct DelayedReset {
thread_mutex mutex;
bool do_reset;
- int w, h;
+ BufferParams params;
int samples;
} delayed_reset;
@@ -129,15 +131,15 @@ protected:
void tonemap();
void path_trace(Tile& tile);
- void reset_(int w, int h, int samples);
+ void reset_(BufferParams& params, int samples);
void run_cpu();
- bool draw_cpu(int w, int h);
- void reset_cpu(int w, int h, int samples);
+ bool draw_cpu(BufferParams& params);
+ void reset_cpu(BufferParams& params, int samples);
void run_gpu();
- bool draw_gpu(int w, int h);
- void reset_gpu(int w, int h, int samples);
+ bool draw_gpu(BufferParams& params);
+ void reset_gpu(BufferParams& params, int samples);
TileManager tile_manager;
bool device_use_gl;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index ba437e74874..b118a7ba478 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -28,21 +28,21 @@ TileManager::TileManager(bool progressive_, int samples_, int tile_size_, int mi
tile_size = tile_size_;
min_size = min_size_;
- reset(0, 0, 0);
+ BufferParams buffer_params;
+ reset(buffer_params, 0);
}
TileManager::~TileManager()
{
}
-void TileManager::reset(int width_, int height_, int samples_)
+void TileManager::reset(BufferParams& params_, int samples_)
{
- full_width = width_;
- full_height = height_;
+ params = params_;
start_resolution = 1;
- int w = width_, h = height_;
+ int w = params.width, h = params.height;
if(min_size != INT_MAX) {
while(w*h > min_size*min_size) {
@@ -55,6 +55,8 @@ void TileManager::reset(int width_, int height_, int samples_)
samples = samples_;
+ state.full_x = 0;
+ state.full_y = 0;
state.width = 0;
state.height = 0;
state.sample = -1;
@@ -70,8 +72,8 @@ void TileManager::set_samples(int samples_)
void TileManager::set_tiles()
{
int resolution = state.resolution;
- int image_w = max(1, full_width/resolution);
- int image_h = max(1, full_height/resolution);
+ int image_w = max(1, params.width/resolution);
+ int image_h = max(1, params.height/resolution);
int tile_w = (image_w + tile_size - 1)/tile_size;
int tile_h = (image_h + tile_size - 1)/tile_size;
int sub_w = image_w/tile_w;
@@ -90,6 +92,8 @@ void TileManager::set_tiles()
}
}
+ state.full_x = params.full_x/resolution;
+ state.full_y = params.full_y/resolution;
state.width = image_w;
state.height = image_h;
}
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index 5cd16eb8afa..76863d23498 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -21,6 +21,7 @@
#include <limits.h>
+#include "buffers.h"
#include "util_list.h"
CCL_NAMESPACE_BEGIN
@@ -39,7 +40,10 @@ public:
class TileManager {
public:
+ BufferParams params;
struct State {
+ int full_x;
+ int full_y;
int width;
int height;
int sample;
@@ -50,7 +54,7 @@ public:
TileManager(bool progressive, int samples, int tile_size, int min_size);
~TileManager();
- void reset(int width, int height, int samples);
+ void reset(BufferParams& params, int samples);
void set_samples(int samples);
bool next();
bool done();
@@ -63,8 +67,6 @@ protected:
int tile_size;
int min_size;
- int full_width;
- int full_height;
int start_resolution;
};
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 7c56f0fbb12..0a1d8ff4555 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -536,6 +536,11 @@ __device_inline float3 float4_to_float3(const float4 a)
return make_float3(a.x, a.y, a.z);
}
+__device_inline float4 float3_to_float4(const float3 a)
+{
+ return make_float4(a.x, a.y, a.z, 1.0f);
+}
+
#ifndef __KERNEL_GPU__
__device_inline void print_float3(const char *label, const float3& a)
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index 4bf3759dd75..07db52f6392 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -209,6 +209,13 @@ __device_inline float3 transform_get_column(const Transform *t, int column)
return make_float3(t->x[column], t->y[column], t->z[column]);
}
+__device_inline void transform_set_column(Transform *t, int column, float3 value)
+{
+ t->x[column] = value.x;
+ t->y[column] = value.y;
+ t->z[column] = value.z;
+}
+
Transform transform_inverse(const Transform& a);
__device_inline bool transform_uniform_scale(const Transform& tfm, float& scale)
@@ -244,6 +251,17 @@ __device_inline bool transform_negative_scale(const Transform& tfm)
return (dot(cross(c0, c1), c2) < 0.0f);
}
+__device_inline Transform transform_clear_scale(const Transform& tfm)
+{
+ Transform ntfm = tfm;
+
+ transform_set_column(&ntfm, 0, normalize(transform_get_column(&ntfm, 0)));
+ transform_set_column(&ntfm, 1, normalize(transform_get_column(&ntfm, 1)));
+ transform_set_column(&ntfm, 2, normalize(transform_get_column(&ntfm, 2)));
+
+ return ntfm;
+}
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index 01217dfd17a..fbb474cb20a 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -34,6 +34,7 @@
#endif
#include <OpenGL/gl.h>
+#include <OpenGL/CGLRenderers.h>
/***** Multithreaded opengl code : uncomment for enabling
#include <OpenGL/OpenGL.h>
*/
@@ -485,7 +486,14 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
// needed for 'Draw Overlap' drawing method
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
- pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
+ // Force software OpenGL, for debugging
+ if(getenv("BLENDER_SOFTWAREGL")) {
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
+ pixelFormatAttrsWindow[i++] = kCGLRendererGenericID;
+ }
+ else
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
+
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
@@ -521,7 +529,14 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
// needed for 'Draw Overlap' drawing method
pixelFormatAttrsWindow[i++] = NSOpenGLPFABackingStore;
- pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
+ // Force software OpenGL, for debugging
+ if(getenv("BLENDER_SOFTWAREGL")) {
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFARendererID;
+ pixelFormatAttrsWindow[i++] = kCGLRendererGenericID;
+ }
+ else
+ pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
+
//pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,; // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 1da5e2ca381..58941e00914 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -29,6 +29,8 @@ from bpy.props import (StringProperty,
from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
+import subprocess
+import os
class MESH_OT_delete_edgeloop(Operator):
'''Delete an edge loop by merging the faces on each side to a single face loop'''
@@ -1175,6 +1177,26 @@ class WM_OT_copy_prev_settings(Operator):
return {'CANCELLED'}
+class WM_OT_blenderplayer_start(bpy.types.Operator):
+ '''Launches the Blenderplayer with the current blendfile'''
+ bl_idname = "wm.blenderplayer_start"
+ bl_label = "Start"
+
+ blender_bin_path = bpy.app.binary_path
+ blender_bin_dir = os.path.dirname(blender_bin_path)
+ ext = os.path.splitext(blender_bin_path)[-1]
+ player_path = os.path.join(blender_bin_dir, 'blenderplayer' + ext)
+
+ def execute(self, context):
+ import sys
+
+ if sys.platform == 'darwin':
+ self.player_path = os.path.join(self.blender_bin_dir, '../../../blenderplayer.app/Contents/MacOS/blenderplayer')
+
+ filepath = bpy.app.tempdir + "game.blend"
+ bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True)
+ subprocess.call([self.player_path, filepath])
+ return {'FINISHED'}
class WM_OT_keyconfig_test(Operator):
"Test keyconfig for conflicts"
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index db65b0ff669..66b8cca7866 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -244,16 +244,22 @@ class RenderButtonsPanel():
return (rd.engine in cls.COMPAT_ENGINES)
-class RENDER_PT_game(RenderButtonsPanel, Panel):
- bl_label = "Game"
+class RENDER_PT_embedded(RenderButtonsPanel, bpy.types.Panel):
+ bl_label = "Embedded Player"
COMPAT_ENGINES = {'BLENDER_GAME'}
-
def draw(self, context):
layout = self.layout
+ rd = context.scene.render
+
row = layout.row()
row.operator("view3d.game_start", text="Start")
row.label()
+ row = layout.row()
+ row.label(text="Resolution:")
+ row = layout.row(align=True)
+ row.prop(rd, "resolution_x", slider=False, text="X")
+ row.prop(rd, "resolution_y", slider=False, text="Y")
class RENDER_PT_game_player(RenderButtonsPanel, Panel):
@@ -264,29 +270,23 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel):
layout = self.layout
gs = context.scene.game_settings
-
- layout.prop(gs, "show_fullscreen")
-
- split = layout.split()
-
- col = split.column()
- col.label(text="Resolution:")
- sub = col.column(align=True)
- sub.prop(gs, "resolution_x", slider=False, text="X")
- sub.prop(gs, "resolution_y", slider=False, text="Y")
-
- col = split.column()
+
+ row = layout.row()
+ row.operator("wm.blenderplayer_start", text="Start")
+ row.prop(gs, "show_fullscreen")
+
+ row = layout.row()
+ row.label(text="Resolution:")
+ row = layout.row(align=True)
+ row.prop(gs, "resolution_x", slider=False, text="X")
+ row.prop(gs, "resolution_y", slider=False, text="Y")
+
+ col = layout.column()
col.label(text="Quality:")
- sub = col.column(align=True)
- sub.prop(gs, "depth", text="Bit Depth", slider=False)
- sub.prop(gs, "frequency", text="FPS", slider=False)
+ col = layout.column(align=True)
+ col.prop(gs, "depth", text="Bit Depth", slider=False)
+ col.prop(gs, "frequency", text="Refresh Rate", slider=False)
- # framing:
- col = layout.column()
- col.label(text="Framing:")
- col.row().prop(gs, "frame_type", expand=True)
- if gs.frame_type == 'LETTERBOX':
- col.prop(gs, "frame_color", text="")
class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
@@ -368,20 +368,24 @@ class RENDER_PT_game_shading(RenderButtonsPanel, Panel):
col.prop(gs, "use_glsl_extra_textures", text="Extra Textures")
-class RENDER_PT_game_performance(RenderButtonsPanel, Panel):
- bl_label = "Performance"
+class RENDER_PT_game_system(RenderButtonsPanel, Panel):
+ bl_label = "System"
COMPAT_ENGINES = {'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
gs = context.scene.game_settings
- col = layout.column()
- row = col.row()
+ row = layout.row()
row.prop(gs, "use_frame_rate")
+ row.prop(gs, "restrict_animation_updates")
+
+ row = layout.row()
row.prop(gs, "use_display_lists")
- col.prop(gs, "restrict_animation_updates")
+ row = layout.row()
+ row.label("Exit Key")
+ row.prop(gs, "exit_key", text="", event=True)
class RENDER_PT_game_display(RenderButtonsPanel, Panel):
@@ -391,6 +395,9 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ row = layout.row()
+ row.prop(context.scene.render, "fps", text="Animation Frame Rate", slider=False)
+
gs = context.scene.game_settings
flow = layout.column_flow()
flow.prop(gs, "show_debug_properties", text="Debug Properties")
@@ -399,6 +406,12 @@ class RENDER_PT_game_display(RenderButtonsPanel, Panel):
flow.prop(gs, "use_deprecation_warnings")
flow.prop(gs, "show_mouse", text="Mouse Cursor")
+ col = layout.column()
+ col.label(text="Framing:")
+ col.row().prop(gs, "frame_type", expand=True)
+ if gs.frame_type == 'LETTERBOX':
+ col.prop(gs, "frame_color", text="")
+
class SceneButtonsPanel():
bl_space_type = 'PROPERTIES'
@@ -463,6 +476,20 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
row.prop(rd, "sample_dist")
row.prop(rd, "sample_max_error")
+class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
+ bl_label = "Sound"
+ COMPAT_ENGINES = {'BLENDER_GAME'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+
+ layout.prop(scene, "audio_distance_model")
+
+ col = layout.column(align=True)
+ col.prop(scene, "audio_doppler_speed", text="Speed")
+ col.prop(scene, "audio_doppler_factor")
class WorldButtonsPanel():
bl_space_type = 'PROPERTIES'
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index f7f67527b63..b19cf0032af 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -76,7 +76,7 @@ class ParticleButtonsPanel():
class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
bl_label = ""
bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@classmethod
def poll(cls, context):
@@ -85,6 +85,10 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+
+ if context.scene.render.engine == "BLENDER_GAME":
+ layout.label("Not available in the Game Engine")
+ return
ob = context.object
psys = context.particle_system
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 4b4c2d2b214..6a8439ffaaa 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -51,7 +51,7 @@ class RenderButtonsPanel():
@classmethod
def poll(cls, context):
rd = context.scene.render
- return (context.scene and rd.use_game_engine is False) and (rd.engine in cls.COMPAT_ENGINES)
+ return context.scene and (rd.engine in cls.COMPAT_ENGINES)
class RENDER_PT_render(RenderButtonsPanel, Panel):
@@ -553,7 +553,7 @@ class RENDER_PT_encoding(RenderButtonsPanel, Panel):
class RENDER_PT_bake(RenderButtonsPanel, Panel):
bl_label = "Bake"
bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 05f4887a542..b7218e4ba47 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -29,12 +29,13 @@ class SceneButtonsPanel():
@classmethod
def poll(cls, context):
- return context.scene
+ rd = context.scene.render
+ return context.scene and (rd.engine in cls.COMPAT_ENGINES)
class SCENE_PT_scene(SceneButtonsPanel, Panel):
bl_label = "Scene"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
@@ -75,7 +76,7 @@ class SCENE_PT_audio(SceneButtonsPanel, Panel):
class SCENE_PT_unit(SceneButtonsPanel, Panel):
bl_label = "Units"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
@@ -93,6 +94,7 @@ class SCENE_PT_unit(SceneButtonsPanel, Panel):
class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
bl_label = "Keying Sets"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
layout = self.layout
@@ -125,6 +127,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, Panel):
class SCENE_PT_keying_set_paths(SceneButtonsPanel, Panel):
bl_label = "Active Keying Set"
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py
index 1ae8095fab3..1fc58475ace 100644
--- a/release/scripts/startup/bl_ui/space_logic.py
+++ b/release/scripts/startup/bl_ui/space_logic.py
@@ -70,7 +70,9 @@ class LOGIC_HT_header(Header):
layout.template_header()
if context.area.show_menus:
- layout.menu("LOGIC_MT_view")
+ row = layout.row(align=True)
+ row.menu("LOGIC_MT_view")
+ row.menu("LOGIC_MT_logicbricks_add")
class LOGIC_MT_view(Menu):
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index c3b2e30cb12..7249e9522ff 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -174,9 +174,7 @@ class TEXT_MT_text(Menu):
st = context.space_data
text = st.text
- layout.operator_context = 'EXEC_AREA'
layout.operator("text.new")
- layout.operator_context = 'INVOKE_AREA'
layout.operator("text.open")
if text:
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 84f8995b480..23073a2d8eb 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -65,6 +65,11 @@ typedef enum {
* unless it's a mesh and can be exploded -> curve can also emit particles
*/
eModifierTypeType_DeformOrConstruct,
+
+ /* Like eModifierTypeType_Nonconstructive, but does not affect the geometry
+ * of the object, rather some of its CustomData layers.
+ * E.g. UVProject and WeightVG modifiers. */
+ eModifierTypeType_NonGeometrical,
} ModifierTypeType;
typedef enum {
@@ -311,6 +316,7 @@ int modifier_supportsMapping(struct ModifierData *md);
int modifier_couldBeCage(struct Scene *scene, struct ModifierData *md);
int modifier_isCorrectableDeformed(struct ModifierData *md);
int modifier_sameTopology(ModifierData *md);
+int modifier_nonGeometrical(ModifierData *md);
int modifier_isEnabled(struct Scene *scene, struct ModifierData *md, int required_mode);
void modifier_setError(struct ModifierData *md, const char *format, ...)
#ifdef __GNUC__
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 378e5872791..6234308048b 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -305,8 +305,6 @@ void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sc
void ntreeMakeLocal(struct bNodeTree *ntree);
int ntreeHasType(struct bNodeTree *ntree, int type);
-void ntreeSocketUseFlags(struct bNodeTree *ntree);
-
void ntreeUpdateTree(struct bNodeTree *ntree);
/* XXX Currently each tree update call does call to ntreeVerifyNodes too.
* Some day this should be replaced by a decent depsgraph automatism!
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 52fa52a5899..7f321abf48e 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -67,7 +67,7 @@ void free_plugin_tex(struct PluginTex *pit);
void init_colorband(struct ColorBand *coba, int rangetype);
struct ColorBand *add_colorband(int rangetype);
-int do_colorband(struct ColorBand *coba, float in, float out[4]);
+int do_colorband(const struct ColorBand *coba, float in, float out[4]);
void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size);
int vergcband(const void *a1, const void *a2);
struct CBData *colorband_element_add(struct ColorBand *coba, float position);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 3bc2ee61e7b..d0ef517e2ae 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -642,7 +642,7 @@ enum {
CALC_WP_AUTO_NORMALIZE= (1<<1)
};
-void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
+static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
{
float colf[4];
@@ -669,10 +669,10 @@ static void calc_weightpaint_vert_color(
if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
int was_a_nonzero= FALSE;
- int i;
+ unsigned int i;
MDeformWeight *dw= dv->dw;
- for (i = dv->totweight; i > 0; i--, dw++) {
+ for (i = dv->totweight; i != 0; i--, dw++) {
/* in multipaint, get the average if auto normalize is inactive
* get the sum if it is active */
if (dw->def_nr < defbase_tot) {
@@ -717,46 +717,65 @@ void vDM_ColorBand_store(ColorBand *coba)
stored_cb= coba;
}
-static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
+/* return an array of vertex weight colors, caller must free.
+ *
+ * note that we could save some memory and allocate RGB only but then we'd need to
+ * re-arrange the colors when copying to the face since MCol has odd ordering,
+ * so leave this as is - campbell */
+static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba)
{
Mesh *me = ob->data;
- ColorBand *coba= stored_cb; /* warning, not a local var */
-
- unsigned char *wtcol = MEM_mallocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
+ unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v");
if (me->dvert) {
- MDeformVert *dvert= me->dvert;
- MFace *mf = me->mface;
+ unsigned char *wc = wtcol_v;
+ MDeformVert *dv= me->dvert;
+ unsigned int i;
+ /* varisbles for multipaint */
const int defbase_tot = BLI_countlist(&ob->defbase);
const int defbase_act = ob->actdef-1;
char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
/* const int unselected = defbase_tot - selected; */ /* UNUSED */
- int i;
-
- memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
- for (i=0; i<me->totface; i++, mf++) {
- unsigned int fidx= mf->v4 ? 3:2;
- do {
- calc_weightpaint_vert_color(&wtcol[(i*4 + fidx)*4],
- &dvert[*(&mf->v1 + fidx)], coba,
- defbase_tot, defbase_act,
- dg_flags, selected, draw_flag);
- } while (fidx--);
+ for (i = me->totvert; i != 0; i--, wc += 4, dv++) {
+ calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag);
}
MEM_freeN(dg_flags);
}
else {
- /* no weights, fill in zero */
int col_i;
weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
- fill_vn_i((int *)wtcol, me->totface*4, col_i);
+ fill_vn_i((int *)wtcol_v, me->totvert, col_i);
+ }
+
+ return wtcol_v;
+}
+
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
+{
+ ColorBand *coba= stored_cb; /* warning, not a local var */
+
+ Mesh *me = ob->data;
+ unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba);
+ unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f");
+
+ MFace *mf = me->mface;
+ int i;
+
+ for (i=0; i<me->totface; i++, mf++) {
+ unsigned int fidx= mf->v4 ? 3:2;
+ do {
+ copy_v4_v4_char((char *)&wtcol_f[(4 * i + fidx) * 4],
+ (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]);
+ } while (fidx--);
}
- CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
+ MEM_freeN(wtcol_v);
+
+ CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData);
}
/* new value for useDeform -1 (hack for the gameengine):
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index f09be8c34ad..5a389019519 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -239,7 +239,14 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
int modifier_sameTopology(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- return ( mti->type == eModifierTypeType_OnlyDeform || mti->type == eModifierTypeType_Nonconstructive);
+ return ELEM3(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_Nonconstructive,
+ eModifierTypeType_NonGeometrical);
+}
+
+int modifier_nonGeometrical(ModifierData *md)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ return (mti->type == eModifierTypeType_NonGeometrical);
}
void modifier_setError(ModifierData *md, const char *format, ...)
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index cc49e8465b9..ce1dd429794 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1325,32 +1325,6 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
node->flag |= NODE_ACTIVE_TEXTURE;
}
-/* use flags are not persistent yet, groups might need different tagging, so we do it each time
- when we need to get this info */
-void ntreeSocketUseFlags(bNodeTree *ntree)
-{
- bNode *node;
- bNodeSocket *sock;
- bNodeLink *link;
-
- /* clear flags */
- for(node= ntree->nodes.first; node; node= node->next) {
- for(sock= node->inputs.first; sock; sock= sock->next)
- sock->flag &= ~SOCK_IN_USE;
- for(sock= node->outputs.first; sock; sock= sock->next)
- sock->flag &= ~SOCK_IN_USE;
- }
-
- /* tag all thats in use */
- for(link= ntree->links.first; link; link= link->next) {
-
- if(link->fromsock) // FIXME, see below
- link->fromsock->flag |= SOCK_IN_USE;
- if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell
- link->tosock->flag |= SOCK_IN_USE;
- }
-}
-
/* ************** dependency stuff *********** */
/* node is guaranteed to be not checked before */
@@ -1425,16 +1399,27 @@ static void ntree_update_link_pointers(bNodeTree *ntree)
/* first clear data */
for(node= ntree->nodes.first; node; node= node->next) {
- for(sock= node->inputs.first; sock; sock= sock->next)
+ for(sock= node->inputs.first; sock; sock= sock->next) {
sock->link= NULL;
+ sock->flag &= ~SOCK_IN_USE;
+ }
+ for(sock= node->outputs.first; sock; sock= sock->next) {
+ sock->flag &= ~SOCK_IN_USE;
+ }
+ }
+ for(sock= ntree->inputs.first; sock; sock= sock->next) {
+ sock->flag &= ~SOCK_IN_USE;
}
- /* clear socket links */
- for(sock= ntree->outputs.first; sock; sock= sock->next)
+ for(sock= ntree->outputs.first; sock; sock= sock->next) {
sock->link= NULL;
+ sock->flag &= ~SOCK_IN_USE;
+ }
for(link= ntree->links.first; link; link= link->next) {
- if (link->tosock)
- link->tosock->link= link;
+ link->tosock->link= link;
+
+ link->fromsock->flag |= SOCK_IN_USE;
+ link->tosock->flag |= SOCK_IN_USE;
}
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 93404dc25fb..7051376a1f4 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -349,9 +349,9 @@ ColorBand *add_colorband(int rangetype)
/* ------------------------------------------------------------------------- */
-int do_colorband(ColorBand *coba, float in, float out[4])
+int do_colorband(const ColorBand *coba, float in, float out[4])
{
- CBData *cbd1, *cbd2, *cbd0, *cbd3;
+ const CBData *cbd1, *cbd2, *cbd0, *cbd3;
float fac, mfac, t[4];
int a;
diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h
index e27a315a023..32c4e012d1d 100644
--- a/source/blender/blenlib/BLI_dynstr.h
+++ b/source/blender/blenlib/BLI_dynstr.h
@@ -100,6 +100,17 @@ int BLI_dynstr_get_len (DynStr *ds);
*/
char* BLI_dynstr_get_cstring (DynStr *ds);
+/**
+ * Get a DynStr's contents as a c-string.
+ * <i> The str argument must be allocated to be at
+ * least the size of BLI_dynstr_get_len(ds) + 1. </i>
+ *
+ * @param ds The DynStr of interest.
+ * @param str The string to fill.
+ * @return The contents of @a ds as a c-string.
+ */
+void BLI_dynstr_get_cstring_ex (DynStr *ds, char *str);
+
/**
* Free the DynStr
*
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index 349bc3492e7..ad52de180aa 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -226,11 +226,11 @@ int BLI_dynstr_get_len(DynStr *ds)
return ds->curlen;
}
-char *BLI_dynstr_get_cstring(DynStr *ds)
+void BLI_dynstr_get_cstring_ex(DynStr *ds, char *rets)
{
- char *s, *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring");
+ char *s;
DynStrElem *dse;
-
+
for (s= rets, dse= ds->elems; dse; dse= dse->next) {
int slen= strlen(dse->str);
@@ -239,7 +239,12 @@ char *BLI_dynstr_get_cstring(DynStr *ds)
s+= slen;
}
rets[ds->curlen]= '\0';
-
+}
+
+char *BLI_dynstr_get_cstring(DynStr *ds)
+{
+ char *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring");
+ BLI_dynstr_get_cstring_ex(ds, rets);
return rets;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index ab362fba143..8c96e4fa377 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7459,6 +7459,30 @@ void do_versions_image_settings_2_60(Scene *sce)
}
+/* socket use flags were only temporary before */
+static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree)
+{
+ bNode *node;
+ bNodeSocket *sock;
+ bNodeLink *link;
+
+ for (node=ntree->nodes.first; node; node=node->next) {
+ for (sock=node->inputs.first; sock; sock=sock->next)
+ sock->flag &= ~SOCK_IN_USE;
+ for (sock=node->outputs.first; sock; sock=sock->next)
+ sock->flag &= ~SOCK_IN_USE;
+ }
+ for (sock=ntree->inputs.first; sock; sock=sock->next)
+ sock->flag &= ~SOCK_IN_USE;
+ for (sock=ntree->outputs.first; sock; sock=sock->next)
+ sock->flag &= ~SOCK_IN_USE;
+
+ for (link=ntree->links.first; link; link=link->next) {
+ link->fromsock->flag |= SOCK_IN_USE;
+ link->tosock->flag |= SOCK_IN_USE;
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -12688,40 +12712,82 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* put compatibility code here until next subversion bump */
{
- MovieClip *clip;
- Object *ob;
+ {
+ /* update use flags for node sockets (was only temporary before) */
+ Scene *sce;
+ Material *mat;
+ Tex *tex;
+ Lamp *lamp;
+ World *world;
+ bNodeTree *ntree;
- for (clip= main->movieclip.first; clip; clip= clip->id.next) {
- MovieTracking *tracking= &clip->tracking;
- MovieTrackingObject *tracking_object= tracking->objects.first;
+ for (sce=main->scene.first; sce; sce=sce->id.next)
+ if (sce->nodetree)
+ do_versions_nodetree_socket_use_flags_2_62(sce->nodetree);
- if(!tracking->settings.object_distance)
- tracking->settings.object_distance= 1.0f;
+ for (mat=main->mat.first; mat; mat=mat->id.next)
+ if (mat->nodetree)
+ do_versions_nodetree_socket_use_flags_2_62(mat->nodetree);
+
+ for (tex=main->tex.first; tex; tex=tex->id.next)
+ if (tex->nodetree)
+ do_versions_nodetree_socket_use_flags_2_62(tex->nodetree);
- if(tracking->objects.first == NULL)
- BKE_tracking_new_object(tracking, "Camera");
+ for (lamp=main->lamp.first; lamp; lamp=lamp->id.next)
+ if (lamp->nodetree)
+ do_versions_nodetree_socket_use_flags_2_62(lamp->nodetree);
- while(tracking_object) {
- if(!tracking_object->scale)
- tracking_object->scale= 1.0f;
+ for (world=main->world.first; world; world=world->id.next)
+ if (world->nodetree)
+ do_versions_nodetree_socket_use_flags_2_62(world->nodetree);
- tracking_object= tracking_object->next;
+ for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+ do_versions_nodetree_socket_use_flags_2_62(ntree);
+ }
+ {
+ /* Initialize BGE exit key to esc key */
+ Scene *scene;
+ for(scene= main->scene.first; scene; scene= scene->id.next) {
+ if (!scene->gm.exitkey)
+ scene->gm.exitkey = 218; // Blender key code for ESC
}
}
+ {
+ MovieClip *clip;
+ Object *ob;
- for (ob= main->object.first; ob; ob= ob->id.next) {
- bConstraint *con;
- for (con= ob->constraints.first; con; con=con->next) {
- bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ for (clip= main->movieclip.first; clip; clip= clip->id.next) {
+ MovieTracking *tracking= &clip->tracking;
+ MovieTrackingObject *tracking_object= tracking->objects.first;
+
+ if(!tracking->settings.object_distance)
+ tracking->settings.object_distance= 1.0f;
+
+ if(tracking->objects.first == NULL)
+ BKE_tracking_new_object(tracking, "Camera");
+
+ while(tracking_object) {
+ if(!tracking_object->scale)
+ tracking_object->scale= 1.0f;
+
+ tracking_object= tracking_object->next;
+ }
+ }
+
+ for (ob= main->object.first; ob; ob= ob->id.next) {
+ bConstraint *con;
+ for (con= ob->constraints.first; con; con=con->next) {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
- if(!cti)
- continue;
+ if(!cti)
+ continue;
- if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
- bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data;
+ if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER) {
+ bObjectSolverConstraint *data= (bObjectSolverConstraint *)con->data;
- if(data->invmat[3][3]==0.0f)
- unit_m4(data->invmat);
+ if(data->invmat[3][3]==0.0f)
+ unit_m4(data->invmat);
+ }
}
}
}
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index f75f2921e51..3a69db013c0 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -243,6 +243,19 @@ int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob
int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me);
int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name);
+
+/* mirrtopo */
+typedef struct MirrTopoStore_t {
+ intptr_t *index_lookup;
+ int prev_vert_tot;
+ int prev_edge_tot;
+ int prev_ob_mode;
+} MirrTopoStore_t;
+
+int ED_mesh_mirrtopo_recalc_check(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
+void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store);
+void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index ea45337ddb3..9853c9c049b 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -845,7 +845,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif
uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply"), 0, "apply_as", MODIFIER_APPLY_DATA);
- if (modifier_sameTopology(md))
+ if (modifier_sameTopology(md) && !modifier_nonGeometrical(md))
uiItemEnumO(row, "OBJECT_OT_modifier_apply", IFACE_("Apply as Shape"), 0, "apply_as", MODIFIER_APPLY_SHAPE);
}
@@ -853,7 +853,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif
uiBlockSetButLock(block, ob && ob->id.lib, ERROR_LIBDATA_MESSAGE);
if (!ELEM5(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem, eModifierType_Cloth, eModifierType_Smoke))
- uiItemO(row, TIP_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy");
+ uiItemO(row, IFACE_("Copy"), ICON_NONE, "OBJECT_OT_modifier_copy");
}
/* result is the layout block inside the box, that we return so that modifier settings can be drawn */
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 02d20e64bc3..95c71488d26 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -815,3 +815,229 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
return OPERATOR_FINISHED;
}
+
+
+/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
+/* note, this is not the best place for the function to be but moved
+ * here to for the purpose of syncing with bmesh */
+
+typedef int MirrTopoHash_t;
+
+typedef struct MirrTopoPair_t {
+ MirrTopoHash_t hash;
+ int v_index;
+} MirrTopoPair_t;
+
+static int MirrTopo_long_sort(const void *l1, const void *l2)
+{
+ if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2 ) return 1;
+ else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2 ) return -1;
+ return 0;
+}
+
+static int MirrTopo_item_sort(const void *v1, const void *v2)
+{
+ if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1;
+ else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1;
+ return 0;
+}
+
+int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+{
+ int totvert;
+ int totedge;
+
+ if (me->edit_mesh) {
+ totvert= me->edit_mesh->totvert;
+ totedge= me->edit_mesh->totedge;
+ }
+ else {
+ totvert= me->totvert;
+ totedge= me->totedge;
+ }
+
+ if( (mesh_topo_store->index_lookup==NULL) ||
+ (mesh_topo_store->prev_ob_mode != ob_mode) ||
+ (totvert != mesh_topo_store->prev_vert_tot) ||
+ (totedge != mesh_topo_store->prev_edge_tot))
+ {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+
+}
+
+void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store)
+{
+ MEdge *medge;
+ EditMesh *em= me->edit_mesh;
+ void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */
+
+ /* editmode*/
+ EditEdge *eed;
+
+ int a, last;
+ int totvert, totedge;
+ int totUnique= -1, totUniqueOld= -1;
+
+ MirrTopoHash_t *MirrTopoHash = NULL;
+ MirrTopoHash_t *MirrTopoHash_Prev = NULL;
+ MirrTopoPair_t *MirrTopoPairs;
+
+ /* reallocate if needed */
+ ED_mesh_mirrtopo_free(mesh_topo_store);
+
+ mesh_topo_store->prev_ob_mode= ob_mode;
+
+ if(em) {
+ EditVert *eve;
+ totvert= 0;
+ eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" );
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ eve_tmp_back[totvert]= eve->tmp.p;
+ eve->tmp.l = totvert++;
+ }
+ }
+ else {
+ totvert = me->totvert;
+ }
+
+ MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" );
+
+ /* Initialize the vert-edge-user counts used to detect unique topology */
+ if(em) {
+ totedge= 0;
+
+ for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
+ MirrTopoHash[eed->v1->tmp.l]++;
+ MirrTopoHash[eed->v2->tmp.l]++;
+ }
+ } else {
+ totedge= me->totedge;
+
+ for(a=0, medge=me->medge; a < me->totedge; a++, medge++) {
+ MirrTopoHash[medge->v1]++;
+ MirrTopoHash[medge->v2]++;
+ }
+ }
+
+ MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash );
+
+ totUniqueOld = -1;
+ while(1) {
+ /* use the number of edges per vert to give verts unique topology IDs */
+
+ if(em) {
+ for(eed=em->edges.first; eed; eed= eed->next) {
+ MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l];
+ MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l];
+ }
+ } else {
+ for(a=0, medge=me->medge; a<me->totedge; a++, medge++) {
+ /* This can make really big numbers, wrapping around here is fine */
+ MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2];
+ MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1];
+ }
+ }
+ memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
+
+ /* sort so we can count unique values */
+ qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort);
+
+ totUnique = 1; /* account for skiping the first value */
+ for(a=1; a<totvert; a++) {
+ if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) {
+ totUnique++;
+ }
+ }
+
+ if (totUnique <= totUniqueOld) {
+ /* Finish searching for unique valus when 1 loop dosnt give a
+ * higher number of unique values compared to the previous loop */
+ break;
+ } else {
+ totUniqueOld = totUnique;
+ }
+ /* Copy the hash calculated this iter, so we can use them next time */
+ memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
+ }
+
+ /* restore eve->tmp.* */
+ if(eve_tmp_back) {
+ EditVert *eve;
+ totvert= 0;
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ eve->tmp.p= eve_tmp_back[totvert++];
+ }
+
+ MEM_freeN(eve_tmp_back);
+ eve_tmp_back= NULL;
+ }
+
+
+ /* Hash/Index pairs are needed for sorting to find index pairs */
+ MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs");
+
+ /* since we are looping through verts, initialize these values here too */
+ mesh_topo_store->index_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" );
+
+ if(em) {
+ EM_init_index_arrays(em,1,0,0);
+ }
+
+
+ for(a=0; a<totvert; a++) {
+ MirrTopoPairs[a].hash= MirrTopoHash[a];
+ MirrTopoPairs[a].v_index = a;
+
+ /* initialize lookup */
+ mesh_topo_store->index_lookup[a] = -1;
+ }
+
+ qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_sort);
+
+ /* Since the loop starts at 2, we must define the last index where the hash's differ */
+ last = ((totvert >= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1;
+
+ /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
+ * but you cant ever access the last 'a' index of MirrTopoPairs */
+ for(a=2; a <= totvert; a++) {
+ /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */
+ if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) {
+ if (a-last==2) {
+ if(em) {
+ mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].v_index);
+ mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].v_index);
+ } else {
+ mesh_topo_store->index_lookup[MirrTopoPairs[a-1].v_index] = MirrTopoPairs[a-2].v_index;
+ mesh_topo_store->index_lookup[MirrTopoPairs[a-2].v_index] = MirrTopoPairs[a-1].v_index;
+ }
+ }
+ last= a;
+ }
+ }
+ if(em) {
+ EM_free_index_arrays();
+ }
+
+ MEM_freeN( MirrTopoPairs );
+ MirrTopoPairs = NULL;
+
+ MEM_freeN( MirrTopoHash );
+ MEM_freeN( MirrTopoHash_Prev );
+
+ mesh_topo_store->prev_vert_tot = totvert;
+ mesh_topo_store->prev_edge_tot = totedge;
+}
+
+void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store)
+{
+ if (mesh_topo_store->index_lookup) {
+ MEM_freeN(mesh_topo_store->index_lookup);
+ }
+ mesh_topo_store->index_lookup = NULL;
+ mesh_topo_store->prev_vert_tot = -1;
+ mesh_topo_store->prev_edge_tot = -1;
+}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index dd82f055f14..77daf21affa 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -765,7 +765,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
if(mode=='u') { /* use table */
if(MeshOctree.table==NULL)
mesh_octree_table(ob, em, NULL, 's');
-
+
if(MeshOctree.table) {
Mesh *me= ob->data;
bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
@@ -848,34 +848,7 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode)
return 0;
}
-
-/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
-
-typedef int MirrTopoHash_t;
-
-typedef struct MirrTopoPair_t {
- MirrTopoHash_t hash;
- int vIndex;
-} MirrTopoPair_t;
-
-static int MirrTopo_long_sort(const void *l1, const void *l2)
-{
- if ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2 ) return 1;
- else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2 ) return -1;
- return 0;
-}
-
-static int MirrTopo_item_sort(const void *v1, const void *v2)
-{
- if (((MirrTopoPair_t *)v1)->hash > ((MirrTopoPair_t *)v2)->hash ) return 1;
- else if (((MirrTopoPair_t *)v1)->hash < ((MirrTopoPair_t *)v2)->hash ) return -1;
- return 0;
-}
-
-static intptr_t *mesh_topo_lookup = NULL;
-static int mesh_topo_lookup_vert_tot = -1;
-static int mesh_topo_lookup_edge_tot = -1;
-static int mesh_topo_lookup_mode = -1;
+MirrTopoStore_t mesh_topo_store= {NULL, -1. -1, -1};
/* mode is 's' start, or 'e' end, or 'u' use */
/* if end, ob can be NULL */
@@ -883,188 +856,15 @@ static int mesh_topo_lookup_mode = -1;
int mesh_mirrtopo_table(Object *ob, char mode)
{
if(mode=='u') { /* use table */
- Mesh *me= ob->data;
- if( (mesh_topo_lookup==NULL) ||
- (mesh_topo_lookup_mode != ob->mode) ||
- (me->edit_mesh && (me->edit_mesh->totvert != mesh_topo_lookup_vert_tot)) ||
- (me->edit_mesh && (me->edit_mesh->totedge != mesh_topo_lookup_edge_tot)) ||
- (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_vert_tot) ||
- (me->edit_mesh==NULL && me->totedge != mesh_topo_lookup_edge_tot)
- ) {
+ if (ED_mesh_mirrtopo_recalc_check(ob->data, ob->mode, &mesh_topo_store)) {
mesh_mirrtopo_table(ob, 's');
}
- } else if(mode=='s') { /* start table */
- Mesh *me= ob->data;
- MEdge *medge;
- EditMesh *em= me->edit_mesh;
- void **eve_tmp_back= NULL; /* some of the callers are using eve->tmp so restore after */
-
-
- /* editmode*/
- EditEdge *eed;
-
- int a, last;
- int totvert, totedge;
- int totUnique= -1, totUniqueOld= -1;
-
- MirrTopoHash_t *MirrTopoHash = NULL;
- MirrTopoHash_t *MirrTopoHash_Prev = NULL;
- MirrTopoPair_t *MirrTopoPairs;
- mesh_topo_lookup_mode= ob->mode;
-
- /* reallocate if needed */
- if (mesh_topo_lookup) {
- MEM_freeN(mesh_topo_lookup);
- mesh_topo_lookup = NULL;
- }
-
- if(em) {
- EditVert *eve;
- totvert= 0;
- eve_tmp_back= MEM_callocN( em->totvert * sizeof(void *), "TopoMirr" );
- for(eve= em->verts.first; eve; eve= eve->next) {
- eve_tmp_back[totvert]= eve->tmp.p;
- eve->tmp.l = totvert++;
- }
- }
- else {
- totvert = me->totvert;
- }
-
- MirrTopoHash = MEM_callocN( totvert * sizeof(MirrTopoHash_t), "TopoMirr" );
-
- /* Initialize the vert-edge-user counts used to detect unique topology */
- if(em) {
- totedge= 0;
-
- for(eed=em->edges.first; eed; eed= eed->next, totedge++) {
- MirrTopoHash[eed->v1->tmp.l]++;
- MirrTopoHash[eed->v2->tmp.l]++;
- }
- } else {
- totedge= me->totedge;
-
- for(a=0, medge=me->medge; a < me->totedge; a++, medge++) {
- MirrTopoHash[medge->v1]++;
- MirrTopoHash[medge->v2]++;
- }
- }
-
- MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash );
-
- totUniqueOld = -1;
- while(1) {
- /* use the number of edges per vert to give verts unique topology IDs */
-
- if(em) {
- for(eed=em->edges.first; eed; eed= eed->next) {
- MirrTopoHash[eed->v1->tmp.l] += MirrTopoHash_Prev[eed->v2->tmp.l];
- MirrTopoHash[eed->v2->tmp.l] += MirrTopoHash_Prev[eed->v1->tmp.l];
- }
- } else {
- for(a=0, medge=me->medge; a<me->totedge; a++, medge++) {
- /* This can make really big numbers, wrapping around here is fine */
- MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2];
- MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1];
- }
- }
- memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
-
- /* sort so we can count unique values */
- qsort(MirrTopoHash_Prev, totvert, sizeof(MirrTopoHash_t), MirrTopo_long_sort);
-
- totUnique = 1; /* account for skiping the first value */
- for(a=1; a<totvert; a++) {
- if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) {
- totUnique++;
- }
- }
-
- if (totUnique <= totUniqueOld) {
- /* Finish searching for unique valus when 1 loop dosnt give a
- * higher number of unique values compared to the previous loop */
- break;
- } else {
- totUniqueOld = totUnique;
- }
- /* Copy the hash calculated this iter, so we can use them next time */
- memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MirrTopoHash_t) * totvert);
- }
-
- /* restore eve->tmp.* */
- if(eve_tmp_back) {
- EditVert *eve;
- totvert= 0;
- for(eve= em->verts.first; eve; eve= eve->next) {
- eve->tmp.p= eve_tmp_back[totvert++];
- }
-
- MEM_freeN(eve_tmp_back);
- eve_tmp_back= NULL;
- }
-
-
- /* Hash/Index pairs are needed for sorting to find index pairs */
- MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair_t) * totvert, "MirrTopoPairs");
-
- /* since we are looping through verts, initialize these values here too */
- mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" );
-
- if(em) {
- EM_init_index_arrays(em,1,0,0);
- }
-
-
- for(a=0; a<totvert; a++) {
- MirrTopoPairs[a].hash= MirrTopoHash[a];
- MirrTopoPairs[a].vIndex = a;
-
- /* initialize lookup */
- mesh_topo_lookup[a] = -1;
- }
-
- qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair_t), MirrTopo_item_sort);
-
- /* Since the loop starts at 2, we must define the last index where the hash's differ */
- last = ((totvert >= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1;
-
- /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
- * but you cant ever access the last 'a' index of MirrTopoPairs */
- for(a=2; a < totvert+1; a++) {
- /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */
- if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) {
- if (a-last==2) {
- if(em) {
- mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex);
- mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (intptr_t)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex);
- } else {
- mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex;
- mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex;
- }
- }
- last= a;
- }
- }
- if(em) {
- EM_free_index_arrays();
- }
-
- MEM_freeN( MirrTopoPairs );
- MirrTopoPairs = NULL;
-
- MEM_freeN( MirrTopoHash );
- MEM_freeN( MirrTopoHash_Prev );
-
- mesh_topo_lookup_vert_tot = totvert;
- mesh_topo_lookup_edge_tot = totedge;
-
- } else if(mode=='e') { /* end table */
- if (mesh_topo_lookup) {
- MEM_freeN(mesh_topo_lookup);
- }
- mesh_topo_lookup = NULL;
- mesh_topo_lookup_vert_tot= -1;
- mesh_topo_lookup_edge_tot= -1;
+ }
+ else if(mode=='s') { /* start table */
+ ED_mesh_mirrtopo_init(ob->data, ob->mode, &mesh_topo_store);
+ }
+ else if(mode=='e') { /* end table */
+ ED_mesh_mirrtopo_free(&mesh_topo_store);
}
return 0;
}
@@ -1088,7 +888,7 @@ static int mesh_get_x_mirror_vert_topo(Object *ob, int index)
if (mesh_mirrtopo_table(ob, 'u')==-1)
return -1;
- return mesh_topo_lookup[index];
+ return mesh_topo_store.index_lookup[index];
}
int mesh_get_x_mirror_vert(Object *ob, int index)
@@ -1136,7 +936,7 @@ static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em
}
}
- poinval= mesh_topo_lookup[ index ];
+ poinval= mesh_topo_store.index_lookup[index];
if(poinval != -1)
return (EditVert *)(poinval);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 240fb8017f2..913e5893a77 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -452,7 +452,7 @@ static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, M
Key *key=me->key;
KeyBlock *kb;
- if(!modifier_sameTopology(md)) {
+ if(!modifier_sameTopology(md) || mti->type == eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes");
return 0;
}
@@ -500,7 +500,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
Mesh *me = ob->data;
MultiresModifierData *mmd= find_multires_modifier_before(scene, md);
- if( me->key) {
+ if(me->key && mti->type != eModifierTypeType_NonGeometrical) {
BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys");
return 0;
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 007a8f7e4d7..1c34df5393a 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -1293,6 +1293,7 @@ static void area_split_exit(bContext *C, wmOperator *op)
op->customdata = NULL;
}
+ WM_cursor_restore(CTX_wm_window(C));
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
/* this makes sure aligned edges will result in aligned grabbing */
@@ -1491,6 +1492,37 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
}
}
break;
+
+ case MIDDLEMOUSE:
+ case TABKEY:
+ if (sd->previewmode==0){
+ }
+ else{
+ dir = RNA_enum_get(op->ptr, "direction");
+
+ if(event->val==KM_PRESS){
+ if (sd->sarea){
+ sd->sarea->flag &= ~(AREA_FLAG_DRAWSPLIT_H|AREA_FLAG_DRAWSPLIT_V);
+ ED_area_tag_redraw(sd->sarea);
+
+ if (dir=='v'){
+ RNA_enum_set(op->ptr, "direction", 'h');
+ sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H;
+
+ WM_cursor_set(CTX_wm_window(C),CURSOR_X_MOVE);
+ }
+ else{
+ RNA_enum_set(op->ptr, "direction", 'v');
+ sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_V;
+
+ WM_cursor_set(CTX_wm_window(C),CURSOR_Y_MOVE);
+ }
+ }
+ }
+ }
+
+ break;
+
case RIGHTMOUSE: /* cancel operation */
case ESCKEY:
return area_split_cancel(C, op);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 2d0ad349be8..eb20465a2ab 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -605,9 +605,13 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size");
ed_keymap_paint_brush_radial_control(keymap, "weight_paint", 0);
- kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */
RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask");
+ /* note, conflicts with vertex paint, but this is more useful */
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", VKEY, KM_PRESS, 0, 0); /* vert mask toggle */
+ RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask_vertex");
+
WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 15e5719be37..1b5f2417384 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -115,6 +115,9 @@ static void active_node_panel(const bContext *C, Panel *pa)
uiItemS(layout);
uiItemR(layout, &ptr, "name", 0, NULL, ICON_NODE);
uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "NODE_OT_hide_socket_toggle");
+ uiItemS(layout);
/* draw this node's settings */
if (node->typeinfo && node->typeinfo->uifuncbut)
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 08e073494bb..7b692f55965 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -351,10 +351,10 @@ static void node_update_hidden(bNode *node)
/* calculate minimal radius */
for(nsock= node->inputs.first; nsock; nsock= nsock->next)
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE))
totin++;
for(nsock= node->outputs.first; nsock; nsock= nsock->next)
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE))
totout++;
tot= MAX2(totin, totout);
@@ -371,7 +371,7 @@ static void node_update_hidden(bNode *node)
rad=drad= (float)M_PI/(1.0f + (float)totout);
for(nsock= node->outputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) {
nsock->locx= node->totr.xmax - hiddenrad + (float)sin(rad)*hiddenrad;
nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad;
rad+= drad;
@@ -382,7 +382,7 @@ static void node_update_hidden(bNode *node)
rad=drad= - (float)M_PI/(1.0f + (float)totin);
for(nsock= node->inputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) {
nsock->locx= node->totr.xmin + hiddenrad + (float)sin(rad)*hiddenrad;
nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad;
rad+= drad;
@@ -854,12 +854,12 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
/* sockets */
for(sock= node->inputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE))
node_socket_circle_draw(snode->nodetree, sock, socket_size);
}
for(sock= node->outputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE))
node_socket_circle_draw(snode->nodetree, sock, socket_size);
}
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 16ee32d10a2..566659e0391 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -195,7 +195,6 @@ void TEXT_OT_new(wmOperatorType *ot)
ot->description= "Create a new text data block";
/* api callbacks */
- ot->invoke= WM_operator_confirm;
ot->exec= text_new_exec;
ot->poll= text_new_poll;
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 6dd362b827f..e0b1741b0d0 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -70,6 +70,25 @@
#include "view3d_intern.h" // own include
+/* user data structures for derived mesh callbacks */
+typedef struct drawMeshFaceSelect_userData {
+ Mesh *me;
+ EdgeHash *eh;
+} drawMeshFaceSelect_userData;
+
+typedef struct drawEMTFMapped_userData {
+ EditMesh *em;
+ short has_mcol;
+ short has_mtface;
+ MFace *mf;
+ MTFace *tf;
+} drawEMTFMapped_userData;
+
+typedef struct drawTFace_userData {
+ MFace *mf;
+ MTFace *tf;
+} drawTFace_userData;
+
/**************************** Face Select Mode *******************************/
/* Flags for marked edges */
@@ -121,7 +140,7 @@ static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
{
- struct { Mesh *me; EdgeHash *eh; } *data = userData;
+ drawMeshFaceSelect_userData *data = userData;
Mesh *me= data->me;
MEdge *med = &me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
@@ -138,7 +157,7 @@ static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
{
- struct { Mesh *me; EdgeHash *eh; } *data = userData;
+ drawMeshFaceSelect_userData *data = userData;
MEdge *med = &data->me->medge[index];
uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
@@ -159,7 +178,7 @@ static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
{
- struct { Mesh *me; EdgeHash *eh; } data;
+ drawMeshFaceSelect_userData data;
data.me = me;
data.eh = get_tface_mesh_marked_edge_info(me);
@@ -513,7 +532,7 @@ static int draw_tface_mapped__set_draw(void *userData, int index)
static int draw_em_tf_mapped__set_draw(void *userData, int index)
{
- struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
+ drawEMTFMapped_userData *data = userData;
EditMesh *em = data->em;
EditFace *efa= EM_get_face_for_index(index);
MTFace *tface;
@@ -631,7 +650,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
static int compareDrawOptions(void *userData, int cur_index, int next_index)
{
- struct { MFace *mf; MTFace *tf; } *data = userData;
+ drawTFace_userData *data = userData;
if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
return 0;
@@ -644,7 +663,7 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index)
static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
{
- struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
+ drawEMTFMapped_userData *data= userData;
if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
return 0;
@@ -669,7 +688,7 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
glColor4f(1.0f,1.0f,1.0f,1.0f);
if(ob->mode & OB_MODE_EDIT) {
- struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
+ drawEMTFMapped_userData data;
data.em= me->edit_mesh;
data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
@@ -693,7 +712,7 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
}
else {
- struct { MFace *mf; MTFace *tf; } userData;
+ drawTFace_userData userData;
if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
add_tface_color_layer(dm);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index e3e551d67ee..7827569bd30 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -118,6 +118,48 @@ typedef enum eWireDrawMode {
OBDRAW_WIRE_ON_DEPTH= 2
} eWireDrawMode;
+/* user data structures for derived mesh callbacks */
+typedef struct foreachScreenVert_userData {
+ void (*func)(void *userData, EditVert *eve, int x, int y, int index);
+ void *userData;
+ ViewContext vc;
+ eV3DClipTest clipVerts;
+} foreachScreenVert_userData;
+
+typedef struct foreachScreenEdge_userData {
+ void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
+ void *userData;
+ ViewContext vc;
+ eV3DClipTest clipVerts;
+} foreachScreenEdge_userData;
+
+typedef struct foreachScreenFace_userData {
+ void (*func)(void *userData, EditFace *efa, int x, int y, int index);
+ void *userData;
+ ViewContext vc;
+} foreachScreenFace_userData;
+
+typedef struct drawDMVerts_userData {
+ int sel;
+ EditVert *eve_act;
+} drawDMVerts_userData;
+
+typedef struct drawDMEdgesSel_userData {
+ unsigned char *baseCol, *selCol, *actCol;
+ EditEdge *eed_act;
+} drawDMEdgesSel_userData;
+
+typedef struct drawDMFacesSel_userData {
+ unsigned char *cols[3];
+ EditFace *efa_act;
+ int *orig_index;
+} drawDMFacesSel_userData;
+
+typedef struct bbsObmodeMeshVerts_userData {
+ void *offset;
+ MVert *mvert;
+} bbsObmodeMeshVerts_userData;
+
static void draw_bounding_volume(Scene *scene, Object *ob, char type);
static void drawcube_size(float size);
@@ -1944,9 +1986,7 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
* use the object matrix in the useual way */
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index);
- void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData;
-
+ foreachScreenVert_userData *data = userData;
EditVert *eve = EM_get_vert_for_index(index);
if (eve->h==0) {
@@ -1968,9 +2008,7 @@ void mesh_foreachScreenVert(
void (*func)(void *userData, EditVert *eve, int x, int y, int index),
void *userData, eV3DClipTest clipVerts)
{
- struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index);
- void *userData; ViewContext vc; eV3DClipTest clipVerts; } data;
-
+ foreachScreenVert_userData data;
DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
data.vc= *vc;
@@ -2024,8 +2062,7 @@ static int is_co_in_region(ARegion *ar, const short co[2])
}
static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
- void *userData; ViewContext vc; eV3DClipTest clipVerts; } *data = userData;
+ foreachScreenEdge_userData *data = userData;
EditEdge *eed = EM_get_edge_for_index(index);
short s[2][2];
@@ -2056,8 +2093,7 @@ void mesh_foreachScreenEdge(
void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index),
void *userData, eV3DClipTest clipVerts)
{
- struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index);
- void *userData; ViewContext vc; eV3DClipTest clipVerts; } data;
+ foreachScreenEdge_userData data;
DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
data.vc= *vc;
@@ -2077,7 +2113,7 @@ void mesh_foreachScreenEdge(
static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *UNUSED(no))
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } *data = userData;
+ foreachScreenFace_userData *data = userData;
EditFace *efa = EM_get_face_for_index(index);
short s[2];
@@ -2095,7 +2131,7 @@ void mesh_foreachScreenFace(
void (*func)(void *userData, EditFace *efa, int x, int y, int index),
void *userData)
{
- struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ViewContext vc; } data;
+ foreachScreenFace_userData data;
DerivedMesh *dm = editmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
data.vc= *vc;
@@ -2240,7 +2276,7 @@ static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm)
/* Draw verts with color set based on selection */
static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
{
- struct { int sel; EditVert *eve_act; } * data = userData;
+ drawDMVerts_userData * data = userData;
EditVert *eve = EM_get_vert_for_index(index);
if (eve->h==0 && (eve->f&SELECT)==data->sel) {
@@ -2267,7 +2303,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
{
- struct { int sel; EditVert *eve_act; } data;
+ drawDMVerts_userData data;
data.sel = sel;
data.eve_act = eve_act;
@@ -2281,7 +2317,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
{
EditEdge *eed = EM_get_edge_for_index(index);
//unsigned char **cols = userData, *col;
- struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } * data = userData;
+ drawDMEdgesSel_userData * data = userData;
unsigned char *col;
if (eed->h==0) {
@@ -2305,7 +2341,7 @@ static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
}
static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditEdge *eed_act)
{
- struct { unsigned char *baseCol, *selCol, *actCol; EditEdge *eed_act; } data;
+ drawDMEdgesSel_userData data;
data.baseCol = baseCol;
data.selCol = selCol;
@@ -2379,7 +2415,7 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
* return 2 for the active face so it renders with stipple enabled */
static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
{
- struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } * data = userData;
+ drawDMFacesSel_userData * data = userData;
EditFace *efa = EM_get_face_for_index(index);
unsigned char *col;
@@ -2399,7 +2435,7 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU
static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
{
- struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } *data = userData;
+ drawDMFacesSel_userData *data = userData;
EditFace *efa;
EditFace *next_efa;
unsigned char *col, *next_col;
@@ -2428,7 +2464,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
/* also draws the active face */
static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act)
{
- struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } data;
+ drawDMFacesSel_userData data;
data.cols[0] = baseCol;
data.cols[1] = selCol;
data.cols[2] = actCol;
@@ -6879,7 +6915,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
{
- struct {void* offset; MVert *mvert;} *data = userData;
+ bbsObmodeMeshVerts_userData *data = userData;
MVert *mv = &data->mvert[index];
int offset = (intptr_t) data->offset;
@@ -6891,7 +6927,7 @@ static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co,
static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
{
- struct {void* offset; struct MVert *mvert;} data;
+ bbsObmodeMeshVerts_userData data;
Mesh *me = ob->data;
MVert *mvert = me->mvert;
data.mvert = mvert;
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 1b849754db8..345e78d70c9 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -576,7 +576,7 @@ typedef struct GameData {
short mode, matmode;
short occlusionRes; /* resolution of occlusion Z buffer in pixel */
short physicsEngine;
- short pad[2];
+ short exitkey, pad;
short ticrate, maxlogicstep, physubstep, maxphystep;
short obstacleSimulation, pad1;
float levelHeight;
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 1e8a4574120..149393b6723 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -181,6 +181,7 @@ typedef struct World {
#define TEXCO_ANGMAP 64
#define TEXCO_H_SPHEREMAP 256
#define TEXCO_H_TUBEMAP 1024
+#define TEXCO_EQUIRECTMAP 2048
/* mapto */
#define WOMAP_BLEND 1
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index a682c329444..9638bba3e80 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1213,6 +1213,13 @@ static void rna_GameSettings_auto_start_set(PointerRNA *UNUSED(ptr), int value)
G.fileflags &= ~G_FILE_AUTOPLAY;
}
+static void rna_GameSettings_exit_key_set(PointerRNA *ptr, int value)
+{
+ GameData *gm = (GameData*)ptr->data;
+
+ if(ISKEYBOARD(value))
+ gm->exitkey=value;
+}
static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[])
{
@@ -2103,6 +2110,13 @@ static void rna_def_scene_game_data(BlenderRNA *brna)
RNA_def_property_range(prop, 8, 32);
RNA_def_property_ui_text(prop, "Bits", "Display bit depth of full screen display");
RNA_def_property_update(prop, NC_SCENE, NULL);
+
+ prop= RNA_def_property(srna, "exit_key", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "exitkey");
+ RNA_def_property_enum_items(prop, event_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_GameSettings_exit_key_set", NULL);
+ RNA_def_property_ui_text(prop, "Exit Key", "Sets the key that exits the Game Engine");
+ RNA_def_property_update(prop, NC_SCENE, NULL);
// Do we need it here ? (since we already have it in World
prop= RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 840498249ea..087716adbe3 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -143,6 +143,7 @@ static void rna_def_world_mtex(BlenderRNA *brna)
{TEXCO_GLOB, "GLOBAL", 0, "Global", "Use global coordinates for the texture coordinates (interior mist)"},
{TEXCO_ANGMAP, "ANGMAP", 0, "AngMap", "Use 360 degree angular coordinates, e.g. for spherical light probes"},
{TEXCO_H_SPHEREMAP, "SPHERE", 0, "Sphere", "For 360 degree panorama sky, spherical mapped, only top half"},
+ {TEXCO_EQUIRECTMAP, "EQUIRECT", 0, "Equirectangular", "For 360 degree panorama sky, equirectangular mapping"},
{TEXCO_H_TUBEMAP, "TUBE", 0, "Tube", "For 360 degree panorama sky, cylindrical mapped, only top half"},
{TEXCO_OBJECT, "OBJECT", 0, "Object", "Use linked object's coordinates for texture coordinates"},
{0, NULL, 0, NULL, NULL}};
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 3146d1c9d5d..38c2073b6a5 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -290,7 +290,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci);
project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci);
project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci);
- if(mf->v3)
+ if(mf->v4)
project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci);
}
else {
@@ -343,7 +343,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci);
project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci);
project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci);
- if(mf->v3)
+ if(mf->v4)
project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci);
}
else {
@@ -407,7 +407,7 @@ ModifierTypeInfo modifierType_UVProject = {
/* name */ "UVProject",
/* structName */ "UVProjectModifierData",
/* structSize */ sizeof(UVProjectModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
+ /* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 24d80fe847c..bdd7ab7486b 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -177,10 +177,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
- DerivedMesh *dm = derivedData, *ret = NULL;
-#if 0
- Mesh *ob_m = NULL;
-#endif
+ DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw = NULL;
float *org_w; /* Array original weights. */
@@ -188,7 +185,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int numVerts;
int defgrp_idx;
int i;
- char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
/* Flags. */
int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
@@ -207,49 +203,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (defgrp_idx < 0)
return dm;
- /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
- * time! See scene 5 of the WeighVG test file...
- */
-#if 0
- /* Get actual dverts (ie vertex group data). */
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- /* If no dverts, return unmodified data... */
- if (dvert == NULL)
- return dm;
-
- /* Get org mesh, only to test whether affected cdata layer has already been copied
- * somewhere up in the modifiers stack.
- */
- ob_m = get_mesh(ob);
- if (ob_m == NULL)
- return dm;
-
- /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
- if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
- /* XXX Seems to create problems with weightpaint mode???
- * I'm missing something here, I guess...
- */
-// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
- ret = CDDM_copy(dm);
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- ret->release(ret);
- return dm;
- }
- rel_ret = 1;
- }
- else
- ret = dm;
-#else
- ret = CDDM_copy(dm);
- rel_ret = 1;
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- if (rel_ret)
- ret->release(ret);
- return dm;
- }
-#endif
+ dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w");
@@ -271,7 +225,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
}
/* Do masking. */
- weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, ret, wmd->mask_constant,
+ weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -285,7 +239,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(dw);
/* Return the vgroup-modified mesh. */
- return ret;
+ return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
@@ -300,7 +254,7 @@ ModifierTypeInfo modifierType_WeightVGEdit = {
/* name */ "VertexWeightEdit",
/* structName */ "WeightVGEditModifierData",
/* structSize */ sizeof(WeightVGEditModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
+ /* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh
/* |eModifierTypeFlag_SupportsMapping*/
|eModifierTypeFlag_SupportsEditmode,
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 221deeef1a6..17316d891da 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -219,10 +219,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData*) md;
- DerivedMesh *dm = derivedData, *ret = NULL;
-#if 0
- Mesh *ob_m = NULL;
-#endif
+ DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
int numVerts;
@@ -232,7 +229,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int *tidx, *indices = NULL;
int numIdx = 0;
int i;
- char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
/* Get number of verts. */
numVerts = dm->getNumVerts(dm);
@@ -254,49 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
return dm;
}
- /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
- * time! See scene 5 of the WeighVG test file...
- */
-#if 0
- /* Get actual dverts (ie vertex group data). */
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- /* If no dverts, return unmodified data... */
- if (dvert == NULL)
- return dm;
-
- /* Get org mesh, only to test whether affected cdata layer has already been copied
- * somewhere up in the modifiers stack.
- */
- ob_m = get_mesh(ob);
- if (ob_m == NULL)
- return dm;
-
- /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
- if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
- /* XXX Seems to create problems with weightpaint mode???
- * I'm missing something here, I guess...
- */
-// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
- ret = CDDM_copy(dm);
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- ret->release(ret);
- return dm;
- }
- rel_ret = 1;
- }
- else
- ret = dm;
-#else
- ret = CDDM_copy(dm);
- rel_ret = 1;
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- if (rel_ret)
- ret->release(ret);
- return dm;
- }
-#endif
+ dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Find out which vertices to work on. */
tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGMix Modifier, tidx");
@@ -364,8 +318,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(tdw1);
MEM_freeN(tdw2);
MEM_freeN(tidx);
- if (rel_ret)
- ret->release(ret);
return dm;
}
if (numIdx != -1) {
@@ -400,7 +352,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
}
/* Do masking. */
- weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
+ weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -419,7 +371,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(indices);
/* Return the vgroup-modified mesh. */
- return ret;
+ return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
@@ -434,7 +386,7 @@ ModifierTypeInfo modifierType_WeightVGMix = {
/* name */ "VertexWeightMix",
/* structName */ "WeightVGMixModifierData",
/* structSize */ sizeof(WeightVGMixModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
+ /* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh
/* |eModifierTypeFlag_SupportsMapping*/
|eModifierTypeFlag_SupportsEditmode,
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index af180b8a688..f67fd907d02 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -28,11 +28,17 @@
* \ingroup modifiers
*/
+#define DO_PROFILE 0
+
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#if DO_PROFILE
+ #include "PIL_time.h"
+#endif
+
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -334,10 +340,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData*) md;
- DerivedMesh *dm = derivedData, *ret = NULL;
-#if 0
- Mesh *ob_m = NULL;
-#endif
+ DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw, **tdw;
int numVerts;
@@ -350,7 +353,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int *tidx, *indices = NULL;
int numIdx = 0;
int i;
- char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
+
+#if DO_PROFILE
+ TIMEIT_START(perf)
+#endif
/* Get number of verts. */
numVerts = dm->getNumVerts(dm);
@@ -371,49 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (defgrp_idx < 0)
return dm;
- /* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
- * time! See scene 5 of the WeighVG test file...
- */
-#if 0
- /* Get actual dverts (ie vertex group data). */
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- /* If no dverts, return unmodified data... */
- if (dvert == NULL)
- return dm;
-
- /* Get org mesh, only to test whether affected cdata layer has already been copied
- * somewhere up in the modifiers stack.
- */
- ob_m = get_mesh(ob);
- if (ob_m == NULL)
- return dm;
-
- /* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
- if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
- /* XXX Seems to create problems with weightpaint mode???
- * I'm missing something here, I guess...
- */
-// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
- ret = CDDM_copy(dm);
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- ret->release(ret);
- return dm;
- }
- rel_ret = 1;
- }
- else
- ret = dm;
-#else
- ret = CDDM_copy(dm);
- rel_ret = 1;
- dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
- if (dvert == NULL) {
- if (rel_ret)
- ret->release(ret);
- return dm;
- }
-#endif
+ dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight.
*/
@@ -433,8 +397,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(tidx);
MEM_freeN(tw);
MEM_freeN(tdw);
- if (rel_ret)
- ret->release(ret);
return dm;
}
indices = MEM_mallocN(sizeof(int) * numIdx, "WeightVGProximity Modifier, indices");
@@ -455,7 +417,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
*/
float (*tv_cos)[3] = MEM_mallocN(sizeof(float[3]) * numVerts, "WeightVGProximity Modifier, tv_cos");
v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos");
- ret->getVertCos(ret, tv_cos);
+ dm->getVertCos(dm, tv_cos);
for (i = 0; i < numIdx; i++)
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
MEM_freeN(tv_cos);
@@ -524,7 +486,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
/* Do masking. */
- weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
+ weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -538,8 +500,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(indices);
MEM_freeN(v_cos);
+#if DO_PROFILE
+ TIMEIT_END(perf)
+#endif
+
/* Return the vgroup-modified mesh. */
- return ret;
+ return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
@@ -554,7 +520,7 @@ ModifierTypeInfo modifierType_WeightVGProximity = {
/* name */ "VertexWeightProximity",
/* structName */ "WeightVGProximityModifierData",
/* structSize */ sizeof(WeightVGProximityModifierData),
- /* type */ eModifierTypeType_Nonconstructive,
+ /* type */ eModifierTypeType_NonGeometrical,
/* flags */ eModifierTypeFlag_AcceptsMesh
/* |eModifierTypeFlag_SupportsMapping*/
|eModifierTypeFlag_SupportsEditmode,
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 87585c35e6a..8b8afc3d846 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -134,8 +134,6 @@ void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mo
bNodeSocket *sock;
int a;
- ntreeSocketUseFlags(ntree);
-
for(node= ntree->nodes.first; node; node= node->next) {
if(node->type==SH_NODE_TEXTURE) {
if((r_mode & R_OSA) && node->id) {
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 69a5fb39b67..ded0f2f768c 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -642,7 +642,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
if (len==16) {
if (is_thick) {
ret= Matrix_CreatePyObject(NULL, 4, 4, Py_NEW, NULL);
- RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr);
+ RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 4,4, mathutils_rna_matrix_cb_index, FALSE);
@@ -653,7 +653,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
else if (len==9) {
if (is_thick) {
ret= Matrix_CreatePyObject(NULL, 3, 3, Py_NEW, NULL);
- RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->contigPtr);
+ RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix);
}
else {
PyObject *mat_cb= Matrix_CreatePyObject_cb(ret, 3,3, mathutils_rna_matrix_cb_index, FALSE);
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 5587028d812..1dfd7c574dd 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
PyDoc_STRVAR(M_Mathutils_doc,
"This module provides access to matrices, eulers, quaternions and vectors."
@@ -211,7 +212,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- else if (((MatrixObject *)value)->col_size < 3 || ((MatrixObject *)value)->row_size < 3) {
+ else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
PyErr_Format(PyExc_ValueError,
"%.200s: matrix must have minimum 3x3 dimensions",
error_prefix);
@@ -267,6 +268,18 @@ int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps)
return 1;
}
+/* dynstr as python string utility funcions, frees 'ds'! */
+PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
+{
+ const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */
+ char *ds_buf = PyMem_Malloc(ds_len + 1);
+ PyObject *ret;
+ BLI_dynstr_get_cstring_ex(ds, ds_buf);
+ BLI_dynstr_free(ds);
+ ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);
+ PyMem_Free(ds_buf);
+ return ret;
+}
/* Mathutils Callbacks */
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index cd3548b9b82..2454e953949 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -37,6 +37,8 @@
/* Can cast different mathutils types to this, use for generic funcs */
+struct DynStr;
+
extern char BaseMathObject_Wrapped_doc[];
extern char BaseMathObject_Owner_doc[];
@@ -120,4 +122,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
+/* dynstr as python string utility funcions */
+PyObject *mathutils_dynstr_to_py(struct DynStr *ds);
+
#endif /* MATHUTILS_H */
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index e46dda7560f..e0a0deb9a0e 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -32,6 +32,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
#define COLOR_SIZE 3
@@ -125,6 +126,21 @@ static PyObject *Color_repr(ColorObject * self)
return ret;
}
+static PyObject *Color_str(ColorObject * self)
+{
+ DynStr *ds;
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ds= BLI_dynstr_new();
+
+ BLI_dynstr_appendf(ds, "<Color (r=%.4f, g=%.4f, b=%.4f)>",
+ self->col[0], self->col[1], self->col[2]);
+
+ return mathutils_dynstr_to_py(ds); /* frees ds */
+}
+
//------------------------tp_richcmpr
//returns -1 execption, 0 false, 1 true
static PyObject* Color_richcmpr(PyObject *a, PyObject *b, int op)
@@ -789,7 +805,7 @@ PyTypeObject color_Type = {
&Color_AsMapping, //tp_as_mapping
NULL, //tp_hash
NULL, //tp_call
- NULL, //tp_str
+ (reprfunc) Color_str, //tp_str
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index f44c0b82a2d..443e77c3798 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -36,6 +36,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
#define EULER_SIZE 3
@@ -317,6 +318,21 @@ static PyObject *Euler_repr(EulerObject * self)
return ret;
}
+static PyObject *Euler_str(EulerObject * self)
+{
+ DynStr *ds;
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ds= BLI_dynstr_new();
+
+ BLI_dynstr_appendf(ds, "<Euler (x=%.4f, y=%.4f, z=%.4f), order='%s'>",
+ self->eul[0], self->eul[1], self->eul[2], euler_order_str(self));
+
+ return mathutils_dynstr_to_py(ds); /* frees ds */
+}
+
static PyObject* Euler_richcmpr(PyObject *a, PyObject *b, int op)
{
PyObject *res;
@@ -635,7 +651,7 @@ PyTypeObject euler_Type = {
&Euler_AsMapping, //tp_as_mapping
NULL, //tp_hash
NULL, //tp_call
- NULL, //tp_str
+ (reprfunc) Euler_str, //tp_str
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 44799bb7943..59aad37f746 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -35,6 +35,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_dynstr.h"
static PyObject *Matrix_copy(MatrixObject *self);
static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *value);
@@ -49,56 +51,56 @@ static int mathutils_matrix_vector_check(BaseMathObject *bmo)
return BaseMath_ReadCallback(self);
}
-static int mathutils_matrix_vector_get(BaseMathObject *bmo, int subtype)
+static int mathutils_matrix_vector_get(BaseMathObject *bmo, int col)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
- int index;
+ int row;
if (BaseMath_ReadCallback(self) == -1)
return -1;
- for (index=0; index < self->col_size; index++) {
- bmo->data[index] = MATRIX_ITEM(self, subtype, index);
+ for (row=0; row < self->num_row; row++) {
+ bmo->data[row] = MATRIX_ITEM(self, row, col);
}
return 0;
}
-static int mathutils_matrix_vector_set(BaseMathObject *bmo, int subtype)
+static int mathutils_matrix_vector_set(BaseMathObject *bmo, int col)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
- int index;
+ int row;
if (BaseMath_ReadCallback(self) == -1)
return -1;
- for (index=0; index < self->col_size; index++) {
- MATRIX_ITEM(self, subtype, index) = bmo->data[index];
+ for (row=0; row < self->num_row; row++) {
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
}
(void)BaseMath_WriteCallback(self);
return 0;
}
-static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int subtype, int index)
+static int mathutils_matrix_vector_get_index(BaseMathObject *bmo, int col, int row)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
if (BaseMath_ReadCallback(self) == -1)
return -1;
- bmo->data[index]= MATRIX_ITEM(self, subtype, index);
+ bmo->data[row]= MATRIX_ITEM(self, row, col);
return 0;
}
-static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int subtype, int index)
+static int mathutils_matrix_vector_set_index(BaseMathObject *bmo, int col, int row)
{
MatrixObject *self= (MatrixObject *)bmo->cb_user;
if (BaseMath_ReadCallback(self) == -1)
return -1;
- MATRIX_ITEM(self, subtype, index) = bmo->data[index];
+ MATRIX_ITEM(self, row, col) = bmo->data[row];
(void)BaseMath_WriteCallback(self);
return 0;
@@ -133,16 +135,16 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *arg= PyTuple_GET_ITEM(args, 0);
/* -1 is an error, size checks will accunt for this */
- const unsigned short row_size= PySequence_Size(arg);
+ const unsigned short num_col= PySequence_Size(arg);
- if (row_size >= 2 && row_size <= 4) {
+ if (num_col >= 2 && num_col <= 4) {
PyObject *item= PySequence_GetItem(arg, 0);
- const unsigned short col_size= PySequence_Size(item);
+ const unsigned short num_row= PySequence_Size(item);
Py_XDECREF(item);
- if (col_size >= 2 && col_size <= 4) {
+ if (num_row >= 2 && num_row <= 4) {
/* sane row & col size, new matrix and assign as slice */
- PyObject *matrix= Matrix_CreatePyObject(NULL, row_size, col_size, Py_NEW, type);
+ PyObject *matrix= Matrix_CreatePyObject(NULL, num_col, num_row, Py_NEW, type);
if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
return matrix;
}
@@ -622,25 +624,25 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
void matrix_as_3x3(float mat[3][3], MatrixObject *self)
{
- copy_v3_v3(mat[0], MATRIX_ROW_PTR(self, 0));
- copy_v3_v3(mat[1], MATRIX_ROW_PTR(self, 1));
- copy_v3_v3(mat[2], MATRIX_ROW_PTR(self, 2));
+ copy_v3_v3(mat[0], MATRIX_COL_PTR(self, 0));
+ copy_v3_v3(mat[1], MATRIX_COL_PTR(self, 1));
+ copy_v3_v3(mat[2], MATRIX_COL_PTR(self, 2));
}
/* assumes rowsize == colsize is checked and the read callback has run */
static float matrix_determinant_internal(MatrixObject *self)
{
- if (self->row_size == 2) {
+ if (self->num_col == 2) {
return determinant_m2(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1),
MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1));
}
- else if (self->row_size == 3) {
+ else if (self->num_col == 3) {
return determinant_m3(MATRIX_ITEM(self, 0, 0), MATRIX_ITEM(self, 0, 1), MATRIX_ITEM(self, 0, 2),
MATRIX_ITEM(self, 1, 0), MATRIX_ITEM(self, 1, 1), MATRIX_ITEM(self, 1, 2),
MATRIX_ITEM(self, 2, 0), MATRIX_ITEM(self, 2, 1), MATRIX_ITEM(self, 2, 2));
}
else {
- return determinant_m4((float (*)[4])self->contigPtr);
+ return determinant_m4((float (*)[4])self->matrix);
}
}
@@ -662,17 +664,17 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if ((self->col_size < 3) || (self->row_size < 3) || (self->col_size != self->row_size)) {
+ if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) {
PyErr_SetString(PyExc_ValueError,
"Matrix.to_quat(): "
"inappropriate matrix size - expects 3x3 or 4x4 matrix");
return NULL;
}
- if (self->col_size == 3) {
- mat3_to_quat(quat, (float (*)[3])self->contigPtr);
+ if (self->num_row == 3) {
+ mat3_to_quat(quat, (float (*)[3])self->matrix);
}
else {
- mat4_to_quat(quat, (float (*)[4])self->contigPtr);
+ mat4_to_quat(quat, (float (*)[4])self->matrix);
}
return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
@@ -719,11 +721,11 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
}
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->col_size ==3 && self->row_size ==3) {
- mat= (float (*)[3])self->contigPtr;
+ if (self->num_row ==3 && self->num_col ==3) {
+ mat= (float (*)[3])self->matrix;
}
- else if (self->col_size ==4 && self->row_size ==4) {
- copy_m3_m4(tmat, (float (*)[4])self->contigPtr);
+ else if (self->num_row ==4 && self->num_col ==4) {
+ copy_m3_m4(tmat, (float (*)[4])self->matrix);
mat= tmat;
}
else {
@@ -774,8 +776,8 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
return NULL;
}
- self->contigPtr = PyMem_Realloc(self->contigPtr, (sizeof(float) * 16));
- if (self->contigPtr == NULL) {
+ self->matrix = PyMem_Realloc(self->matrix, (sizeof(float) * 16));
+ if (self->matrix == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Matrix.resize_4x4(): "
"problem allocating pointer space");
@@ -783,31 +785,31 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
}
/*move data to new spot in array + clean*/
- for (blank_rows = (4 - self->row_size); blank_rows > 0; blank_rows--) {
+ for (blank_rows = (4 - self->num_col); blank_rows > 0; blank_rows--) {
for (x = 0; x < 4; x++) {
- index = (4 * (self->row_size + (blank_rows - 1))) + x;
+ index = (4 * (self->num_col + (blank_rows - 1))) + x;
if (index == 10 || index == 15) {
- self->contigPtr[index] = 1.0f;
+ self->matrix[index] = 1.0f;
}
else {
- self->contigPtr[index] = 0.0f;
+ self->matrix[index] = 0.0f;
}
}
}
- for (x = 1; x <= self->row_size; x++) {
- first_row_elem = (self->col_size * (self->row_size - x));
- curr_pos = (first_row_elem + (self->col_size -1));
- new_pos = (4 * (self->row_size - x)) + (curr_pos - first_row_elem);
- for (blank_columns = (4 - self->col_size); blank_columns > 0; blank_columns--) {
- self->contigPtr[new_pos + blank_columns] = 0.0f;
+ for (x = 1; x <= self->num_col; x++) {
+ first_row_elem = (self->num_row * (self->num_col - x));
+ curr_pos = (first_row_elem + (self->num_row -1));
+ new_pos = (4 * (self->num_col - x)) + (curr_pos - first_row_elem);
+ for (blank_columns = (4 - self->num_row); blank_columns > 0; blank_columns--) {
+ self->matrix[new_pos + blank_columns] = 0.0f;
}
for ( ; curr_pos >= first_row_elem; curr_pos--) {
- self->contigPtr[new_pos] = self->contigPtr[curr_pos];
+ self->matrix[new_pos] = self->matrix[curr_pos];
new_pos--;
}
}
- self->row_size = 4;
- self->col_size = 4;
+ self->num_col = 4;
+ self->num_row = 4;
Py_RETURN_NONE;
}
@@ -825,12 +827,12 @@ static PyObject *Matrix_to_4x4(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->col_size==4 && self->row_size==4) {
- return Matrix_CreatePyObject(self->contigPtr, 4, 4, Py_NEW, Py_TYPE(self));
+ if (self->num_row==4 && self->num_col==4) {
+ return Matrix_CreatePyObject(self->matrix, 4, 4, Py_NEW, Py_TYPE(self));
}
- else if (self->col_size==3 && self->row_size==3) {
+ else if (self->num_row==3 && self->num_col==3) {
float mat[4][4];
- copy_m4_m3(mat, (float (*)[3])self->contigPtr);
+ copy_m4_m3(mat, (float (*)[3])self->matrix);
return Matrix_CreatePyObject((float *)mat, 4, 4, Py_NEW, Py_TYPE(self));
}
/* TODO, 2x2 matrix */
@@ -856,7 +858,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if ((self->col_size < 3) || (self->row_size < 3)) {
+ if ((self->num_row < 3) || (self->num_col < 3)) {
PyErr_SetString(PyExc_TypeError,
"Matrix.to_3x3(): inappropriate matrix size");
return NULL;
@@ -880,14 +882,14 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if ((self->col_size < 3) || self->row_size < 4) {
+ if ((self->num_row < 3) || self->num_col < 4) {
PyErr_SetString(PyExc_TypeError,
"Matrix.to_translation(): "
"inappropriate matrix size");
return NULL;
}
- return Vector_CreatePyObject(MATRIX_ROW_PTR(self, 3), 3, Py_NEW, NULL);
+ return Vector_CreatePyObject(MATRIX_COL_PTR(self, 3), 3, Py_NEW, NULL);
}
PyDoc_STRVAR(Matrix_to_scale_doc,
@@ -910,7 +912,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if ((self->col_size < 3) || (self->row_size < 3)) {
+ if ((self->num_row < 3) || (self->num_col < 3)) {
PyErr_SetString(PyExc_TypeError,
"Matrix.to_scale(): "
"inappropriate matrix size, 3x3 minimum size");
@@ -948,7 +950,7 @@ static PyObject *Matrix_invert(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->row_size != self->col_size) {
+ if (self->num_col != self->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix.invert(ed): "
"only square matrices are supported");
@@ -960,26 +962,26 @@ static PyObject *Matrix_invert(MatrixObject *self)
if (det != 0) {
/*calculate the classical adjoint*/
- if (self->row_size == 2) {
+ if (self->num_col == 2) {
mat[0] = MATRIX_ITEM(self, 1, 1);
mat[1] = -MATRIX_ITEM(self, 0, 1);
mat[2] = -MATRIX_ITEM(self, 1, 0);
mat[3] = MATRIX_ITEM(self, 0, 0);
}
- else if (self->row_size == 3) {
- adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->contigPtr);
+ else if (self->num_col == 3) {
+ adjoint_m3_m3((float (*)[3]) mat,(float (*)[3])self->matrix);
}
- else if (self->row_size == 4) {
- adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->contigPtr);
+ else if (self->num_col == 4) {
+ adjoint_m4_m4((float (*)[4]) mat, (float (*)[4])self->matrix);
}
/*divide by determinate*/
- for (x = 0; x < (self->row_size * self->col_size); x++) {
+ for (x = 0; x < (self->num_col * self->num_row); x++) {
mat[x] /= det;
}
/*set values*/
- for (x = 0; x < self->row_size; x++) {
- for (y = 0; y < self->col_size; y++) {
- MATRIX_ITEM(self, x, y) = mat[z];
+ for (x = 0; x < self->num_col; x++) {
+ for (y = 0; y < self->num_row; y++) {
+ MATRIX_ITEM(self, y, x) = mat[z];
z++;
}
}
@@ -1032,7 +1034,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
if (mathutils_any_to_rotmat(other_rmat, value, "matrix.rotate(value)") == -1)
return NULL;
- if (self->col_size != 3 || self->row_size != 3) {
+ if (self->num_row != 3 || self->num_col != 3) {
PyErr_SetString(PyExc_TypeError,
"Matrix.rotate(): "
"must have 3x3 dimensions");
@@ -1042,7 +1044,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
matrix_as_3x3(self_rmat, self);
mul_m3_m3m3(rmat, other_rmat, self_rmat);
- copy_m3_m3((float (*)[3])(self->contigPtr), rmat);
+ copy_m3_m3((float (*)[3])(self->matrix), rmat);
(void)BaseMath_WriteCallback(self);
Py_RETURN_NONE;
@@ -1065,7 +1067,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
float quat[4];
float size[3];
- if (self->col_size != 4 || self->row_size != 4) {
+ if (self->num_row != 4 || self->num_col != 4) {
PyErr_SetString(PyExc_TypeError,
"Matrix.decompose(): "
"inappropriate matrix size - expects 4x4 matrix");
@@ -1075,7 +1077,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr);
+ mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->matrix);
mat3_to_quat(quat, rot);
ret= PyTuple_New(3);
@@ -1108,7 +1110,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac))
return NULL;
- if (self->row_size != mat2->row_size || self->col_size != mat2->col_size) {
+ if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) {
PyErr_SetString(PyExc_ValueError,
"Matrix.lerp(): "
"expects both matrix objects of the same dimensions");
@@ -1119,11 +1121,11 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
/* TODO, different sized matrix */
- if (self->row_size==4 && self->col_size==4) {
- blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->contigPtr, (float (*)[4])mat2->contigPtr, fac);
+ if (self->num_col==4 && self->num_row==4) {
+ blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac);
}
- else if (self->row_size==3 && self->col_size==3) {
- blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac);
+ else if (self->num_col==3 && self->num_row==3) {
+ blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac);
}
else {
PyErr_SetString(PyExc_ValueError,
@@ -1132,7 +1134,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
- return Matrix_CreatePyObject(mat, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
}
/*---------------------------matrix.determinant() ----------------*/
@@ -1151,7 +1153,7 @@ static PyObject *Matrix_determinant(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->row_size != self->col_size) {
+ if (self->num_col != self->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix.determinant(): "
"only square matrices are supported");
@@ -1173,23 +1175,23 @@ static PyObject *Matrix_transpose(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->row_size != self->col_size) {
+ if (self->num_col != self->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix.transpose(d): "
"only square matrices are supported");
return NULL;
}
- if (self->row_size == 2) {
+ if (self->num_col == 2) {
const float t = MATRIX_ITEM(self, 1, 0);
MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1);
MATRIX_ITEM(self, 0, 1) = t;
}
- else if (self->row_size == 3) {
- transpose_m3((float (*)[3])self->contigPtr);
+ else if (self->num_col == 3) {
+ transpose_m3((float (*)[3])self->matrix);
}
else {
- transpose_m4((float (*)[4])self->contigPtr);
+ transpose_m4((float (*)[4])self->matrix);
}
(void)BaseMath_WriteCallback(self);
@@ -1220,7 +1222,7 @@ PyDoc_STRVAR(Matrix_zero_doc,
);
static PyObject *Matrix_zero(MatrixObject *self)
{
- fill_vn_fl(self->contigPtr, self->row_size * self->col_size, 0.0f);
+ fill_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f);
if (BaseMath_WriteCallback(self) == -1)
return NULL;
@@ -1243,24 +1245,24 @@ static PyObject *Matrix_identity(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->row_size != self->col_size) {
+ if (self->num_col != self->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix.identity(): "
"only square matrices are supported");
return NULL;
}
- if (self->row_size == 2) {
+ if (self->num_col == 2) {
MATRIX_ITEM(self, 0, 0) = 1.0f;
MATRIX_ITEM(self, 0, 1) = 0.0f;
MATRIX_ITEM(self, 1, 0) = 0.0f;
MATRIX_ITEM(self, 1, 1) = 1.0f;
}
- else if (self->row_size == 3) {
- unit_m3((float (*)[3])self->contigPtr);
+ else if (self->num_col == 3) {
+ unit_m3((float (*)[3])self->matrix);
}
else {
- unit_m4((float (*)[4])self->contigPtr);
+ unit_m4((float (*)[4])self->matrix);
}
if (BaseMath_WriteCallback(self) == -1)
@@ -1283,26 +1285,26 @@ static PyObject *Matrix_copy(MatrixObject *self)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return Matrix_CreatePyObject((float (*))self->contigPtr, self->row_size, self->col_size, Py_NEW, Py_TYPE(self));
+ return Matrix_CreatePyObject((float (*))self->matrix, self->num_col, self->num_row, Py_NEW, Py_TYPE(self));
}
/*----------------------------print object (internal)-------------*/
/*print the object to screen*/
static PyObject *Matrix_repr(MatrixObject *self)
{
- int x, y;
+ int col, row;
PyObject *rows[MATRIX_MAX_DIM]= {NULL};
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- for (x = 0; x < self->row_size; x++) {
- rows[x]= PyTuple_New(self->col_size);
- for (y = 0; y < self->col_size; y++) {
- PyTuple_SET_ITEM(rows[x], y, PyFloat_FromDouble(MATRIX_ITEM(self, x, y)));
+ for (col = 0; col < self->num_col; col++) {
+ rows[col]= PyTuple_New(self->num_row);
+ for (row = 0; row < self->num_row; row++) {
+ PyTuple_SET_ITEM(rows[col], row, PyFloat_FromDouble(MATRIX_ITEM(self, row, col)));
}
}
- switch (self->row_size) {
+ switch (self->num_col) {
case 2: return PyUnicode_FromFormat("Matrix((%R,\n"
" %R))", rows[0], rows[1]);
@@ -1320,6 +1322,42 @@ static PyObject *Matrix_repr(MatrixObject *self)
return NULL;
}
+static PyObject* Matrix_str(MatrixObject *self)
+{
+ DynStr *ds;
+
+ int maxsize[MATRIX_MAX_DIM];
+ int row, col;
+
+ char dummy_buf[1];
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ds= BLI_dynstr_new();
+
+ /* First determine the maximum width for each column */
+ for (col = 0; col < self->num_col; col++) {
+ maxsize[col]= 0;
+ for (row = 0; row < self->num_row; row++) {
+ int size= BLI_snprintf(dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
+ maxsize[col]= MAX2(maxsize[col], size);
+ }
+ }
+
+ /* Now write the unicode string to be printed */
+ BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col);
+ for (row = 0; row < self->num_row; row++) {
+ for (col = 0; col < self->num_col; col++) {
+ BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col));
+ }
+ BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n " : ")");
+ }
+ BLI_dynstr_append(ds, ">");
+
+ return mathutils_dynstr_to_py(ds); /* frees ds */
+}
+
static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op)
{
PyObject *res;
@@ -1332,9 +1370,9 @@ static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op)
if (BaseMath_ReadCallback(matA) == -1 || BaseMath_ReadCallback(matB) == -1)
return NULL;
- ok= ( (matA->col_size == matB->col_size) &&
- (matA->row_size == matB->row_size) &&
- EXPP_VectorsAreEqual(matA->contigPtr, matB->contigPtr, (matA->row_size * matA->col_size), 1)
+ ok= ( (matA->num_row == matB->num_row) &&
+ (matA->num_col == matB->num_col) &&
+ EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1)
) ? 0 : -1;
}
@@ -1364,7 +1402,7 @@ static PyObject* Matrix_richcmpr(PyObject *a, PyObject *b, int op)
sequence length*/
static int Matrix_len(MatrixObject *self)
{
- return (self->row_size);
+ return (self->num_col);
}
/*----------------------------object[]---------------------------
sequence accessor (get)
@@ -1374,13 +1412,13 @@ static PyObject *Matrix_item(MatrixObject *self, int i)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (i < 0 || i >= self->row_size) {
+ if (i < 0 || i >= self->num_col) {
PyErr_SetString(PyExc_IndexError,
"matrix[attribute]: "
"array index out of range");
return NULL;
}
- return Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, i);
+ return Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_vector_cb_index, i);
}
/*----------------------------object[]-------------------------
sequence accessor (set) */
@@ -1391,17 +1429,17 @@ static int Matrix_ass_item(MatrixObject *self, int i, PyObject *value)
if (BaseMath_ReadCallback(self) == -1)
return -1;
- if (i >= self->row_size || i < 0) {
+ if (i >= self->num_col || i < 0) {
PyErr_SetString(PyExc_IndexError,
"matrix[attribute] = x: bad column");
return -1;
}
- if (mathutils_array_parse(vec, self->col_size, self->col_size, value, "matrix[i] = value assignment") < 0) {
+ if (mathutils_array_parse(vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") < 0) {
return -1;
}
- memcpy(MATRIX_ROW_PTR(self, i), vec, self->col_size * sizeof(float));
+ memcpy(MATRIX_COL_PTR(self, i), vec, self->num_row * sizeof(float));
(void)BaseMath_WriteCallback(self);
return 0;
@@ -1418,14 +1456,14 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- CLAMP(begin, 0, self->row_size);
- CLAMP(end, 0, self->row_size);
+ CLAMP(begin, 0, self->num_col);
+ CLAMP(end, 0, self->num_col);
begin= MIN2(begin, end);
tuple= PyTuple_New(end - begin);
for (count= begin; count < end; count++) {
PyTuple_SET_ITEM(tuple, count - begin,
- Vector_CreatePyObject_cb((PyObject *)self, self->col_size, mathutils_matrix_vector_cb_index, count));
+ Vector_CreatePyObject_cb((PyObject *)self, self->num_row, mathutils_matrix_vector_cb_index, count));
}
@@ -1440,8 +1478,8 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
if (BaseMath_ReadCallback(self) == -1)
return -1;
- CLAMP(begin, 0, self->row_size);
- CLAMP(end, 0, self->row_size);
+ CLAMP(begin, 0, self->num_col);
+ CLAMP(end, 0, self->num_col);
begin = MIN2(begin, end);
/* non list/tuple cases */
@@ -1467,7 +1505,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
/*parse each sub sequence*/
PyObject *item= PySequence_Fast_GET_ITEM(value_fast, i);
- if (mathutils_array_parse(&mat[i * self->col_size], self->col_size, self->col_size, item,
+ if (mathutils_array_parse(&mat[i * self->num_row], self->num_row, self->num_row, item,
"matrix[begin:end] = value assignment") < 0)
{
return -1;
@@ -1477,7 +1515,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
Py_DECREF(value_fast);
/*parsed well - now set in matrix*/
- memcpy(self->contigPtr + (begin * self->col_size), mat, sizeof(float) * (size * self->col_size));
+ memcpy(self->matrix + (begin * self->num_row), mat, sizeof(float) * (size * self->num_row));
(void)BaseMath_WriteCallback(self);
return 0;
@@ -1504,16 +1542,16 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1)
return NULL;
- if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) {
+ if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
}
- add_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size);
+ add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
subtraction*/
@@ -1537,24 +1575,24 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
if (BaseMath_ReadCallback(mat1) == -1 || BaseMath_ReadCallback(mat2) == -1)
return NULL;
- if (mat1->row_size != mat2->row_size || mat1->col_size != mat2->col_size) {
+ if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
PyErr_SetString(PyExc_TypeError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
}
- sub_vn_vnvn(mat, mat1->contigPtr, mat2->contigPtr, mat1->row_size * mat1->col_size);
+ sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
- return Matrix_CreatePyObject(mat, mat1->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
mulplication*/
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
float tmat[16];
- mul_vn_vn_fl(tmat, mat->contigPtr, mat->row_size * mat->col_size, scalar);
- return Matrix_CreatePyObject(tmat, mat->row_size, mat->col_size, Py_NEW, Py_TYPE(mat));
+ mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
+ return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_NEW, Py_TYPE(mat));
}
static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
@@ -1581,19 +1619,19 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f};
double dot = 0.0f;
- int x, y, z;
+ int col, row, item;
- for (x = 0; x < mat2->row_size; x++) {
- for (y = 0; y < mat1->col_size; y++) {
- for (z = 0; z < mat1->row_size; z++) {
- dot += MATRIX_ITEM(mat1, z, y) * MATRIX_ITEM(mat2, x, z);
+ for (col = 0; col < mat2->num_col; col++) {
+ for (row = 0; row < mat1->num_row; row++) {
+ for (item = 0; item < mat1->num_col; item++) {
+ dot += MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col);
}
- mat[((x * mat1->col_size) + y)] = (float)dot;
+ mat[((col * mat1->num_row) + row)] = (float)dot;
dot = 0.0f;
}
}
- return Matrix_CreatePyObject(mat, mat2->row_size, mat1->col_size, Py_NEW, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_NEW, Py_TYPE(mat1));
}
else if (mat2) {
/*FLOAT/INT * MATRIX */
@@ -1660,13 +1698,13 @@ static PyObject *Matrix_subscript(MatrixObject* self, PyObject* item)
if (i == -1 && PyErr_Occurred())
return NULL;
if (i < 0)
- i += self->row_size;
+ i += self->num_col;
return Matrix_item(self, i);
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0)
+ if (PySlice_GetIndicesEx((void *)item, self->num_col, &start, &stop, &step, &slicelength) < 0)
return NULL;
if (slicelength <= 0) {
@@ -1696,13 +1734,13 @@ static int Matrix_ass_subscript(MatrixObject* self, PyObject* item, PyObject* va
if (i == -1 && PyErr_Occurred())
return -1;
if (i < 0)
- i += self->row_size;
+ i += self->num_col;
return Matrix_ass_item(self, i, value);
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx((void *)item, self->row_size, &start, &stop, &step, &slicelength) < 0)
+ if (PySlice_GetIndicesEx((void *)item, self->num_col, &start, &stop, &step, &slicelength) < 0)
return -1;
if (step == 1)
@@ -1767,12 +1805,12 @@ static PyNumberMethods Matrix_NumMethods = {
static PyObject *Matrix_getRowSize(MatrixObject *self, void *UNUSED(closure))
{
- return PyLong_FromLong((long) self->row_size);
+ return PyLong_FromLong((long) self->num_col);
}
static PyObject *Matrix_getColSize(MatrixObject *self, void *UNUSED(closure))
{
- return PyLong_FromLong((long) self->col_size);
+ return PyLong_FromLong((long) self->num_row);
}
static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closure))
@@ -1783,7 +1821,7 @@ static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closur
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if ((self->col_size < 3) || (self->row_size < 3)) {
+ if ((self->num_row < 3) || (self->num_col < 3)) {
PyErr_SetString(PyExc_AttributeError,
"Matrix.median_scale: "
"inappropriate matrix size, 3x3 minimum");
@@ -1801,10 +1839,10 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->col_size == 4 && self->row_size == 4)
- return PyBool_FromLong(is_negative_m4((float (*)[4])self->contigPtr));
- else if (self->col_size == 3 && self->row_size == 3)
- return PyBool_FromLong(is_negative_m3((float (*)[3])self->contigPtr));
+ if (self->num_row == 4 && self->num_col == 4)
+ return PyBool_FromLong(is_negative_m4((float (*)[4])self->matrix));
+ else if (self->num_row == 3 && self->num_col == 3)
+ return PyBool_FromLong(is_negative_m3((float (*)[3])self->matrix));
else {
PyErr_SetString(PyExc_AttributeError,
"Matrix.is_negative: "
@@ -1819,10 +1857,10 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu
return NULL;
/*must be 3-4 cols, 3-4 rows, square matrix*/
- if (self->col_size == 4 && self->row_size == 4)
- return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->contigPtr));
- else if (self->col_size == 3 && self->row_size == 3)
- return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->contigPtr));
+ if (self->num_row == 4 && self->num_col == 4)
+ return PyBool_FromLong(is_orthogonal_m4((float (*)[4])self->matrix));
+ else if (self->num_row == 3 && self->num_col == 3)
+ return PyBool_FromLong(is_orthogonal_m3((float (*)[3])self->matrix));
else {
PyErr_SetString(PyExc_AttributeError,
"Matrix.is_orthogonal: "
@@ -1906,7 +1944,7 @@ PyTypeObject matrix_Type = {
&Matrix_AsMapping, /*tp_as_mapping*/
NULL, /*tp_hash*/
NULL, /*tp_call*/
- NULL, /*tp_str*/
+ (reprfunc) Matrix_str, /*tp_str*/
NULL, /*tp_getattro*/
NULL, /*tp_setattro*/
NULL, /*tp_as_buffer*/
@@ -1944,37 +1982,37 @@ PyTypeObject matrix_Type = {
* pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
* (i.e. it must be created here with PyMEM_malloc()) */
PyObject *Matrix_CreatePyObject(float *mat,
- const unsigned short row_size, const unsigned short col_size,
+ const unsigned short num_col, const unsigned short num_row,
int type, PyTypeObject *base_type)
{
MatrixObject *self;
/* matrix objects can be any 2-4row x 2-4col matrix */
- if (row_size < 2 || row_size > 4 || col_size < 2 || col_size > 4) {
+ if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
PyErr_SetString(PyExc_RuntimeError,
"Matrix(): "
"row and column sizes must be between 2 and 4");
return NULL;
}
- self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) :
- (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
+ self= base_type ? (MatrixObject *)base_type->tp_alloc(base_type, 0) :
+ (MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
if (self) {
- self->row_size = row_size;
- self->col_size = col_size;
+ self->num_col = num_col;
+ self->num_row = num_row;
/* init callbacks as NULL */
self->cb_user= NULL;
self->cb_type= self->cb_subtype= 0;
if (type == Py_WRAP) {
- self->contigPtr = mat;
+ self->matrix = mat;
self->wrapped = Py_WRAP;
}
else if (type == Py_NEW) {
- self->contigPtr = PyMem_Malloc(row_size * col_size * sizeof(float));
- if (self->contigPtr == NULL) { /*allocation failure*/
+ self->matrix = PyMem_Malloc(num_col * num_row * sizeof(float));
+ if (self->matrix == NULL) { /*allocation failure*/
PyErr_SetString(PyExc_MemoryError,
"Matrix(): "
"problem allocating pointer space");
@@ -1982,16 +2020,16 @@ PyObject *Matrix_CreatePyObject(float *mat,
}
if (mat) { /*if a float array passed*/
- memcpy(self->contigPtr, mat, row_size * col_size * sizeof(float));
+ memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
}
- else if (row_size == col_size) {
+ else if (num_col == num_row) {
/* or if no arguments are passed return identity matrix for square matrices */
PyObject *ret_dummy= Matrix_identity(self);
Py_DECREF(ret_dummy);
}
else {
/* otherwise zero everything */
- memset(self->contigPtr, 0, row_size * col_size * sizeof(float));
+ memset(self->matrix, 0, num_col * num_row * sizeof(float));
}
self->wrapped = Py_NEW;
}
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index 95768febca0..91a276b648e 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -41,22 +41,22 @@ extern PyTypeObject matrix_Type;
/* matrix[row][col] == MATRIX_ITEM_INDEX(matrix, row, col) */
#ifdef DEBUG
-# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->row_size && _col < (_mat)->col_size))
+# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col))
#else
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0
#endif
-#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->col_size * (_row)) + (_col)))
-#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->contigPtr + MATRIX_ITEM_INDEX(_mat, _row, _col))
-#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->contigPtr [MATRIX_ITEM_INDEX(_mat, _row, _col)])
+#define MATRIX_ITEM_INDEX(_mat, _row, _col) (MATRIX_ITEM_ASSERT(_mat, _row, _col),(((_mat)->num_row * (_col)) + (_row)))
+#define MATRIX_ITEM_PTR( _mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col))
+#define MATRIX_ITEM( _mat, _row, _col) ((_mat)->matrix [MATRIX_ITEM_INDEX(_mat, _row, _col)])
-#define MATRIX_ROW_INDEX(_mat, _row) (MATRIX_ITEM_INDEX(_mat, _row, 0))
-#define MATRIX_ROW_PTR( _mat, _row) ((_mat)->contigPtr + MATRIX_ROW_INDEX(_mat, _row))
+#define MATRIX_COL_INDEX(_mat, _col) (MATRIX_ITEM_INDEX(_mat, 0, _col))
+#define MATRIX_COL_PTR( _mat, _col) ((_mat)->matrix + MATRIX_COL_INDEX(_mat, _col))
typedef struct {
- BASE_MATH_MEMBERS(contigPtr);
- unsigned short row_size;
- unsigned short col_size;
+ BASE_MATH_MEMBERS(matrix);
+ unsigned short num_col;
+ unsigned short num_row;
} MatrixObject;
/* struct data contains a pointer to the actual data that the
@@ -66,9 +66,9 @@ typedef struct {
/* prototypes */
PyObject *Matrix_CreatePyObject(float *mat,
- const unsigned short row_size, const unsigned short col_size,
+ const unsigned short num_col, const unsigned short num_row,
int type, PyTypeObject *base_type);
-PyObject *Matrix_CreatePyObject_cb(PyObject *user, int row_size, int col_size, int cb_type, int cb_subtype);
+PyObject *Matrix_CreatePyObject_cb(PyObject *user, int num_col, int num_row, int cb_type, int cb_subtype);
extern int mathutils_matrix_vector_cb_index;
extern struct Mathutils_Callback mathutils_matrix_vector_cb;
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 7ab9b7b0713..7c339807ee9 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
#define QUAT_SIZE 4
@@ -493,6 +494,21 @@ static PyObject *Quaternion_repr(QuaternionObject *self)
return ret;
}
+static PyObject *Quaternion_str(QuaternionObject *self)
+{
+ DynStr *ds;
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ds= BLI_dynstr_new();
+
+ BLI_dynstr_appendf(ds, "<Quaternion (w=%.4f, x=%.4f, y=%.4f, z=%.4f)>",
+ self->quat[0], self->quat[1], self->quat[2], self->quat[3]);
+
+ return mathutils_dynstr_to_py(ds); /* frees ds */
+}
+
static PyObject* Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
{
PyObject *res;
@@ -1167,7 +1183,7 @@ PyTypeObject quaternion_Type = {
&Quaternion_AsMapping, //tp_as_mapping
NULL, //tp_hash
NULL, //tp_call
- NULL, //tp_str
+ (reprfunc) Quaternion_str, //tp_str
NULL, //tp_getattro
NULL, //tp_setattro
NULL, //tp_as_buffer
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index aedf60e7191..bd121b6177f 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
#define MAX_DIMENSIONS 4
@@ -1171,6 +1172,29 @@ static PyObject *Vector_repr(VectorObject *self)
return ret;
}
+static PyObject *Vector_str(VectorObject *self)
+{
+ int i;
+
+ DynStr *ds;
+
+ if (BaseMath_ReadCallback(self) == -1)
+ return NULL;
+
+ ds= BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, "<Vector (");
+
+ for (i = 0; i < self->size; i++) {
+ BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]);
+ }
+
+ BLI_dynstr_append(ds, ")>");
+
+ return mathutils_dynstr_to_py(ds); /* frees ds */
+}
+
+
/* Sequence Protocol */
/* sequence length len(vector) */
static int Vector_len(VectorObject *self)
@@ -1462,14 +1486,14 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
* note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
* note: assume read callbacks have been done first.
*/
-int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
+int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
{
float vec_cpy[MAX_DIMENSIONS];
double dot = 0.0f;
- int x, y, z = 0;
+ int row, col, z = 0;
- if (mat->row_size != vec->size) {
- if (mat->row_size == 4 && vec->size == 3) {
+ if (mat->num_col != vec->size) {
+ if (mat->num_col == 4 && vec->size == 3) {
vec_cpy[3] = 1.0f;
}
else {
@@ -1483,13 +1507,13 @@ int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec,
memcpy(vec_cpy, vec->vec, vec->size * sizeof(float));
- rvec[3] = 1.0f;
+ r_vec[3] = 1.0f;
- for (x = 0; x < mat->col_size; x++) {
- for (y = 0; y < mat->row_size; y++) {
- dot += (double)(MATRIX_ITEM(mat, y, x) * vec_cpy[y]);
+ for (row = 0; row < mat->num_row; row++) {
+ for (col = 0; col < mat->num_col; col++) {
+ dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]);
}
- rvec[z++] = (float)dot;
+ r_vec[z++] = (float)dot;
dot = 0.0f;
}
@@ -2589,8 +2613,8 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v
double dot = 0.0f;
int x, y, z= 0, vec_size= vec->size;
- if (mat->col_size != vec_size) {
- if (mat->col_size == 4 && vec_size != 3) {
+ if (mat->num_row != vec_size) {
+ if (mat->num_row == 4 && vec_size != 3) {
PyErr_SetString(PyExc_ValueError,
"vector * matrix: matrix column size "
"and the vector size must be the same");
@@ -2608,9 +2632,9 @@ static int row_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject *v
rvec[3] = 1.0f;
//muliplication
- for (x = 0; x < mat->row_size; x++) {
- for (y = 0; y < mat->col_size; y++) {
- dot += MATRIX_ITEM(mat, x, y) * vec_cpy[y];
+ for (x = 0; x < mat->num_col; x++) {
+ for (y = 0; y < mat->num_row; y++) {
+ dot += MATRIX_ITEM(mat, y, x) * vec_cpy[y];
}
rvec[z++] = (float)dot;
dot = 0.0f;
@@ -2715,7 +2739,7 @@ PyTypeObject vector_Type = {
NULL, /* hashfunc tp_hash; */
NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
+ (reprfunc)Vector_str, /* reprfunc tp_str; */
NULL, /* getattrofunc tp_getattro; */
NULL, /* setattrofunc tp_setattro; */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 2b44bad82ab..dc2de5fb450 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -190,6 +190,11 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
if(!result)
return;
+
+ result->tilerect.xmin += re->disprect.xmin;
+ result->tilerect.xmax += re->disprect.xmin;
+ result->tilerect.ymin += re->disprect.ymin;
+ result->tilerect.ymax += re->disprect.ymin;
/* merge. on break, don't merge in result for preview renders, looks nicer */
if(!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 883684c3483..f9992050052 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -3083,6 +3083,12 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
continue;
}
break;
+ case TEXCO_EQUIRECTMAP:
+ tempvec[0]= atan2f(lo[0], lo[2]) / (float)M_PI;
+ tempvec[1]= 1.0f - 2.0f*saacos(lo[1]) / (float)M_PI;
+ tempvec[2]= 0.0f;
+ co= tempvec;
+ break;
case TEXCO_OBJECT:
if(mtex->object) {
copy_v3_v3(tempvec, lo);
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 79a7f5bd910..6851b783463 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -491,7 +491,6 @@ elseif(WIN32)
else()
install(
FILES
- ${LIBDIR}/png/lib/libpng.dll
${LIBDIR}/zlib/lib/zlib.dll
DESTINATION ${TARGETDIR}
)
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 360a082b03b..445f2b8f0ba 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -241,6 +241,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
ketsjiengine->SetUseFixedTime(usefixed);
ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS);
+ KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey));
//set the global settings (carried over if restart/load new files)
ketsjiengine->SetGlobalSettings(&gs);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
index 1c91f498d32..93bf133635d 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
@@ -41,6 +41,7 @@
#include "wm_event_types.h"
#include "WM_types.h"
#include "SCA_IInputDevice.h"
+#include "BL_BlenderDataConversion.h"
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
@@ -51,172 +52,9 @@
*/
class BL_BlenderInputDevice : public SCA_IInputDevice
{
- // this map is Blender specific: a conversion between blender and ketsji enums
- std::map<int,KX_EnumInputs> m_reverseKeyTranslateTable;
public:
BL_BlenderInputDevice()
{
-
- /* The reverse table. In order to not confuse ourselves, we */
- /* immediately convert all events that come in to KX codes. */
- m_reverseKeyTranslateTable[LEFTMOUSE ] = KX_LEFTMOUSE;
- m_reverseKeyTranslateTable[MIDDLEMOUSE ] = KX_MIDDLEMOUSE;
- m_reverseKeyTranslateTable[RIGHTMOUSE ] = KX_RIGHTMOUSE;
- m_reverseKeyTranslateTable[WHEELUPMOUSE ] = KX_WHEELUPMOUSE;
- m_reverseKeyTranslateTable[WHEELDOWNMOUSE ] = KX_WHEELDOWNMOUSE;
- m_reverseKeyTranslateTable[MOUSEX ] = KX_MOUSEX;
- m_reverseKeyTranslateTable[MOUSEY ] = KX_MOUSEY;
-
- // TIMERS
-
- m_reverseKeyTranslateTable[TIMER0 ] = KX_TIMER0;
- m_reverseKeyTranslateTable[TIMER1 ] = KX_TIMER1;
- m_reverseKeyTranslateTable[TIMER2 ] = KX_TIMER2;
-
- // SYSTEM
-#if 0
- /* **** XXX **** */
- m_reverseKeyTranslateTable[KEYBD ] = KX_KEYBD;
- m_reverseKeyTranslateTable[RAWKEYBD ] = KX_RAWKEYBD;
- m_reverseKeyTranslateTable[REDRAW ] = KX_REDRAW;
- m_reverseKeyTranslateTable[INPUTCHANGE ] = KX_INPUTCHANGE;
- m_reverseKeyTranslateTable[QFULL ] = KX_QFULL;
- m_reverseKeyTranslateTable[WINFREEZE ] = KX_WINFREEZE;
- m_reverseKeyTranslateTable[WINTHAW ] = KX_WINTHAW;
- m_reverseKeyTranslateTable[WINCLOSE ] = KX_WINCLOSE;
- m_reverseKeyTranslateTable[WINQUIT ] = KX_WINQUIT;
- m_reverseKeyTranslateTable[Q_FIRSTTIME ] = KX_Q_FIRSTTIME;
- /* **** XXX **** */
-#endif
- // standard keyboard
-
- m_reverseKeyTranslateTable[AKEY ] = KX_AKEY;
- m_reverseKeyTranslateTable[BKEY ] = KX_BKEY;
- m_reverseKeyTranslateTable[CKEY ] = KX_CKEY;
- m_reverseKeyTranslateTable[DKEY ] = KX_DKEY;
- m_reverseKeyTranslateTable[EKEY ] = KX_EKEY;
- m_reverseKeyTranslateTable[FKEY ] = KX_FKEY;
- m_reverseKeyTranslateTable[GKEY ] = KX_GKEY;
- //XXX clean up
-#ifdef WIN32
-#define HKEY 'h'
-#endif
- m_reverseKeyTranslateTable[HKEY ] = KX_HKEY;
- //XXX clean up
-#ifdef WIN32
-#undef HKEY
-#endif
- m_reverseKeyTranslateTable[IKEY ] = KX_IKEY;
- m_reverseKeyTranslateTable[JKEY ] = KX_JKEY;
- m_reverseKeyTranslateTable[KKEY ] = KX_KKEY;
- m_reverseKeyTranslateTable[LKEY ] = KX_LKEY;
- m_reverseKeyTranslateTable[MKEY ] = KX_MKEY;
- m_reverseKeyTranslateTable[NKEY ] = KX_NKEY;
- m_reverseKeyTranslateTable[OKEY ] = KX_OKEY;
- m_reverseKeyTranslateTable[PKEY ] = KX_PKEY;
- m_reverseKeyTranslateTable[QKEY ] = KX_QKEY;
- m_reverseKeyTranslateTable[RKEY ] = KX_RKEY;
- m_reverseKeyTranslateTable[SKEY ] = KX_SKEY;
- m_reverseKeyTranslateTable[TKEY ] = KX_TKEY;
- m_reverseKeyTranslateTable[UKEY ] = KX_UKEY;
- m_reverseKeyTranslateTable[VKEY ] = KX_VKEY;
- m_reverseKeyTranslateTable[WKEY ] = KX_WKEY;
- m_reverseKeyTranslateTable[XKEY ] = KX_XKEY;
- m_reverseKeyTranslateTable[YKEY ] = KX_YKEY;
- m_reverseKeyTranslateTable[ZKEY ] = KX_ZKEY;
-
- m_reverseKeyTranslateTable[ZEROKEY ] = KX_ZEROKEY;
- m_reverseKeyTranslateTable[ONEKEY ] = KX_ONEKEY;
- m_reverseKeyTranslateTable[TWOKEY ] = KX_TWOKEY;
- m_reverseKeyTranslateTable[THREEKEY ] = KX_THREEKEY;
- m_reverseKeyTranslateTable[FOURKEY ] = KX_FOURKEY;
- m_reverseKeyTranslateTable[FIVEKEY ] = KX_FIVEKEY;
- m_reverseKeyTranslateTable[SIXKEY ] = KX_SIXKEY;
- m_reverseKeyTranslateTable[SEVENKEY ] = KX_SEVENKEY;
- m_reverseKeyTranslateTable[EIGHTKEY ] = KX_EIGHTKEY;
- m_reverseKeyTranslateTable[NINEKEY ] = KX_NINEKEY;
-
- m_reverseKeyTranslateTable[CAPSLOCKKEY ] = KX_CAPSLOCKKEY;
-
- m_reverseKeyTranslateTable[LEFTCTRLKEY ] = KX_LEFTCTRLKEY;
- m_reverseKeyTranslateTable[LEFTALTKEY ] = KX_LEFTALTKEY;
- m_reverseKeyTranslateTable[RIGHTALTKEY ] = KX_RIGHTALTKEY;
- m_reverseKeyTranslateTable[RIGHTCTRLKEY ] = KX_RIGHTCTRLKEY;
- m_reverseKeyTranslateTable[RIGHTSHIFTKEY ] = KX_RIGHTSHIFTKEY;
- m_reverseKeyTranslateTable[LEFTSHIFTKEY ] = KX_LEFTSHIFTKEY;
-
- m_reverseKeyTranslateTable[ESCKEY ] = KX_ESCKEY;
- m_reverseKeyTranslateTable[TABKEY ] = KX_TABKEY;
- m_reverseKeyTranslateTable[RETKEY ] = KX_RETKEY;
- m_reverseKeyTranslateTable[SPACEKEY ] = KX_SPACEKEY;
- m_reverseKeyTranslateTable[LINEFEEDKEY ] = KX_LINEFEEDKEY;
- m_reverseKeyTranslateTable[BACKSPACEKEY ] = KX_BACKSPACEKEY;
- m_reverseKeyTranslateTable[DELKEY ] = KX_DELKEY;
- m_reverseKeyTranslateTable[SEMICOLONKEY ] = KX_SEMICOLONKEY;
- m_reverseKeyTranslateTable[PERIODKEY ] = KX_PERIODKEY;
- m_reverseKeyTranslateTable[COMMAKEY ] = KX_COMMAKEY;
- m_reverseKeyTranslateTable[QUOTEKEY ] = KX_QUOTEKEY;
- m_reverseKeyTranslateTable[ACCENTGRAVEKEY ] = KX_ACCENTGRAVEKEY;
- m_reverseKeyTranslateTable[MINUSKEY ] = KX_MINUSKEY;
- m_reverseKeyTranslateTable[SLASHKEY ] = KX_SLASHKEY;
- m_reverseKeyTranslateTable[BACKSLASHKEY ] = KX_BACKSLASHKEY;
- m_reverseKeyTranslateTable[EQUALKEY ] = KX_EQUALKEY;
- m_reverseKeyTranslateTable[LEFTBRACKETKEY ] = KX_LEFTBRACKETKEY;
- m_reverseKeyTranslateTable[RIGHTBRACKETKEY ] = KX_RIGHTBRACKETKEY;
-
- m_reverseKeyTranslateTable[LEFTARROWKEY ] = KX_LEFTARROWKEY;
- m_reverseKeyTranslateTable[DOWNARROWKEY ] = KX_DOWNARROWKEY;
- m_reverseKeyTranslateTable[RIGHTARROWKEY ] = KX_RIGHTARROWKEY;
- m_reverseKeyTranslateTable[UPARROWKEY ] = KX_UPARROWKEY;
-
- m_reverseKeyTranslateTable[PAD2 ] = KX_PAD2;
- m_reverseKeyTranslateTable[PAD4 ] = KX_PAD4;
- m_reverseKeyTranslateTable[PAD6 ] = KX_PAD6;
- m_reverseKeyTranslateTable[PAD8 ] = KX_PAD8;
-
- m_reverseKeyTranslateTable[PAD1 ] = KX_PAD1;
- m_reverseKeyTranslateTable[PAD3 ] = KX_PAD3;
- m_reverseKeyTranslateTable[PAD5 ] = KX_PAD5;
- m_reverseKeyTranslateTable[PAD7 ] = KX_PAD7;
- m_reverseKeyTranslateTable[PAD9 ] = KX_PAD9;
-
- m_reverseKeyTranslateTable[PADPERIOD ] = KX_PADPERIOD;
- m_reverseKeyTranslateTable[PADSLASHKEY ] = KX_PADSLASHKEY;
- m_reverseKeyTranslateTable[PADASTERKEY ] = KX_PADASTERKEY;
-
-
- m_reverseKeyTranslateTable[PAD0 ] = KX_PAD0;
- m_reverseKeyTranslateTable[PADMINUS ] = KX_PADMINUS;
- m_reverseKeyTranslateTable[PADENTER ] = KX_PADENTER;
- m_reverseKeyTranslateTable[PADPLUSKEY ] = KX_PADPLUSKEY;
-
-
- m_reverseKeyTranslateTable[F1KEY ] = KX_F1KEY;
- m_reverseKeyTranslateTable[F2KEY ] = KX_F2KEY;
- m_reverseKeyTranslateTable[F3KEY ] = KX_F3KEY;
- m_reverseKeyTranslateTable[F4KEY ] = KX_F4KEY;
- m_reverseKeyTranslateTable[F5KEY ] = KX_F5KEY;
- m_reverseKeyTranslateTable[F6KEY ] = KX_F6KEY;
- m_reverseKeyTranslateTable[F7KEY ] = KX_F7KEY;
- m_reverseKeyTranslateTable[F8KEY ] = KX_F8KEY;
- m_reverseKeyTranslateTable[F9KEY ] = KX_F9KEY;
- m_reverseKeyTranslateTable[F10KEY ] = KX_F10KEY;
- m_reverseKeyTranslateTable[F11KEY ] = KX_F11KEY;
- m_reverseKeyTranslateTable[F12KEY ] = KX_F12KEY;
- m_reverseKeyTranslateTable[F13KEY ] = KX_F13KEY;
- m_reverseKeyTranslateTable[F14KEY ] = KX_F14KEY;
- m_reverseKeyTranslateTable[F15KEY ] = KX_F15KEY;
- m_reverseKeyTranslateTable[F16KEY ] = KX_F16KEY;
- m_reverseKeyTranslateTable[F17KEY ] = KX_F17KEY;
- m_reverseKeyTranslateTable[F18KEY ] = KX_F18KEY;
- m_reverseKeyTranslateTable[F19KEY ] = KX_F19KEY;
-
- m_reverseKeyTranslateTable[PAUSEKEY ] = KX_PAUSEKEY;
- m_reverseKeyTranslateTable[INSERTKEY ] = KX_INSERTKEY;
- m_reverseKeyTranslateTable[HOMEKEY ] = KX_HOMEKEY;
- m_reverseKeyTranslateTable[PAGEUPKEY ] = KX_PAGEUPKEY;
- m_reverseKeyTranslateTable[PAGEDOWNKEY ] = KX_PAGEDOWNKEY;
- m_reverseKeyTranslateTable[ENDKEY ] = KX_ENDKEY;
}
virtual ~BL_BlenderInputDevice()
@@ -225,7 +63,7 @@ public:
}
KX_EnumInputs ToNative(unsigned short incode) {
- return m_reverseKeyTranslateTable[incode];
+ return ConvertKeyCode(incode);
}
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
index a6712c531fb..54c60096812 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.cpp
@@ -36,6 +36,7 @@
#endif
#include "KX_BlenderKeyboardDevice.h"
+#include "KX_KetsjiEngine.h"
KX_BlenderKeyboardDevice::KX_BlenderKeyboardDevice()
: m_hookesc(false)
@@ -106,7 +107,7 @@ bool KX_BlenderKeyboardDevice::ConvertBlenderEvent(unsigned short incode,short v
if (val == KM_PRESS)
{
- if (kxevent == KX_ESCKEY && val != 0 && !m_hookesc)
+ if (kxevent == KX_KetsjiEngine::GetExitKey() && val != 0 && !m_hookesc)
result = true;
if (kxevent == KX_PAUSEKEY && val && (IsPressed(KX_LEFTCTRLKEY) || IsPressed(KX_RIGHTCTRLKEY)))
result = true;
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h
index 63a01db2fe0..3039e69efcd 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderKeyboardDevice.h
@@ -50,6 +50,8 @@ public:
virtual bool ConvertBlenderEvent(unsigned short incode,short val);
virtual void NextFrame();
virtual void HookEscape();
+private:
+ short m_exit_key;
#ifdef WITH_CXX_GUARDEDALLOC
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 57611d65e14..ff4b9ba9c96 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -197,6 +197,180 @@ extern "C" {
static bool default_light_mode = 0;
+static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table()
+{
+ std::map<int, SCA_IInputDevice::KX_EnumInputs> m;
+
+ /* The reverse table. In order to not confuse ourselves, we */
+ /* immediately convert all events that come in to KX codes. */
+ m[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
+ m[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
+ m[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
+ m[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE;
+ m[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
+ m[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
+ m[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
+
+ // TIMERS
+
+ m[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
+ m[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
+ m[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
+
+ // SYSTEM
+
+#if 0
+ /* **** XXX **** */
+ m[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
+ m[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
+ m[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
+ m[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
+ m[QFULL ] = SCA_IInputDevice::KX_QFULL;
+ m[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
+ m[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
+ m[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
+ m[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
+ m[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
+ /* **** XXX **** */
+#endif
+
+ // standard keyboard
+
+ m[AKEY ] = SCA_IInputDevice::KX_AKEY;
+ m[BKEY ] = SCA_IInputDevice::KX_BKEY;
+ m[CKEY ] = SCA_IInputDevice::KX_CKEY;
+ m[DKEY ] = SCA_IInputDevice::KX_DKEY;
+ m[EKEY ] = SCA_IInputDevice::KX_EKEY;
+ m[FKEY ] = SCA_IInputDevice::KX_FKEY;
+ m[GKEY ] = SCA_IInputDevice::KX_GKEY;
+
+//XXX clean up
+#ifdef WIN32
+#define HKEY 'h'
+#endif
+ m[HKEY ] = SCA_IInputDevice::KX_HKEY;
+//XXX clean up
+#ifdef WIN32
+#undef HKEY
+#endif
+
+ m[IKEY ] = SCA_IInputDevice::KX_IKEY;
+ m[JKEY ] = SCA_IInputDevice::KX_JKEY;
+ m[KKEY ] = SCA_IInputDevice::KX_KKEY;
+ m[LKEY ] = SCA_IInputDevice::KX_LKEY;
+ m[MKEY ] = SCA_IInputDevice::KX_MKEY;
+ m[NKEY ] = SCA_IInputDevice::KX_NKEY;
+ m[OKEY ] = SCA_IInputDevice::KX_OKEY;
+ m[PKEY ] = SCA_IInputDevice::KX_PKEY;
+ m[QKEY ] = SCA_IInputDevice::KX_QKEY;
+ m[RKEY ] = SCA_IInputDevice::KX_RKEY;
+ m[SKEY ] = SCA_IInputDevice::KX_SKEY;
+ m[TKEY ] = SCA_IInputDevice::KX_TKEY;
+ m[UKEY ] = SCA_IInputDevice::KX_UKEY;
+ m[VKEY ] = SCA_IInputDevice::KX_VKEY;
+ m[WKEY ] = SCA_IInputDevice::KX_WKEY;
+ m[XKEY ] = SCA_IInputDevice::KX_XKEY;
+ m[YKEY ] = SCA_IInputDevice::KX_YKEY;
+ m[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
+
+ m[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
+ m[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
+ m[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
+ m[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
+ m[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
+ m[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
+ m[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
+ m[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
+ m[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
+ m[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
+
+ m[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
+
+ m[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
+ m[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
+ m[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
+ m[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
+ m[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
+ m[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
+
+ m[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
+ m[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
+ m[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
+ m[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
+ m[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
+ m[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
+ m[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
+ m[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
+ m[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
+ m[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
+ m[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
+ m[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
+ m[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
+ m[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
+ m[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
+ m[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
+ m[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
+ m[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
+
+ m[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
+ m[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
+ m[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
+ m[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
+
+ m[PAD2 ] = SCA_IInputDevice::KX_PAD2;
+ m[PAD4 ] = SCA_IInputDevice::KX_PAD4;
+ m[PAD6 ] = SCA_IInputDevice::KX_PAD6;
+ m[PAD8 ] = SCA_IInputDevice::KX_PAD8;
+
+ m[PAD1 ] = SCA_IInputDevice::KX_PAD1;
+ m[PAD3 ] = SCA_IInputDevice::KX_PAD3;
+ m[PAD5 ] = SCA_IInputDevice::KX_PAD5;
+ m[PAD7 ] = SCA_IInputDevice::KX_PAD7;
+ m[PAD9 ] = SCA_IInputDevice::KX_PAD9;
+
+ m[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
+ m[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
+ m[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
+
+ m[PAD0 ] = SCA_IInputDevice::KX_PAD0;
+ m[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
+ m[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
+ m[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
+
+
+ m[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
+ m[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
+ m[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
+ m[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
+ m[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
+ m[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
+ m[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
+ m[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
+ m[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
+ m[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
+ m[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
+ m[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
+ m[F13KEY ] = SCA_IInputDevice::KX_F13KEY;
+ m[F14KEY ] = SCA_IInputDevice::KX_F14KEY;
+ m[F15KEY ] = SCA_IInputDevice::KX_F15KEY;
+ m[F16KEY ] = SCA_IInputDevice::KX_F16KEY;
+ m[F17KEY ] = SCA_IInputDevice::KX_F17KEY;
+ m[F18KEY ] = SCA_IInputDevice::KX_F18KEY;
+ m[F19KEY ] = SCA_IInputDevice::KX_F19KEY;
+
+
+ m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
+ m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
+ m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
+ m[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
+ m[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
+ m[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
+
+ return m;
+}
+
+static std::map<int, SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable = create_translate_table();
+
static unsigned int KX_rgbaint2uint_new(unsigned int icol)
{
union
@@ -2854,3 +3028,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
RAS_BucketManager *bucketmanager = kxscene->GetBucketManager();
bucketmanager->OptimizeBuckets(distance);
}
+
+SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code)
+{
+ return gReverseKeyTranslateTable[key_code];
+} \ No newline at end of file
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
index 2ae7fee1798..6da3ac90aef 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.h
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -36,6 +36,7 @@
#include "STR_String.h"
#include "KX_Python.h"
#include "KX_PhysicsEngineEnums.h"
+#include "SCA_IInputDevice.h"
class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
@@ -49,5 +50,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
bool alwaysUseExpandFraming
);
+SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code);
+
#endif // __BLENDER_CONVERT
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index b7aee8ec924..9391d12a3ce 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -86,10 +86,7 @@ probably misplaced */
#include "KX_KetsjiEngine.h"
#include "KX_BlenderSceneConverter.h"
-
-// this map is Blender specific: a conversion between blender and ketsji enums
-std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
-
+#include "BL_BlenderDataConversion.h"
void BL_ConvertSensors(struct Object* blenderobject,
class KX_GameObject* gameobj,
@@ -102,177 +99,6 @@ void BL_ConvertSensors(struct Object* blenderobject,
KX_BlenderSceneConverter* converter
)
{
- static bool reverseTableConverted = false;
-
- if (!reverseTableConverted)
- {
- reverseTableConverted = true;
-
- /* The reverse table. In order to not confuse ourselves, we */
- /* immediately convert all events that come in to KX codes. */
- gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
- gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
- gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
- gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE;
- gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
- gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
- gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
-
- // TIMERS
-
- gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
- gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
- gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
-
- // SYSTEM
-
-#if 0
- /* **** XXX **** */
- gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
- gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
- gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
- gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
- gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL;
- gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
- gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
- gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
- gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
- gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
- /* **** XXX **** */
-#endif
-
- // standard keyboard
-
- gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY;
- gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY;
- gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY;
- gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY;
- gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY;
- gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY;
- gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY;
-
-//XXX clean up
-#ifdef WIN32
-#define HKEY 'h'
-#endif
- gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY;
-//XXX clean up
-#ifdef WIN32
-#undef HKEY
-#endif
-
- gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY;
- gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY;
- gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY;
- gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY;
- gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY;
- gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY;
- gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY;
- gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY;
- gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY;
- gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY;
- gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY;
- gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY;
- gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY;
- gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY;
- gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY;
- gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY;
- gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY;
- gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
-
- gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
- gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
- gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
- gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
- gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
- gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
- gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
- gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
- gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
- gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
-
- gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
-
- gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
- gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
- gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
- gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
- gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
- gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
-
- gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
- gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
- gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
- gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
- gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
- gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
- gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
- gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
- gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
- gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
- gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
- gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
- gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
- gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
- gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
- gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
- gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
- gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
-
- gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
- gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
- gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
- gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
-
- gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2;
- gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4;
- gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6;
- gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8;
-
- gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1;
- gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3;
- gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5;
- gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7;
- gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9;
-
- gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
- gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
- gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
-
- gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0;
- gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
- gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
- gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
-
-
- gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
- gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
- gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
- gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
- gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
- gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
- gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
- gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
- gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
- gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
- gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
- gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
- gReverseKeyTranslateTable[F13KEY ] = SCA_IInputDevice::KX_F13KEY;
- gReverseKeyTranslateTable[F14KEY ] = SCA_IInputDevice::KX_F14KEY;
- gReverseKeyTranslateTable[F15KEY ] = SCA_IInputDevice::KX_F15KEY;
- gReverseKeyTranslateTable[F16KEY ] = SCA_IInputDevice::KX_F16KEY;
- gReverseKeyTranslateTable[F17KEY ] = SCA_IInputDevice::KX_F17KEY;
- gReverseKeyTranslateTable[F18KEY ] = SCA_IInputDevice::KX_F18KEY;
- gReverseKeyTranslateTable[F19KEY ] = SCA_IInputDevice::KX_F19KEY;
-
-
- gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
- gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
- gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
- gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
- gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
- gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
- }
int executePriority = 0;
int uniqueint = 0;
@@ -470,9 +296,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
if (eventmgr)
{
gamesensor = new SCA_KeyboardSensor(eventmgr,
- gReverseKeyTranslateTable[blenderkeybdsensor->key],
- gReverseKeyTranslateTable[blenderkeybdsensor->qual],
- gReverseKeyTranslateTable[blenderkeybdsensor->qual2],
+ ConvertKeyCode(blenderkeybdsensor->key),
+ ConvertKeyCode(blenderkeybdsensor->qual),
+ ConvertKeyCode(blenderkeybdsensor->qual2),
(blenderkeybdsensor->type == SENS_ALL_KEYS),
blenderkeybdsensor->targetName,
blenderkeybdsensor->toggleName,
diff --git a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h
index 5b267c92908..3d88dc467b0 100644
--- a/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h
+++ b/source/gameengine/GamePlayer/common/GPC_KeyboardDevice.h
@@ -57,6 +57,7 @@ protected:
* System dependent keyboard codes are stored as ints.
*/
std::map<int, KX_EnumInputs> m_reverseKeyTranslateTable;
+ short m_exitkey;
public:
bool m_hookesc;
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 7490e187824..f9403c9725a 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -40,6 +40,7 @@
#include "GPU_extensions.h"
#include "GPG_Application.h"
+#include "BL_BlenderDataConversion.h"
#include <iostream>
#include <MT_assert.h>
@@ -626,6 +627,8 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
m_ketsjiengine->SetRasterizer(m_rasterizer);
m_ketsjiengine->SetTimingDisplay(frameRate, false, false);
+
+ KX_KetsjiEngine::SetExitKey(ConvertKeyCode(gm->exitkey));
#ifdef WITH_PYTHON
CValue::SetDeprecationWarnings(nodepwarnings);
#else
@@ -908,12 +911,10 @@ bool GPG_Application::handleKey(GHOST_IEvent* event, bool isDown)
{
GHOST_TEventDataPtr eventData = ((GHOST_IEvent*)event)->getData();
GHOST_TEventKeyData* keyData = static_cast<GHOST_TEventKeyData*>(eventData);
- //no need for this test
- //if (fSystem->getFullScreen()) {
- if (keyData->key == GHOST_kKeyEsc && !m_keyboard->m_hookesc && !m_isEmbedded) {
- m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
- }
- //}
+
+ if (m_keyboard->ToNative(keyData->key) == KX_KetsjiEngine::GetExitKey() && !m_keyboard->m_hookesc && !m_isEmbedded) {
+ m_exitRequested = KX_EXIT_REQUEST_OUTSIDE;
+ }
m_keyboard->ConvertEvent(keyData->key, isDown);
handled = true;
}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h
index a8a976f9dd2..37625dc8998 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h
@@ -103,6 +103,7 @@ protected:
* Shuts the game engine down.
*/
void exitEngine(void);
+ short m_exitkey;
/* The game data */
STR_String m_startSceneName;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index a9be588e6b2..29727dc04da 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -110,6 +110,7 @@ double KX_KetsjiEngine::m_suspendedtime = 0.0;
double KX_KetsjiEngine::m_suspendeddelta = 0.0;
double KX_KetsjiEngine::m_average_framerate = 0.0;
bool KX_KetsjiEngine::m_restrict_anim_fps = false;
+short KX_KetsjiEngine::m_exitkey = 130; //ESC Key
/**
@@ -1857,6 +1858,16 @@ double KX_KetsjiEngine::GetAverageFrameRate()
return m_average_framerate;
}
+void KX_KetsjiEngine::SetExitKey(short key)
+{
+ m_exitkey = key;
+}
+
+short KX_KetsjiEngine::GetExitKey()
+{
+ return m_exitkey;
+}
+
void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties)
{
m_show_framerate = frameRate;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 5a02da07e43..96b737b686d 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -124,6 +124,8 @@ private:
static double m_suspendedtime;
static double m_suspendeddelta;
+ static short m_exitkey; /* Key used to exit the BGE */
+
int m_exitcode;
STR_String m_exitstring;
/**
@@ -352,6 +354,10 @@ public:
*/
static double GetAverageFrameRate();
+ static void SetExitKey(short key);
+
+ static short GetExitKey();
+
/**
* Activates or deactivates timing information display.
* @param frameRate Display for frame rate on or off.
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 29871c2b3cd..9a2c0cb89b1 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -419,6 +419,20 @@ static PyObject* gPyGetLogicTicRate(PyObject*)
return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate());
}
+static PyObject* gPySetExitKey(PyObject*, PyObject* args)
+{
+ short exitkey;
+ if (!PyArg_ParseTuple(args, "h:setExitKey", &exitkey))
+ return NULL;
+ KX_KetsjiEngine::SetExitKey(exitkey);
+ Py_RETURN_NONE;
+}
+
+static PyObject* gPyGetExitKey(PyObject*)
+{
+ return PyLong_FromSsize_t(KX_KetsjiEngine::GetExitKey());
+}
+
static PyObject* gPySetMaxLogicFrame(PyObject*, PyObject* args)
{
int frame;
@@ -812,6 +826,8 @@ static struct PyMethodDef game_methods[] = {
{"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (const char *)"Sets the logic tic rate"},
{"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (const char *)"Gets the physics tic rate"},
{"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, (const char *)"Sets the physics tic rate"},
+ {"getExitKey", (PyCFunction) gPyGetExitKey, METH_NOARGS, (const char *)"Gets the key used to exit the game engine"},
+ {"setExitKey", (PyCFunction) gPySetExitKey, METH_VARARGS, (const char *)"Sets the key used to exit the game engine"},
{"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"},
{"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"},
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt
index 40d304ef4b9..74a0ad1c628 100644
--- a/source/tests/CMakeLists.txt
+++ b/source/tests/CMakeLists.txt
@@ -60,6 +60,11 @@ add_test(script_run_operators ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_run_operators.py
)
+# test running mathutils testing script
+add_test(script_pyapi_mathutils ${TEST_BLENDER_EXE}
+ --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_mathutils.py
+)
+
# ------------------------------------------------------------------------------
# IO TESTS
diff --git a/source/tests/bl_pyapi_mathutils.py b/source/tests/bl_pyapi_mathutils.py
new file mode 100644
index 00000000000..f1d6d96c68b
--- /dev/null
+++ b/source/tests/bl_pyapi_mathutils.py
@@ -0,0 +1,109 @@
+import unittest
+from test import support
+from mathutils import Matrix, Vector
+
+
+class MatrixTesting(unittest.TestCase):
+ def test_matrix_column_access(self):
+ #mat =
+ #[ 1 2 3 4 ]
+ #[ 1 2 3 4 ]
+ #[ 1 2 3 4 ]
+ mat = Matrix(((1, 11, 111),
+ (2, 22, 222),
+ (3, 33, 333),
+ (4, 44, 444)))
+
+ self.assertEqual(mat[0], Vector((1, 11, 111)))
+ self.assertEqual(mat[1], Vector((2, 22, 222)))
+ self.assertEqual(mat[2], Vector((3, 33, 333)))
+ self.assertEqual(mat[3], Vector((4, 44, 444)))
+
+ def test_item_access(self):
+ args = ((1, 4, 0, -1),
+ (2, -1, 2, -2),
+ (0, 3, 8, 3),
+ (-2, 9, 1, 0))
+
+ mat = Matrix(args)
+
+ for i in range(4):
+ for j in range(4):
+ self.assertEqual(mat[i][j], args[i][j])
+
+ self.assertEqual(mat[0][2], 0)
+ self.assertEqual(mat[3][1], 9)
+ self.assertEqual(mat[2][3], 3)
+ self.assertEqual(mat[0][0], 1)
+ self.assertEqual(mat[3][3], 0)
+
+ def test_item_assignment(self):
+ mat = Matrix() - Matrix()
+ indices = (0, 0), (1, 3), (2, 0), (3, 2), (3, 1)
+ checked_indices = []
+ for col, row in indices:
+ mat[col][row] = 1
+
+ for col in range(4):
+ for row in range(4):
+ if mat[col][row]:
+ checked_indices.append((col, row))
+
+ for item in checked_indices:
+ self.assertIn(item, indices)
+
+ def test_matrix_to_3x3(self):
+ #mat =
+ #[ 1 2 3 4 ]
+ #[ 2 4 6 8 ]
+ #[ 3 6 9 12 ]
+ #[ 4 8 12 16 ]
+ mat = Matrix(tuple((i, 2 * i, 3 * i, 4 * i) for i in range(1, 5)))
+ mat_correct = Matrix(((1, 2, 3), (2, 4, 6), (3, 6, 9)))
+ self.assertEqual(mat.to_3x3(), mat_correct)
+
+ def test_matrix_to_translation(self):
+ mat = Matrix()
+ mat[3] = (1, 2, 3, 4)
+ self.assertEqual(mat.to_translation(), Vector((1, 2, 3)))
+
+ def test_matrix_inverse(self):
+ mat = Matrix(((1, 4, 0, -1),
+ (2, -1, 2, -2),
+ (0, 3, 8, 3),
+ (-2, 9, 1, 0)))
+
+ inv_mat = (1 / 285) * Matrix(((195, -57, 27, -102),
+ (50, -19, 4, 6),
+ (-60, 57, 18, 27),
+ (110, -133, 43, -78)))
+
+ self.assertEqual(mat.inverted(), inv_mat)
+
+ def test_matrix_mult(self):
+ mat = Matrix(((1, 4, 0, -1),
+ (2, -1, 2, -2),
+ (0, 3, 8, 3),
+ (-2, 9, 1, 0)))
+
+ prod_mat = Matrix(((11, -9, 7, -9),
+ (4, -3, 12, 6),
+ (0, 48, 73, 18),
+ (16, -14, 26, -13)))
+
+ self.assertEqual(mat * mat, prod_mat)
+
+
+def test_main():
+ try:
+ support.run_unittest(MatrixTesting)
+ except:
+ import traceback
+ traceback.print_exc()
+
+ # alert CTest we failed
+ import sys
+ sys.exit(1)
+
+if __name__ == '__main__':
+ test_main()