Merging r40653 through r40847 from trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 7 Oct 2011 18:57:26 +0000 (18:57 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 7 Oct 2011 18:57:26 +0000 (18:57 +0000)
251 files changed:
CMakeLists.txt
GNUmakefile
SConstruct
build_files/buildbot/config/user-config-i686.py
build_files/buildbot/config/user-config-player-i686.py
build_files/buildbot/config/user-config-player-x86_64.py
build_files/buildbot/config/user-config-x86_64.py
build_files/cmake/Modules/FindPythonLibsUnix.cmake
build_files/cmake/Modules/FindSamplerate.cmake [deleted file]
build_files/cmake/config/blender_headless.cmake
build_files/cmake/config/blender_lite.cmake
build_files/cmake/config/bpy_module.cmake
build_files/cmake/macros.cmake
build_files/package_spec/debian/control
build_files/package_spec/pacman/PKGBUILD
build_files/scons/config/darwin-config.py
build_files/scons/config/freebsd7-config.py
build_files/scons/config/freebsd8-config.py
build_files/scons/config/freebsd9-config.py
build_files/scons/config/linux-config.py
build_files/scons/config/linuxcross-config.py
build_files/scons/config/openbsd3-config.py
build_files/scons/config/sunos5-config.py
build_files/scons/config/win32-mingw-config.py
build_files/scons/config/win32-vc-config.py
build_files/scons/config/win64-vc-config.py
build_files/scons/tools/Blender.py
build_files/scons/tools/btools.py
doc/python_api/examples/aud.py
doc/python_api/rst/change_log.rst
doc/python_api/sphinx_changelog_gen.py
doc/python_api/sphinx_doc_gen.py
extern/recastnavigation/CMakeLists.txt
extern/recastnavigation/Recast/Include/Recast.h
extern/recastnavigation/Recast/Include/RecastAlloc.h [new file with mode: 0644]
extern/recastnavigation/Recast/Include/RecastAssert.h [new file with mode: 0644]
extern/recastnavigation/Recast/Source/Recast.cpp
extern/recastnavigation/Recast/Source/RecastAlloc.cpp [new file with mode: 0644]
extern/recastnavigation/Recast/Source/RecastArea.cpp [new file with mode: 0644]
extern/recastnavigation/Recast/Source/RecastContour.cpp
extern/recastnavigation/Recast/Source/RecastFilter.cpp
extern/recastnavigation/Recast/Source/RecastLayers.cpp [new file with mode: 0644]
extern/recastnavigation/Recast/Source/RecastMesh.cpp
extern/recastnavigation/Recast/Source/RecastMeshDetail.cpp
extern/recastnavigation/Recast/Source/RecastRasterization.cpp
extern/recastnavigation/Recast/Source/RecastRegion.cpp
extern/recastnavigation/recast-capi.cpp
extern/recastnavigation/recast-capi.h
intern/audaspace/CMakeLists.txt
intern/audaspace/SConscript
intern/container/CTR_List.h
intern/container/CTR_Map.h
intern/elbeem/intern/ntl_world.cpp
intern/ghost/GHOST_Types.h
intern/ghost/SConscript
intern/ghost/intern/GHOST_Buttons.h
intern/ghost/intern/GHOST_ModifierKeys.h
intern/ghost/intern/GHOST_SystemCarbon.h
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemPathsCarbon.h
intern/ghost/intern/GHOST_SystemPathsCocoa.h
intern/ghost/intern/GHOST_TaskbarWin32.h
intern/ghost/intern/GHOST_Window.h
intern/ghost/intern/GHOST_WindowCarbon.h
intern/ghost/test/gears/GHOST_C-Test.c
intern/mikktspace/mikktspace.c
intern/string/STR_String.h
po/README.txt
po/check_po.py [new file with mode: 0755]
po/clean_po.py [new file with mode: 0755]
po/merge_po.py [new file with mode: 0755]
po/messages.txt [deleted file]
po/update_mo.py
po/update_msg.py
po/update_po.py
po/update_pot.py
release/bin/.blender/.Blanguages [deleted file]
release/bin/.blender/fonts/droidsans.ttf.gz
release/scripts/modules/bpy/ops.py
release/scripts/modules/bpy_extras/keyconfig_utils.py
release/scripts/startup/bl_operators/object_quick_effects.py
release/scripts/startup/bl_operators/screen_play_rendered_anim.py
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_sequencer.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_userpref_keymap.py
release/scripts/startup/bl_ui/space_view3d.py
release/text/readme.html
source/blender/blenfont/CMakeLists.txt
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/navmesh_conversion.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/mesh/mesh_navmesh.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/render/render_preview.c
source/blender/editors/screen/area.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/space_file.c
source/blender/editors/space_graph/graph_buttons.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_sequencer/sequencer_intern.h
source/blender/editors/space_sequencer/sequencer_ops.c
source/blender/editors/space_sequencer/sequencer_select.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/imbuf/intern/anim_movie.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesdna/intern/CMakeLists.txt
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_define.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_boid.c
source/blender/makesrna/intern/rna_camera.c
source/blender/makesrna/intern/rna_camera_api.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_cloth.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_curve.c
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_fcurve.c
source/blender/makesrna/intern/rna_fluidsim.c
source/blender/makesrna/intern/rna_group.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_internal_types.h
source/blender/makesrna/intern/rna_key.c
source/blender/makesrna/intern/rna_lattice.c
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_material.c
source/blender/makesrna/intern/rna_mesh.c
source/blender/makesrna/intern/rna_meta.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_particle.c
source/blender/makesrna/intern/rna_pose.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_rna.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_screen.c
source/blender/makesrna/intern/rna_sequencer.c
source/blender/makesrna/intern/rna_smoke.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_texture.c
source/blender/makesrna/intern/rna_tracking.c
source/blender/makesrna/intern/rna_ui.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/intern/rna_wm.c
source/blender/modifiers/intern/MOD_explode.c
source/blender/nodes/composite/nodes/node_composite_idMask.c
source/blender/python/intern/bpy_app_handlers.c
source/blender/python/intern/bpy_driver.c
source/blender/python/intern/bpy_operator.c
source/blender/python/intern/bpy_operator_wrap.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h
source/blender/python/mathutils/mathutils.c
source/blender/quicktime/SConscript
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/volume_precache.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/gameengine/Converter/BlenderWorldInfo.h
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
source/gameengine/GameLogic/SCA_2DFilterActuator.h
source/gameengine/Ketsji/KX_Dome.cpp
source/gameengine/Ketsji/KX_Dome.h
source/gameengine/Ketsji/KX_NavMeshObject.cpp
source/gameengine/Ketsji/KX_OrientationInterpolator.h
source/gameengine/Ketsji/KX_SteeringActuator.cpp
source/gameengine/Ketsji/KX_VertexProxy.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h
source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/SceneGraph/SG_DList.h
source/gameengine/VideoTexture/ImageRender.h
source/gameengine/VideoTexture/ImageViewport.h

index a45a356..ad7c684 100644 (file)
@@ -26,8 +26,8 @@
 # ***** END GPL LICENSE BLOCK *****
 
 #-----------------------------------------------------------------------------
-# We don't allow in-source builds. This causes no end of troubles because 
-# all out-of-source builds will use the CMakeCache.txt file there and even 
+# We don't allow in-source builds. This causes no end of troubles because
+# all out-of-source builds will use the CMakeCache.txt file there and even
 # build the libs and objects in it.
 
 if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
@@ -189,7 +189,6 @@ option(WITH_OPENCOLLADA             "Enable OpenCollada Support (http://www.opencollada.org
 option(WITH_SDL           "Enable SDL for sound and joystick support" ON)
 option(WITH_OPENAL        "Enable OpenAL Support (http://www.openal.org)" ON)
 option(WITH_JACK          "Enable Jack Support (http://www.jackaudio.org)" OFF)
-option(WITH_SAMPLERATE    "Enable samplerate conversion" ON)
 
 # Compression
 option(WITH_LZO           "Enable fast LZO compression (used for pointcache)" ON)
@@ -200,7 +199,7 @@ option(WITH_LIBMV         "Enable libmv structure from motion library" ON)
 
 # Misc
 option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
-option(WITH_RAYOPTIMIZATION    "Enable use of SIMD (SSE) optimizations for the raytracer" ON) 
+option(WITH_RAYOPTIMIZATION    "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
 if(UNIX AND NOT APPLE)
        option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
 endif()
@@ -276,7 +275,7 @@ if(WITH_PYTHON_MODULE)
        set(WITH_HEADLESS ON)
 endif()
 
-TEST_SSE_SUPPORT()
+TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
 
 # don't store paths to libs for portable distrobution
 if(WITH_INSTALL_PORTABLE)
@@ -289,8 +288,8 @@ endif()
 # linux only, not cached
 set(WITH_BINRELOC OFF)
 
-# MAXOSX only, set to avoid uninitialized 
-set(EXETYPE)
+# MAXOSX only, set to avoid uninitialized
+set(EXETYPE "")
 
 # C/C++ flags
 set(PLATFORM_CFLAGS)
@@ -301,26 +300,26 @@ set(CXX_WARNINGS)
 
 # libraries to link the binary with passed to target_link_libraries()
 # known as LLIBS to scons
-set(PLATFORM_LINKLIBS)
+set(PLATFORM_LINKLIBS "")
 
 # Added to linker flags in setup_liblinks
 # - CMAKE_EXE_LINKER_FLAGS
 # - CMAKE_EXE_LINKER_FLAGS_DEBUG
-set(PLATFORM_LINKFLAGS)
-set(PLATFORM_LINKFLAGS_DEBUG)
+set(PLATFORM_LINKFLAGS "")
+set(PLATFORM_LINKFLAGS_DEBUG "")
 
 
 # disabled for now, not supported
 # option(WITH_WEBPLUGIN     "Enable Web Plugin (Unix only)" OFF)
 
 # For alternate Python locations the commandline can be used to override detected/default cache settings, e.g:
-# On Unix: 
+# On Unix:
 #   cmake ../blender \
 #         -D PYTHON_VERSION=3.2 \
 #         -D PYTHON_INCLUDE_DIR=/opt/py32/include/python3.2d \
 #         -D PYTHON_LIBRARY=/opt/py32/lib/libpython3.2d.so
 #
-# On Macs: 
+# On Macs:
 #   cmake ../blender \
 #         -D PYTHON_INCLUDE_DIR=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 \
 #         -D PYTHON_LIBPATH=/System/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/config \
@@ -332,7 +331,7 @@ set(PLATFORM_LINKFLAGS_DEBUG)
 #Platform specifics
 
 if(UNIX AND NOT APPLE)
-       
+
        # needed for ubuntu 11.04
        if(EXISTS "/usr/lib/x86_64-linux-gnu")
                set(CMAKE_LIBRARY_PATH "/usr/lib/x86_64-linux-gnu;${CMAKE_LIBRARY_PATH}")
@@ -384,10 +383,12 @@ if(UNIX AND NOT APPLE)
 
        if(WITH_SDL)
                find_package(SDL)
-               mark_as_advanced(SDLMAIN_LIBRARY)
-               mark_as_advanced(SDL_INCLUDE_DIR)
-               mark_as_advanced(SDL_LIBRARY)
-               mark_as_advanced(SDL_LIBRARY_TEMP)
+               mark_as_advanced(
+                       SDLMAIN_LIBRARY
+                       SDL_INCLUDE_DIR
+                       SDL_LIBRARY
+                       SDL_LIBRARY_TEMP
+               )
                # unset(SDLMAIN_LIBRARY CACHE)
                if(NOT SDL_FOUND)
                        set(WITH_SDL OFF)
@@ -431,11 +432,13 @@ if(UNIX AND NOT APPLE)
                        PATHS
                        /sw/lib
                )
-               mark_as_advanced(ICONV_LIBRARY)
-               mark_as_advanced(INTL_LIBRARY)
+               mark_as_advanced(
+                       ICONV_LIBRARY
+                       INTL_LIBRARY
+               )
 
                if(INTL_LIBRARY AND ICONV_LIBRARY)
-                       set(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY})
+                       set(GETTEXT_LIBRARIES ${INTL_LIBRARY} ${ICONV_LIBRARY})
                endif()
        endif()
 
@@ -446,13 +449,6 @@ if(UNIX AND NOT APPLE)
                endif()
        endif()
 
-       if(WITH_SAMPLERATE)
-               find_package(Samplerate)
-               if(NOT SAMPLERATE_FOUND)
-                       set(WITH_SAMPLERATE OFF)
-               endif()
-       endif()
-
        if(WITH_OPENCOLLADA)
                find_package(OpenCOLLADA)
                if(OPENCOLLADA_FOUND)
@@ -491,17 +487,17 @@ if(UNIX AND NOT APPLE)
                find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
                mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
 
-               list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
+               set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_X11_LIB}")
 
                if(WITH_X11_XINPUT)
-                       list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
+                       set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}")
                endif()
        endif()
 
        if(CMAKE_SYSTEM_NAME MATCHES "Linux")
                if(NOT WITH_PYTHON_MODULE)
                        # BSD's dont use libdl.so
-                       list(APPEND PLATFORM_LINKLIBS -ldl)
+               set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} -ldl")
                        # binreloc is linux only
                        set(BINRELOC_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extern/binreloc/include)
                        set(WITH_BINRELOC ON)
@@ -522,16 +518,16 @@ if(UNIX AND NOT APPLE)
        # Intel C++ Compiler
        elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
                # think these next two are broken
-               find_program(XIAR xiar) 
-               if(XIAR) 
+               find_program(XIAR xiar)
+               if(XIAR)
                        set(CMAKE_AR "${XIAR}")
-               endif() 
+               endif()
                mark_as_advanced(XIAR)
 
-               find_program(XILD xild) 
-               if(XILD) 
+               find_program(XILD xild)
+               if(XILD)
                        set(CMAKE_LINKER "${XILD}")
-               endif() 
+               endif()
                mark_as_advanced(XILD)
 
                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fp-model precise -prec_div -parallel")
@@ -554,7 +550,7 @@ elseif(WIN32)
                message("64 bit compiler detected.")
                set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
        endif()
-       
+
        add_definitions(-DWIN32)
 
        if(WITH_INTERNATIONAL)
@@ -564,13 +560,6 @@ elseif(WIN32)
                set(ICONV_LIBPATH ${ICONV}/lib)
        endif()
 
-       if(WITH_SAMPLERATE)
-               set(SAMPLERATE ${LIBDIR}/samplerate)
-               set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE}/include)
-               set(SAMPLERATE_LIBRARIES libsamplerate)
-               set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
-       endif()
-
        set(PNG "${LIBDIR}/png")
        set(PNG_INCLUDE_DIR "${PNG}/include")
        set(PNG_LIBPATH ${PNG}/lib) # not cmake defined
@@ -579,7 +568,7 @@ elseif(WIN32)
        set(JPEG_INCLUDE_DIR "${JPEG}/include")
        set(JPEG_LIBPATH ${JPEG}/lib) # not cmake defined
 
-       set(WINTAB_INC ${LIBDIR}/wintab/include) 
+       set(WINTAB_INC ${LIBDIR}/wintab/include)
 
        if(WITH_OPENAL)
                set(OPENAL ${LIBDIR}/openal)
@@ -644,9 +633,9 @@ elseif(WIN32)
 
                if(WITH_INTERNATIONAL)
                        set(GETTEXT ${LIBDIR}/gettext)
-                       set(GETTEXT_INC ${GETTEXT}/include)
+                       set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
                        set(GETTEXT_LIBPATH ${GETTEXT}/lib)
-                       set(GETTEXT_LIB gnu_gettext)
+                       set(GETTEXT_LIBRARIES gnu_gettext)
                endif()
 
                if(CMAKE_CL_64)
@@ -687,7 +676,7 @@ elseif(WIN32)
                                ${LIBDIR}/opencollada/include/COLLADABaseUtils/include
                                ${LIBDIR}/opencollada/include/COLLADAFramework/include
                                ${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
-                               ${LIBDIR}/opencollada/include/GeneratedSaxParser/include                        
+                               ${LIBDIR}/opencollada/include/GeneratedSaxParser/include
                        )
 
                        set(OPENCOLLADA_LIBRARIES
@@ -744,7 +733,7 @@ elseif(WIN32)
                        set(OPENEXR_INCUDE ${OPENEXR}/include${MSVC_INC})
                        set(OPENEXR_INCLUDE_DIRS
                                ${OPENEXR_INCUDE}
-                               ${OPENEXR_INCUDE}/IlmImf
+                               ${OPENEXR_INCUDE}/IlmImf
                                ${OPENEXR_INCUDE}/Iex
                                ${OPENEXR_INCUDE}/Imath
                        )
@@ -803,9 +792,9 @@ elseif(WIN32)
 
                if(WITH_INTERNATIONAL)
                        set(GETTEXT ${LIBDIR}/gcc/gettext)
-                       set(GETTEXT_INC ${GETTEXT}/include)
+                       set(GETTEXT_INCLUDE_DIRS ${GETTEXT}/include)
                        set(GETTEXT_LIBPATH ${GETTEXT}/lib)
-                       set(GETTEXT_LIB intl)
+                       set(GETTEXT_LIBRARIES intl)
                endif()
 
                set(JPEG_LIBRARIES libjpeg)
@@ -820,7 +809,7 @@ elseif(WIN32)
                set(PTHREADS_INCLUDE_DIRS ${PTHREADS}/include)
                set(PTHREADS_LIBPATH ${PTHREADS}/lib)
                set(PTHREADS_LIBRARIES pthreadGC2)
-               
+
                set(FREETYPE ${LIBDIR}/gcc/freetype)
                set(FREETYPE_INCLUDE_DIRS ${FREETYPE}/include ${FREETYPE}/include/freetype2)
                set(FREETYPE_LIBPATH ${FREETYPE}/lib)
@@ -840,13 +829,13 @@ elseif(WIN32)
                                ${LIBDIR}/gcc/opencollada/include/COLLADABaseUtils/include
                                ${LIBDIR}/gcc/opencollada/include/COLLADAFramework/include
                                ${LIBDIR}/gcc/opencollada/include/COLLADASaxFrameworkLoader/include
-                               ${LIBDIR}/gcc/opencollada/include/GeneratedSaxParser/include                    
+                               ${LIBDIR}/gcc/opencollada/include/GeneratedSaxParser/include
                        )
                        set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib ${OPENCOLLADA}/lib)
                        set(OPENCOLLADA_LIBRARIES OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa)
                        set(PCRE_LIBRARIES pcre)
                endif()
-               
+
                if(WITH_CODEC_FFMPEG)
                        set(FFMPEG ${LIBDIR}/ffmpeg)
                        set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include ${FFMPEG}/include)
@@ -873,7 +862,7 @@ elseif(WIN32)
                        set(JACK_INCLUDE_DIRS ${JACK}/include/jack ${JACK}/include)
                        set(JACK_LIBRARIES jack)
                        set(JACK_LIBPATH ${JACK}/lib)
-                       
+
                        # TODO, gives linking errors, force off
                        set(WITH_JACK OFF)
                endif()
@@ -911,7 +900,7 @@ elseif(APPLE)
                        set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.0.0-powerpc)
                endif()
        endif()
-       
+
 
        if(WITH_OPENAL)
                find_package(OpenAL)
@@ -955,8 +944,8 @@ elseif(APPLE)
 
        if(WITH_INTERNATIONAL)
                set(GETTEXT ${LIBDIR}/gettext)
-               set(GETTEXT_INC "${GETTEXT}/include")
-               set(GETTEXT_LIB intl iconv)
+               set(GETTEXT_INCLUDE_DIRS "${GETTEXT}/include")
+               set(GETTEXT_LIBRARIES intl iconv)
                set(GETTEXT_LIBPATH ${GETTEXT}/lib)
        endif()
 
@@ -994,16 +983,9 @@ elseif(APPLE)
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")
        endif()
 
-       if(WITH_SAMPLERATE)
-               set(SAMPLERATE ${LIBDIR}/samplerate)
-               set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE}/include)
-               set(SAMPLERATE_LIBRARIES samplerate)
-               set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
-       endif()
-
-       find_library(SYSTEMSTUBS_LIBRARY 
-               NAMES 
-               SystemStubs 
+       find_library(SYSTEMSTUBS_LIBRARY
+               NAMES
+               SystemStubs
                PATHS
        )
        mark_as_advanced(SYSTEMSTUBS_LIBRARY)
@@ -1021,13 +1003,13 @@ elseif(APPLE)
                        set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
                        if(CMAKE_OSX_ARCHITECTURES MATCHES i386)
                                set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
-                               #libSDL still needs 32bit carbon quicktime 
+                               #libSDL still needs 32bit carbon quicktime
                        endif()
                elseif(WITH_CODEC_QUICKTIME)
                        set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
                endif()
 
-               # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED! 
+               # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
                # ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL
                if(WITH_INPUT_NDOF)
                        # This thread it *should* work and check the framework - campbell
@@ -1104,11 +1086,11 @@ elseif(APPLE)
        set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
        set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -g")
        if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
-               set(CMAKE_CXX_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
-               set(CMAKE_C_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
+               set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
+               set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
        elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
-               set(CMAKE_CXX_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
-               set(CMAKE_C_FLAGS_RELEASE "-O3 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
+               set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
+               set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
        else()
                set(CMAKE_C_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
                set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
@@ -1127,31 +1109,17 @@ endif()
 # See TEST_SSE_SUPPORT() for how this is defined.
 
 if(WITH_RAYOPTIMIZATION)
-       if(CMAKE_COMPILER_IS_GNUCC)
-               set(_sse "-msse")
-               set(_sse2 "-msse2")
-       elseif(MSVC)
-               set(_sse "/arch:SSE")
-               set(_sse2 "/arch:SSE2")
-       else()
-               message(WARNING "SSE flags for this compiler not known")
-               set(_sse)
-               set(_sse2)
-       endif()
-
        if(SUPPORT_SSE_BUILD)
-               set(PLATFORM_CFLAGS " ${_sse} ${PLATFORM_CFLAGS}")
+               set(PLATFORM_CFLAGS " ${COMPILER_SSE_FLAG} ${PLATFORM_CFLAGS}")
                add_definitions(-D__SSE__ -D__MMX__)
        endif()
        if(SUPPORT_SSE2_BUILD)
-               set(PLATFORM_CFLAGS " ${_sse2} ${PLATFORM_CFLAGS}")
+               set(PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG} ${PLATFORM_CFLAGS}")
                add_definitions(-D__SSE2__)
                if(NOT SUPPORT_SSE_BUILD) # dont double up
                        add_definitions(-D__MMX__)
                endif()
        endif()
-       unset(_sse)
-       unset(_sse2)
 endif()
 
 
@@ -1187,7 +1155,7 @@ endif()
 #-----------------------------------------------------------------------------
 # Blender WebPlugin
 
-if(WITH_WEBPLUGIN) 
+if(WITH_WEBPLUGIN)
        set(GECKO_DIR "${CMAKE_SOURCE_DIR}/../gecko-sdk/" CACHE PATH "Gecko SDK path")
        set(WEBPLUGIN_SANDBOX_MODE "apparmor" CACHE STRING "WEB Plugin sandbox mode, can be apparmor, privsep, none")
 
@@ -1199,13 +1167,13 @@ endif()
 # Configure OpenGL.
 find_package(OpenGL)
 blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
-# unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake 
-# unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake 
+# unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake
+# unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake
 
 #-----------------------------------------------------------------------------
 # Configure OpenMP.
 if(WITH_OPENMP)
-       find_package(OpenMP)    
+       find_package(OpenMP)
        if(OPENMP_FOUND)
                set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
@@ -1217,9 +1185,11 @@ if(WITH_OPENMP)
                set(WITH_OPENMP OFF)
        endif()
 
-       mark_as_advanced(OpenMP_C_FLAGS)
-       mark_as_advanced(OpenMP_CXX_FLAGS)
-endif() 
+       mark_as_advanced(
+               OpenMP_C_FLAGS
+               OpenMP_CXX_FLAGS
+       )
+endif()
 
 #-----------------------------------------------------------------------------
 # Configure GLEW
@@ -1234,8 +1204,10 @@ else()
                message(FATAL_ERROR "GLEW is required to build blender, install it or use WITH_BUILTIN_GLEW")
        endif()
 
-       mark_as_advanced(GLEW_LIBRARY)
-       mark_as_advanced(GLEW_INCLUDE_PATH)
+       mark_as_advanced(
+               GLEW_LIBRARY
+               GLEW_INCLUDE_PATH
+       )
 endif()
 
 #-----------------------------------------------------------------------------
@@ -1243,7 +1215,7 @@ endif()
 
 if(WITH_PYTHON_MODULE)
        add_definitions(-DPy_ENABLE_SHARED)
-endif() 
+endif()
 
 #-----------------------------------------------------------------------------
 # Extra compile flags
@@ -1252,7 +1224,7 @@ if((NOT WIN32) AND (NOT MSVC))
        # used for internal debug checks
        set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
        set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG")
-       
+
        # assert() checks for this.
        set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
        set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -DNDEBUG")
@@ -1302,6 +1274,10 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
        ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
 
+       # disable numbered, false positives
+       set(C_WARNINGS "${C_WARNINGS} -wd188,186,144,913,556")
+       set(CXX_WARNINGS "${CXX_WARNINGS} -wd188,186,144,913,556")
+
 endif()
 
 # MSVC2010 fails to links C++ libs right
@@ -1402,8 +1378,8 @@ if(FIRST_RUN)
        macro(info_cfg_text
                _text)
                set(_config_msg "${_config_msg}\n\n  ${_text}")
-               
-               
+
+
        endmacro()
 
        info_cfg_text("Build Options:")
@@ -1441,7 +1417,6 @@ if(FIRST_RUN)
        info_cfg_option(WITH_JACK)
        info_cfg_option(WITH_CODEC_FFMPEG)
        info_cfg_option(WITH_CODEC_SNDFILE)
-       info_cfg_option(WITH_SAMPLERATE)
 
        info_cfg_text("Compression:")
        info_cfg_option(WITH_LZMA)
index 9915406..aad3c58 100644 (file)
@@ -164,7 +164,7 @@ package_archive:
 # Other Targets
 #
 translations:
-       $(BUILD_DIR)/bin/blender --background --python po/update_msg.py
+       $(BUILD_DIR)/bin/blender --background --factory-startup --python po/update_msg.py
        python3 po/update_pot.py
        python3 po/update_po.py
        python3 po/update_mo.py
index 42ee334..738466d 100644 (file)
@@ -30,6 +30,7 @@
 # Then read all SConscripts and build
 #
 # TODO: fix /FORCE:MULTIPLE on windows to get proper debug builds.
+# TODO: cleanup CCFLAGS / CPPFLAGS use, often both are set when we only need one.
 
 import platform as pltfrm
 
@@ -277,32 +278,27 @@ if env['OURPLATFORM']=='darwin':
             print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
             env['WITH_BF_3DMOUSE'] = 0
         else:
-            env.Append(LINKFLAGS=['-weak_framework','3DconnexionClient'])
+            env.Append(LINKFLAGS=['-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
 
 if env['WITH_BF_OPENMP'] == 1:
         if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
                 env['CCFLAGS'].append('/openmp')
                 env['CPPFLAGS'].append('/openmp')
-                env['CXXFLAGS'].append('/openmp')
         else:
             if env['CC'].endswith('icc'): # to be able to handle CC=/opt/bla/icc case
                 env.Append(LINKFLAGS=['-openmp', '-static-intel'])
                 env['CCFLAGS'].append('-openmp')
                 env['CPPFLAGS'].append('-openmp')
-                env['CXXFLAGS'].append('-openmp')
             else:
                 env.Append(CCFLAGS=['-fopenmp']) 
                 env.Append(CPPFLAGS=['-fopenmp'])
-                env.Append(CXXFLAGS=['-fopenmp'])
 
 if env['WITH_GHOST_COCOA'] == True:
     env.Append(CFLAGS=['-DGHOST_COCOA']) 
-    env.Append(CXXFLAGS=['-DGHOST_COCOA'])
     env.Append(CPPFLAGS=['-DGHOST_COCOA'])
     
 if env['USE_QTKIT'] == True:
-    env.Append(CFLAGS=['-DUSE_QTKIT']) 
-    env.Append(CXXFLAGS=['-DUSE_QTKIT'])
+    env.Append(CFLAGS=['-DUSE_QTKIT'])
     env.Append(CPPFLAGS=['-DUSE_QTKIT'])
 
 #check for additional debug libnames
@@ -334,23 +330,19 @@ if 'blendernogame' in B.targets:
 # disable elbeem (fluidsim) compilation?
 if env['BF_NO_ELBEEM'] == 1:
     env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
-    env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
     env['CCFLAGS'].append('-DDISABLE_ELBEEM')
 
 
 if btools.ENDIAN == "big":
     env['CPPFLAGS'].append('-D__BIG_ENDIAN__')
-    env['CXXFLAGS'].append('-D__BIG_ENDIAN__')
     env['CCFLAGS'].append('-D__BIG_ENDIAN__')
 else:
     env['CPPFLAGS'].append('-D__LITTLE_ENDIAN__')
-    env['CXXFLAGS'].append('-D__LITTLE_ENDIAN__')
     env['CCFLAGS'].append('-D__LITTLE_ENDIAN__')       
 
 
 # TODO, make optional
 env['CPPFLAGS'].append('-DWITH_AUDASPACE')
-env['CXXFLAGS'].append('-DWITH_AUDASPACE')
 env['CCFLAGS'].append('-DWITH_AUDASPACE')
 
 # lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
@@ -523,7 +515,7 @@ if env['OURPLATFORM']!='darwin':
             
             for f in df:
                 # This files aren't used anymore
-                if f in ['.Blanguages', '.bfont.ttf']:
+                if f in (".bfont.ttf", ):
                     continue
 
                 if not env['WITH_BF_INTERNATIONAL']:
index facbf49..f2197a0 100644 (file)
@@ -58,8 +58,6 @@ WITH_BF_PNG = True
 BF_PNG_LIB = 'libpng'
 BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
 
-WITH_BF_STATICLIBSAMPLERATE = True
-
 WITH_BF_ZLIB = True
 WITH_BF_STATICZLIB = True
 BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
@@ -91,6 +89,9 @@ BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
 WITH_BF_FFTW3 = True
 WITH_BF_STATICFFTW3 = True
 
+# JACK
+WITH_BF_JACK = True
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index d02779e..99671ec 100644 (file)
@@ -52,8 +52,6 @@ WITH_BF_PNG = True
 BF_PNG_LIB = 'libpng'
 BF_PNG_LIBPATH = '/home/sources/staticlibs/lib32'
 
-WITH_BF_STATICLIBSAMPLERATE = True
-
 WITH_BF_ZLIB = True
 WITH_BF_STATICZLIB = True
 BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
@@ -82,6 +80,9 @@ WITH_BF_STATIC3DMOUSE = True
 BF_3DMOUSE = '/home/sources/staticlibs/spnav'
 BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
 
+# JACK
+WITH_BF_JACK = True
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 810dcb8..a1ca388 100644 (file)
@@ -52,8 +52,6 @@ WITH_BF_PNG = True
 BF_PNG_LIB = 'libpng'
 BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
 
-WITH_BF_STATICLIBSAMPLERATE = True
-
 WITH_BF_ZLIB = True
 WITH_BF_STATICZLIB = True
 BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
@@ -82,6 +80,9 @@ WITH_BF_STATIC3DMOUSE = True
 BF_3DMOUSE = '/home/sources/staticlibs/spnav'
 BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
 
+# JACK
+WITH_BF_JACK = True
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 536f8f9..93fe3ca 100644 (file)
@@ -58,8 +58,6 @@ WITH_BF_PNG = True
 BF_PNG_LIB = 'libpng'
 BF_PNG_LIBPATH = '/home/sources/staticlibs/lib64'
 
-WITH_BF_STATICLIBSAMPLERATE = True
-
 WITH_BF_ZLIB = True
 WITH_BF_STATICZLIB = True
 BF_ZLIB_LIB_STATIC = '${BF_ZLIB}/lib/libz.a'
@@ -91,6 +89,9 @@ BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
 WITH_BF_FFTW3 = True
 WITH_BF_STATICFFTW3 = True
 
+# JACK
+WITH_BF_JACK = True
+
 # Compilation and optimization
 BF_DEBUG = False
 REL_CFLAGS = ['-O2']
index 882f1e2..fd5d209 100644 (file)
@@ -34,67 +34,71 @@ IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
   SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
 ENDIF()
 
-IF(DEFINED PYTHON_VERSION)
-  SET(PYTHON_VERSION "${PYTHON_VERSION}" CACHE STRING "")
-ELSE()
-  SET(PYTHON_VERSION 3.2 CACHE STRING "")
-ENDIF()
+SET(PYTHON_VERSION 3.2 CACHE STRING "Python Version (major and minor only)")
 MARK_AS_ADVANCED(PYTHON_VERSION)
 
-SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
+
+# See: http://docs.python.org/extending/embedding.html#linking-requirements
+#      for why this is needed
+SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for python")
 MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
 
-SET(_python_ABI_FLAGS
-  "m;mu;u; "  # release
-  "md;mud;ud;d" # debug
-)
-
-STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
-
-SET(_python_SEARCH_DIRS
-  ${PYTHON_ROOT_DIR}
-  "$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
-  "/opt/py${_PYTHON_VERSION_NO_DOTS}"
-)
-
-FOREACH(_CURRENT_ABI_FLAGS ${_python_ABI_FLAGS})
-  #IF(CMAKE_BUILD_TYPE STREQUAL Debug)
-  #  SET(_CURRENT_ABI_FLAGS "d${_CURRENT_ABI_FLAGS}")
-  #ENDIF()
-  STRING(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
-
-  FIND_PATH(PYTHON_INCLUDE_DIR
-    NAMES
-      Python.h
-    HINTS
-      ${_python_SEARCH_DIRS}
-    PATH_SUFFIXES
-      include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
-  )
 
-  FIND_LIBRARY(PYTHON_LIBRARY
-    NAMES
-      "python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}"
-    HINTS
-      ${_python_SEARCH_DIRS}
-    PATH_SUFFIXES
-      lib64 lib
+# only search for the dirs if we havn't already
+IF((NOT DEFINED PYTHON_INCLUDE_DIR) OR (NOT DEFINED PYTHON_LIBRARY))
+
+  SET(_python_ABI_FLAGS
+    "m;mu;u; "    # release
+    "md;mud;ud;d" # debug
   )
 
-  IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR)
-    break()
-  ELSE()
-    # ensure we dont find values from 2 different ABI versions
-    UNSET(PYTHON_INCLUDE_DIR CACHE)
-    UNSET(PYTHON_LIBRARY CACHE)
-  ENDIF()
-ENDFOREACH()
+  STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
 
-UNSET(_CURRENT_ABI_FLAGS)
-UNSET(_CURRENT_PATH)
+  SET(_python_SEARCH_DIRS
+    ${PYTHON_ROOT_DIR}
+    "$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
+    "/opt/py${_PYTHON_VERSION_NO_DOTS}"
+  )
 
-UNSET(_python_ABI_FLAGS)
-UNSET(_python_SEARCH_DIRS)
+  FOREACH(_CURRENT_ABI_FLAGS ${_python_ABI_FLAGS})
+    #IF(CMAKE_BUILD_TYPE STREQUAL Debug)
+    #  SET(_CURRENT_ABI_FLAGS "d${_CURRENT_ABI_FLAGS}")
+    #ENDIF()
+    STRING(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
+
+    FIND_PATH(PYTHON_INCLUDE_DIR
+      NAMES
+        Python.h
+      HINTS
+        ${_python_SEARCH_DIRS}
+      PATH_SUFFIXES
+        include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
+    )
+
+    FIND_LIBRARY(PYTHON_LIBRARY
+      NAMES
+        "python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}"
+      HINTS
+        ${_python_SEARCH_DIRS}
+      PATH_SUFFIXES
+        lib64 lib
+    )
+
+    IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR)
+      break()
+    ELSE()
+      # ensure we dont find values from 2 different ABI versions
+      UNSET(PYTHON_INCLUDE_DIR CACHE)
+      UNSET(PYTHON_LIBRARY CACHE)
+    ENDIF()
+  ENDFOREACH()
+
+  UNSET(_CURRENT_ABI_FLAGS)
+  UNSET(_CURRENT_PATH)
+
+  UNSET(_python_ABI_FLAGS)
+  UNSET(_python_SEARCH_DIRS)
+ENDIF()
 
 # handle the QUIETLY and REQUIRED arguments and SET PYTHONLIBSUNIX_FOUND to TRUE IF 
 # all listed variables are TRUE
diff --git a/build_files/cmake/Modules/FindSamplerate.cmake b/build_files/cmake/Modules/FindSamplerate.cmake
deleted file mode 100644 (file)
index ea7a0d7..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# - Find Samplerate library
-# Find the native Samplerate includes and library
-# This module defines
-#  SAMPLERATE_INCLUDE_DIRS, where to find samplerate.h, Set when
-#                        SAMPLERATE_INCLUDE_DIR is found.
-#  SAMPLERATE_LIBRARIES, libraries to link against to use Samplerate.
-#  SAMPLERATE_ROOT_DIR, The base directory to search for Samplerate.
-#                    This can also be an environment variable.
-#  SAMPLERATE_FOUND, If false, do not try to use Samplerate.
-#
-# also defined, but not for general use are
-#  SAMPLERATE_LIBRARY, where to find the Samplerate library.
-
-#=============================================================================
-# Copyright 2011 Blender Foundation.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-
-# If SAMPLERATE_ROOT_DIR was defined in the environment, use it.
-IF(NOT SAMPLERATE_ROOT_DIR AND NOT $ENV{SAMPLERATE_ROOT_DIR} STREQUAL "")
-  SET(SAMPLERATE_ROOT_DIR $ENV{SAMPLERATE_ROOT_DIR})
-ENDIF()
-
-SET(_samplerate_SEARCH_DIRS
-  ${SAMPLERATE_ROOT_DIR}
-  /usr/local
-  /sw # Fink
-  /opt/local # DarwinPorts
-  /opt/csw # Blastwave
-)
-
-FIND_PATH(SAMPLERATE_INCLUDE_DIR
-  NAMES
-    samplerate.h
-  HINTS
-    ${_samplerate_SEARCH_DIRS}
-  PATH_SUFFIXES
-    include
-)
-
-FIND_LIBRARY(SAMPLERATE_LIBRARY
-  NAMES
-    samplerate
-  HINTS
-    ${_samplerate_SEARCH_DIRS}
-  PATH_SUFFIXES
-    lib64 lib
-  )
-
-# handle the QUIETLY and REQUIRED arguments and set SAMPLERATE_FOUND to TRUE if 
-# all listed variables are TRUE
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Samplerate DEFAULT_MSG
-    SAMPLERATE_LIBRARY SAMPLERATE_INCLUDE_DIR)
-
-IF(SAMPLERATE_FOUND)
-  SET(SAMPLERATE_LIBRARIES ${SAMPLERATE_LIBRARY})
-  SET(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE_INCLUDE_DIR})
-ENDIF(SAMPLERATE_FOUND)
-
-MARK_AS_ADVANCED(
-  SAMPLERATE_INCLUDE_DIR
-  SAMPLERATE_LIBRARY
-)
index bd69eed..c4d6412 100644 (file)
@@ -11,7 +11,6 @@ set(WITH_GAMEENGINE          OFF CACHE FORCE BOOL)
 # disable audio, its possible some devs may want this but for now disable
 # so the python module doesnt hold the audio device and loads quickly.
 set(WITH_AUDASPACE           OFF CACHE FORCE BOOL)
-set(WITH_SAMPLERATE          OFF CACHE FORCE BOOL)
 set(WITH_FFTW3               OFF CACHE FORCE BOOL)
 set(WITH_JACK                OFF CACHE FORCE BOOL)
 set(WITH_SDL                 OFF CACHE FORCE BOOL)
index f09a805..6791028 100644 (file)
@@ -38,6 +38,5 @@ set(WITH_OPENCOLLADA         OFF CACHE FORCE BOOL)
 set(WITH_OPENMP              OFF CACHE FORCE BOOL)
 set(WITH_PYTHON_INSTALL      OFF CACHE FORCE BOOL)
 set(WITH_RAYOPTIMIZATION     OFF CACHE FORCE BOOL)
-set(WITH_SAMPLERATE          OFF CACHE FORCE BOOL)
 set(WITH_SDL                 OFF CACHE FORCE BOOL)
 set(WITH_X11_XINPUT          OFF CACHE FORCE BOOL)
index 5392705..6279f06 100644 (file)
@@ -18,7 +18,6 @@ set(WITH_GAMEENGINE          OFF CACHE FORCE BOOL)
 # disable audio, its possible some devs may want this but for now disable
 # so the python module doesnt hold the audio device and loads quickly.
 set(WITH_AUDASPACE           OFF CACHE FORCE BOOL)
-set(WITH_SAMPLERATE          OFF CACHE FORCE BOOL)
 set(WITH_FFTW3               OFF CACHE FORCE BOOL)
 set(WITH_JACK                OFF CACHE FORCE BOOL)
 set(WITH_SDL                 OFF CACHE FORCE BOOL)
index ef4edca..e466512 100644 (file)
@@ -181,9 +181,6 @@ macro(SETUP_LIBDIRS)
        if(WITH_CODEC_SNDFILE)
                link_directories(${SNDFILE_LIBPATH})
        endif()
-       if(WITH_SAMPLERATE)
-               link_directories(${SAMPLERATE_LIBPATH})
-       endif()
        if(WITH_FFTW3)
                link_directories(${FFTW3_LIBPATH})
        endif()
@@ -213,6 +210,7 @@ macro(setup_liblinks
                        ${JPEG_LIBRARIES}
                        ${PNG_LIBRARIES}
                        ${ZLIB_LIBRARIES}
+                       ${FREETYPE_LIBRARY}
                        ${PLATFORM_LINKLIBS})
 
        # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
@@ -233,15 +231,8 @@ macro(setup_liblinks
                target_link_libraries(${target} ${GLEW_LIBRARY})
        endif()
 
-       target_link_libraries(${target}
-                       ${OPENGL_glu_LIBRARY}
-                       ${JPEG_LIBRARIES}
-                       ${PNG_LIBRARIES}
-                       ${ZLIB_LIBRARIES}
-                       ${FREETYPE_LIBRARY})
-
        if(WITH_INTERNATIONAL)
-               target_link_libraries(${target} ${GETTEXT_LIB})
+               target_link_libraries(${target} ${GETTEXT_LIBRARIES})
 
                if(WIN32 AND NOT UNIX)
                        target_link_libraries(${target} ${ICONV_LIBRARIES})
@@ -260,9 +251,6 @@ macro(setup_liblinks
        if(WITH_CODEC_SNDFILE)
                target_link_libraries(${target} ${SNDFILE_LIBRARIES})
        endif()
-       if(WITH_SAMPLERATE)
-               target_link_libraries(${target} ${SAMPLERATE_LIBRARIES})
-       endif()
        if(WITH_SDL)
                target_link_libraries(${target} ${SDL_LIBRARY})
        endif()
@@ -286,6 +274,11 @@ macro(setup_liblinks
                target_link_libraries(${target} ${OPENJPEG_LIBRARIES})
        endif()
        if(WITH_CODEC_FFMPEG)
+
+               # Strange!, without this ffmpeg gives linking errors (on linux)
+               # even though its linked above
+               target_link_libraries(${target} ${OPENGL_glu_LIBRARY})
+
                target_link_libraries(${target} ${FFMPEG_LIBRARIES})
        endif()
        if(WITH_OPENCOLLADA)
@@ -326,44 +319,59 @@ macro(setup_liblinks
        endif()
 endmacro()
 
-macro(TEST_SSE_SUPPORT)
+macro(TEST_SSE_SUPPORT
+       _sse_flags
+       _sse2_flags)
+
        include(CheckCSourceRuns)
 
        # message(STATUS "Detecting SSE support")
-       if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
-               set(CMAKE_REQUIRED_FLAGS "-msse -msse2")
+       if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
+               set(${_sse_flags} "-msse")
+               set(${_sse2_flags} "-msse2")
        elseif(MSVC)
-               set(CMAKE_REQUIRED_FLAGS "/arch:SSE2") # TODO, SSE 1 ?
+               set(${_sse_flags} "/arch:SSE")
+               set(${_sse2_flags} "/arch:SSE2")
+       elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
+               set(${_sse_flags} "")  # icc defaults to -msse
+               set(${_sse2_flags} "-msse2")
+       else()
+               message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known")
+               set(${_sse_flags})
+               set(${_sse2_flags})
        endif()
 
-       if(NOT DEFINED ${SUPPORT_SSE_BUILD})
+       set(CMAKE_REQUIRED_FLAGS "${${_sse_flags}} ${${_sse2_flags}}")
+
+       if(NOT DEFINED SUPPORT_SSE_BUILD)
+               # result cached
                check_c_source_runs("
                        #include <xmmintrin.h>
-                       int main() { __m128 v = _mm_setzero_ps(); return 0; }"
+                       int main(void) { __m128 v = _mm_setzero_ps(); return 0; }"
                SUPPORT_SSE_BUILD)
-               
+
                if(SUPPORT_SSE_BUILD)
                        message(STATUS "SSE Support: detected.")
                else()
                        message(STATUS "SSE Support: missing.")
                endif()
-               set(${SUPPORT_SSE_BUILD} ${SUPPORT_SSE_BUILD} CACHE INTERNAL "SSE Test")
-       endif() 
+       endif()
 
-       if(NOT DEFINED ${SUPPORT_SSE2_BUILD})
+       if(NOT DEFINED SUPPORT_SSE2_BUILD)
+               # result cached
                check_c_source_runs("
                        #include <emmintrin.h>
-                       int main() { __m128d v = _mm_setzero_pd(); return 0; }"
+                       int main(void) { __m128d v = _mm_setzero_pd(); return 0; }"
                SUPPORT_SSE2_BUILD)
 
                if(SUPPORT_SSE2_BUILD)
                        message(STATUS "SSE2 Support: detected.")
                else()
                        message(STATUS "SSE2 Support: missing.")
-               endif() 
-               set(${SUPPORT_SSE2_BUILD} ${SUPPORT_SSE2_BUILD} CACHE INTERNAL "SSE2 Test")
+               endif()
        endif()
 
+       unset(CMAKE_REQUIRED_FLAGS)
 endmacro()
 
 # when we have warnings as errors applied globally this
@@ -499,7 +507,7 @@ endmacro()
 
 
 # hacks to override initial project settings
-# these macros must be called directly before/after project(Blender) 
+# these macros must be called directly before/after project(Blender)
 macro(blender_project_hack_pre)
        # ----------------
        # MINGW HACK START
@@ -541,8 +549,10 @@ macro(blender_project_hack_post)
                # have libs we define and that cmake & scons builds match.
                set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
                set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE)
-               mark_as_advanced(CMAKE_C_STANDARD_LIBRARIES)
-               mark_as_advanced(CMAKE_CXX_STANDARD_LIBRARIES)
+               mark_as_advanced(
+                       CMAKE_C_STANDARD_LIBRARIES
+                       CMAKE_CXX_STANDARD_LIBRARIES
+               )
        endif()
        unset(_reset_standard_libraries)
 
index be703e0..addd717 100644 (file)
@@ -2,7 +2,7 @@ Source: blender
 Section: graphics
 Priority: extra
 Maintainer: Dan Eicher <dan@trollwerks.org>
-Build-Depends: debhelper (>= 7.0.50~), cmake, python3, python, libfreetype6-dev, libglu1-mesa-dev, libilmbase-dev, libopenexr-dev, libjpeg62-dev, libopenal-dev, libpng12-dev, libsamplerate0-dev, libsdl-dev, libtiff4-dev, libx11-dev, libxi-dev, zlib1g-dev, python3.2-dev, libopenjpeg-dev
+Build-Depends: debhelper (>= 7.0.50~), cmake, python3, python, libfreetype6-dev, libglu1-mesa-dev, libilmbase-dev, libopenexr-dev, libjpeg62-dev, libopenal-dev, libpng12-dev, libsdl-dev, libtiff4-dev, libx11-dev, libxi-dev, zlib1g-dev, python3.2-dev, libopenjpeg-dev
 Standards-Version: 3.9.1
 Homepage: http://blender.org/
 X-Python3-Version: >= 3.2, << 3.3
index 0c4164b..e59d1cf 100644 (file)
@@ -4,7 +4,7 @@
 blender_srcdir=$(dirname $startdir)"/../.."
 # value may be formatted: 35042:35051M
 blender_revision=$(svnversion $blender_srcdir | cut -d: -f2 | awk '{print $3}')
-blender_version=$(grep BLENDER_VERSION $blender_srcdir/source/blender/blenkernel/BKE_blender.h | awk '{print $3}')
+blender_version=$(grep "BLENDER_VERSION\s" $blender_srcdir/source/blender/blenkernel/BKE_blender.h | awk '{print $3}')
 blender_version=$(expr $blender_version / 100).$(expr $blender_version % 100)  # 256 -> 2.56
 blender_version_char=$(sed -ne 's/.*BLENDER_VERSION_CHAR.*\([a-z]\)$/\1/p' $blender_srcdir/source/blender/blenkernel/BKE_blender.h)
 # blender_subversion=$(grep BLENDER_SUBVERSION $blender_srcdir/source/blender/blenkernel/BKE_blender.h | awk '{print $3}')
@@ -12,10 +12,12 @@ blender_version_char=$(sed -ne 's/.*BLENDER_VERSION_CHAR.*\([a-z]\)$/\1/p' $blen
 # map the version a -> 1
 # not to be confused with blender's internal subversions
 if [ "$blender_version_char" ]; then
-    blender_version=${blender_version}.$(expr index abcdefghijklmnopqrstuvwxyz $blender_version_char)
+    blender_version_full=${blender_version}.$(expr index abcdefghijklmnopqrstuvwxyz $blender_version_char)
+else
+       blender_version_full=${blender_version}
 fi
 
-blender_ver_string=$blender_version+svn$blender_revision
+blender_ver_string=$blender_version+svn$blender_version_full
 
 pkgname=blender-snapshot
 pkgver=$blender_ver_string
@@ -25,7 +27,7 @@ arch=('i686' 'x86_64')
 url="www.blender.org"
 license=('GPL')
 groups=()
-depends=('libjpeg' 'libpng' 'openjpeg' 'libtiff' 'openexr'  'python>=3.2' 'gettext' 'libxi' 'libxmu' 'mesa' 'freetype2' 'openal' 'sdl' 'libsndfile' 'libsamplerate' 'ffmpeg')
+depends=('libjpeg' 'libpng' 'openjpeg' 'libtiff' 'openexr'  'python>=3.2' 'gettext' 'libxi' 'libxmu' 'mesa' 'freetype2' 'openal' 'sdl' 'libsndfile' 'ffmpeg')
 makedepends=('cmake' 'svn')
 optdepends=()
 provides=()
@@ -61,5 +63,8 @@ build() {
 package() {
   cd $srcdir/build
   make DESTDIR="$pkgdir" install
-  python -m compileall $pkgdir/usr/share/blender
+  python -m compileall \
+       $pkgdir/usr/share/blender/$blender_version/scripts/startup \
+       $pkgdir/usr/share/blender/$blender_version/scripts/modules \
+       $pkgdir/usr/share/blender/$blender_version/scripts/addons
 }
index 29d2b39..0c13204 100644 (file)
@@ -90,9 +90,10 @@ LIBDIR = '${LCGDIR}'
 ###################          Dependency settings           ##################
 #############################################################################
 
-#Defaults openMP to true if compiler handles it
-if CC == 'gcc-4.2' or CC == 'llvm-gcc-4.2':
-    WITH_BF_OPENMP = True  # multithreading for fluids, cloth and smoke
+#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
+# if your compiler does not have accurate suffix you may have to enable it by hand !
+if CC.endswith('4.6.1'):
+    WITH_BF_OPENMP = True  # multithreading for fluids, cloth, sculpt and smoke
 else:
     WITH_BF_OPENMP = False
 
@@ -147,11 +148,6 @@ BF_CXX = '/usr'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 # TODO - set proper paths here (add precompiled to lib/ ? )
 WITH_BF_JACK = False
 BF_JACK = '/usr'
index a73574a..fec7531 100644 (file)
@@ -25,11 +25,6 @@ BF_CXX = '/usr/local'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = '/usr/local'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_JACK = True
 BF_JACK = '/usr/local'
 BF_JACK_INC = '${BF_JACK}/include/jack'
index dd7ab5f..eea89bf 100644 (file)
@@ -25,11 +25,6 @@ BF_CXX = '/usr/local'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = '/usr/local'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_JACK = True
 BF_JACK = '/usr/local'
 BF_JACK_INC = '${BF_JACK}/include/jack'
index 9c53d52..a63da6e 100644 (file)
@@ -25,11 +25,6 @@ BF_CXX = '/usr/local'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = '/usr/local'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_JACK = True
 BF_JACK = '/usr/local'
 BF_JACK_INC = '${BF_JACK}/include/jack'
index c6613ec..a26748c 100644 (file)
@@ -23,13 +23,6 @@ BF_CXX = '/usr'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = '/usr'
-WITH_BF_STATICLIBSAMPLERATE = False
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-BF_LIBSAMPLERATE_LIB_STATIC = '${BF_LIBSAMPLERATE}/lib/libsamplerate.a'
-
 WITH_BF_JACK = False
 BF_JACK = '/usr'
 BF_JACK_INC = '${BF_JACK}/include/jack'
index 8057d47..070e18a 100644 (file)
@@ -23,11 +23,6 @@ BF_CXX = '/usr'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_SDL = True
 BF_SDL = LIBDIR + '/sdl'
 BF_SDL_INC = '${BF_SDL}/include'
index 67d850f..83c515d 100644 (file)
@@ -16,11 +16,6 @@ WITH_BF_OPENAL = False
 #BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
 #BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
 
-BF_LIBSAMPLERATE = '/usr/local'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_SDL = True
 BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
 BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
index 828e286..0cf78c9 100644 (file)
@@ -22,11 +22,6 @@ BF_CXX = '/usr'
 WITH_BF_STATICCXX = False
 BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
 
-BF_LIBSAMPLERATE = '/usr/local'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'samplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_SDL = True
 BF_SDL = '/usr/local' #$(shell sdl-config --prefix)
 BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
index 37d693d..167ed50 100644 (file)
@@ -23,11 +23,6 @@ BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
 BF_FFMPEG_INC =  LIBDIR + '/ffmpeg/include'
 BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
 
-BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'libsamplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_JACK = False
 BF_JACK = LIBDIR + '/jack'
 BF_JACK_INC = '${BF_JACK}/include'
index 2950ca9..9604eb5 100644 (file)
@@ -29,11 +29,6 @@ BF_ICONV_INC = '${BF_ICONV}/include'
 BF_ICONV_LIB = 'iconv'
 BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
 
-BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'libsamplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_JACK = False
 BF_JACK = LIBDIR + '/jack'
 BF_JACK_INC = '${BF_JACK}/include ${BF_FFMPEG}/include/msvc'
@@ -152,6 +147,8 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
 
 WITH_BF_3DMOUSE = True
 
+WITH_BF_OPENMP = True
+
 #Ray trace optimization
 WITH_BF_RAYOPTIMIZATION = True
 BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
index 280ba3d..049b7eb 100644 (file)
@@ -17,7 +17,7 @@ BF_PYTHON_LIB = 'python32'
 BF_PYTHON_DLL = '${BF_PYTHON_LIB}'
 BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
 
-WITH_BF_OPENAL = False 
+WITH_BF_OPENAL = True
 BF_OPENAL = LIBDIR + '/openal'
 BF_OPENAL_INC = '${BF_OPENAL}/include '
 BF_OPENAL_LIB = 'wrap_oal'
@@ -40,11 +40,6 @@ BF_ICONV_INC = '${BF_ICONV}/include'
 BF_ICONV_LIB = 'iconv'
 BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
 
-BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
-BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
-BF_LIBSAMPLERATE_LIB = 'libsamplerate'
-BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
-
 WITH_BF_SDL = True
 BF_SDL = LIBDIR + '/sdl'
 BF_SDL_INC = '${BF_SDL}/include'
@@ -156,6 +151,8 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
 
 WITH_BF_3DMOUSE = True
 
+WITH_BF_OPENMP = True
+
 #Ray trace optimization
 WITH_BF_RAYOPTIMIZATION = True
 BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
index 34b245c..0b7a2c4 100644 (file)
@@ -131,7 +131,6 @@ def setup_staticlibs(lenv):
         lenv['BF_JPEG_LIBPATH'],
         lenv['BF_ZLIB_LIBPATH'],
         lenv['BF_PNG_LIBPATH'],
-        lenv['BF_LIBSAMPLERATE_LIBPATH'],
         lenv['BF_ICONV_LIBPATH']
         ])
 
@@ -194,9 +193,6 @@ def setup_staticlibs(lenv):
         if lenv['OURPLATFORM'] == 'linuxcross':
             libincs += Split(lenv['BF_OPENMP_LIBPATH'])
 
-    if lenv['WITH_BF_STATICLIBSAMPLERATE']:
-        statlibs += Split(lenv['BF_LIBSAMPLERATE_LIB_STATIC'])
-
     # setting this last so any overriding of manually libs could be handled
     if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
         libincs.append('/usr/lib')
@@ -270,9 +266,6 @@ def setup_syslibs(lenv):
             syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
         syslibs.append(lenv['BF_EXPAT_LIB'])
 
-    if not lenv['WITH_BF_STATICLIBSAMPLERATE']:
-        syslibs += Split(lenv['BF_LIBSAMPLERATE_LIB'])
-
     if lenv['WITH_BF_JEMALLOC']:
         if not lenv['WITH_BF_STATICJEMALLOC']:
             syslibs += Split(lenv['BF_JEMALLOC_LIB'])
@@ -576,8 +569,6 @@ def AppIt(target=None, source=None, env=None):
         commands.getoutput(cmd)
         cmd = 'cp -R %s/release/bin/.blender/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
         commands.getoutput(cmd)
-        cmd = 'cp %s/release/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
-        commands.getoutput(cmd)
         cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
         commands.getoutput(cmd)
 
@@ -638,7 +629,11 @@ def UnixPyBundle(target=None, source=None, env=None):
     run("rm -rf '%s/distutils'" % py_target)
     run("rm -rf '%s/lib2to3'" % py_target)
     run("rm -rf '%s/config'" % py_target)
-    run("rm -rf '%s/config-*'" % py_target)
+
+    for f in os.listdir(py_target):
+        if f.startswith("config-"):
+            run("rm -rf '%s/%s'" % (py_target, f))
+
     run("rm -rf '%s/site-packages'" % py_target)
     run("mkdir '%s/site-packages'" % py_target)    # python needs it.'
     run("rm -rf '%s/idlelib'" % py_target)
index 854a21c..add67ea 100644 (file)
@@ -99,7 +99,6 @@ def validate_arguments(args, bc):
             'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'WITH_OSX_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS', 
             'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
             'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
-            'BF_LIBSAMPLERATE', 'BF_LIBSAMPLERATE_INC', 'BF_LIBSAMPLERATE_LIB', 'BF_LIBSAMPLERATE_LIBPATH', 'WITH_BF_STATICLIBSAMPLERATE', 'BF_LIBSAMPLERATE_LIB_STATIC',
             'WITH_BF_JACK', 'BF_JACK', 'BF_JACK_INC', 'BF_JACK_LIB', 'BF_JACK_LIBPATH',
             'WITH_BF_SNDFILE', 'BF_SNDFILE', 'BF_SNDFILE_INC', 'BF_SNDFILE_LIB', 'BF_SNDFILE_LIBPATH', 'WITH_BF_STATICSNDFILE', 'BF_SNDFILE_LIB_STATIC',
             'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
@@ -267,13 +266,6 @@ def read_opts(env, cfg, args):
         ('BF_SDL_LIB', 'SDL library', ''),
         ('BF_SDL_LIBPATH', 'SDL library path', ''),
 
-        ('BF_LIBSAMPLERATE', 'libsamplerate aka SRC base path', ''),
-        ('BF_LIBSAMPLERATE_INC', 'libsamplerate aka SRC include path', ''),
-        ('BF_LIBSAMPLERATE_LIB', 'libsamplerate aka SRC library', ''),
-        ('BF_LIBSAMPLERATE_LIBPATH', 'libsamplerate aka SRC library path', ''),
-        ('BF_LIBSAMPLERATE_LIB_STATIC', 'Path to libsamplerate static library', ''),
-        (BoolVariable('WITH_BF_STATICLIBSAMPLERATE', 'Staticly link to libsamplerate', False)),
-
         (BoolVariable('WITH_BF_JACK', 'Enable jack support if true', True)),
         ('BF_JACK', 'jack base path', ''),
         ('BF_JACK_INC', 'jack include path', ''),
index e41e821..2c74d6a 100644 (file)
@@ -11,10 +11,10 @@ device = aud.device()
 factory = aud.Factory('music.ogg')
 
 # play the audio, this return a handle to control play/pause
-handle = device.play(sound)
+handle = device.play(factory)
 # if the audio is not too big and will be used often you can buffer it
-factory_buffered = aud.Factory.buffer(sound)
-handle_buffered = device.play(buffered)
+factory_buffered = aud.Factory.buffer(factory)
+handle_buffered = device.play(factory_buffered)
 
 # stop the sounds (otherwise they play until their ends)
 handle.stop()
index b9c154b..d332c4f 100644 (file)
@@ -909,6 +909,181 @@ Added
 
 * :class:`bpy.types.SceneGameData.use_glsl_color_management`
 
+
+2.58 to 2.59
+============
+
+bpy.types.Scene
+---------------
+
+Function Arguments
+^^^^^^^^^^^^^^^^^^
+
+* :class:`bpy.types.Scene.collada_export` (filepath, selected), *was (filepath)*
+
+bpy.types.MultiresModifier
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.MultiresModifier.use_subsurf_uv`
+
+bpy.types.KeyMap
+----------------
+
+Removed
+^^^^^^^
+
+* **copy_to_user**
+
+Renamed
+^^^^^^^
+
+* **is_user_defined** -> :class:`bpy.types.KeyMap.is_user_modified`
+
+bpy.types.SceneRenderLayer
+--------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.SceneRenderLayer.use_pass_material_index`
+
+bpy.types.ToolSettings
+----------------------
+
+Renamed
+^^^^^^^
+
+* **use_snap_project_self** -> :class:`bpy.types.ToolSettings.use_snap_self`
+
+bpy.types.UserPreferencesInput
+------------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.UserPreferencesInput.ndof_fly_helicopter`
+* :class:`bpy.types.UserPreferencesInput.ndof_lock_horizon`
+* :class:`bpy.types.UserPreferencesInput.ndof_orbit_invert_axes`
+* :class:`bpy.types.UserPreferencesInput.ndof_sensitivity`
+* :class:`bpy.types.UserPreferencesInput.ndof_show_guide`
+* :class:`bpy.types.UserPreferencesInput.ndof_zoom_invert`
+* :class:`bpy.types.UserPreferencesInput.ndof_zoom_updown`
+
+Removed
+^^^^^^^
+
+* **edited_keymaps**
+* **ndof_pan_speed**
+* **ndof_rotate_speed**
+
+bpy.types.IDMaterials
+---------------------
+
+Function Arguments
+^^^^^^^^^^^^^^^^^^
+
+* :class:`bpy.types.IDMaterials.pop` (index, update_data), *was (index)*
+
+bpy.types.Material
+------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Material.pass_index`
+
+bpy.types.RenderLayer
+---------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.RenderLayer.use_pass_material_index`
+
+bpy.types.Object
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Object.closest_point_on_mesh`
+
+bpy.types.ThemeNodeEditor
+-------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ThemeNodeEditor.noodle_curving`
+
+bpy.types.ChildOfConstraint
+---------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.ChildOfConstraint.inverse_matrix`
+
+bpy.types.KeyConfigurations
+---------------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.KeyConfigurations.addon`
+* :class:`bpy.types.KeyConfigurations.user`
+
+bpy.types.Image
+---------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Image.use_generated_float`
+
+bpy.types.KeyMapItem
+--------------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.KeyMapItem.is_user_modified`
+
+
+2.59 to 2.60
+============
+
+.. These have been manually added wait until RC to do final changelog!
+
+bpy.types.MeshTextureFace
+-------------------------
+
+Removed
+^^^^^^^
+
+* **use_image**
+* **use_object_color**
+* **use_blend_shared**
+
+Moved
+^^^^^
+
+* **hide** -> :class:`bpy.types.Material.game_settings.invisible`
+* **use_collision** -> :class:`bpy.types.Material.game_settings.physics`
+* **use_light** -> :class:`bpy.types.Material.game_settings.use_shadeless`
+* **use_twoside** -> :class:`bpy.types.Material.game_settings.backface_culling`
+* **use_bitmap_text** -> :class:`bpy.types.Material.game_settings.text`
+* **blend_type** -> :class:`bpy.types.Material.game_settings.alpha_blend`
+* **use_alpha_sort** -> :class:`bpy.types.Material.game_settings.alpha_blend`
+* **use_billboard** -> :class:`bpy.types.Material.game_settings.face_orientation`
+* **use_halo** -> :class:`bpy.types.Material.game_settings.face_orientation`
+* **use_shadow_cast** -> :class:`bpy.types.Material.game_settings.face_orientation`
+
+.. Automatically Generated, 2.59 -> r40804!
+
 bpy.types.RenderSettings
 ------------------------
 
@@ -937,7 +1112,15 @@ Added
 ^^^^^
 
 * :class:`bpy.types.Sound.factory`
-* :class:`bpy.types.Sound.mono`
+* :class:`bpy.types.Sound.use_mono`
+
+bpy.types.Camera
+----------------
+
+Added
+^^^^^
+
+* :class:`bpy.types.Camera.view_frame`
 
 bpy.types.Scene
 ---------------
@@ -961,7 +1144,7 @@ bpy.types.Armature
 Added
 ^^^^^
 
-* :class:`bpy.types.Armature.vert_deformer`
+* :class:`bpy.types.Armature.deform_method`
 
 bpy.types.GameObjectSettings
 ----------------------------
@@ -969,8 +1152,8 @@ bpy.types.GameObjectSettings
 Added
 ^^^^^
 
-* :class:`bpy.types.GameObjectSettings.create_obstacle`
 * :class:`bpy.types.GameObjectSettings.obstacle_radius`
+* :class:`bpy.types.GameObjectSettings.use_obstacle_create`
 
 bpy.types.BlendData
 -------------------
@@ -997,13 +1180,13 @@ Added
 * :class:`bpy.types.ThemeGraphEditor.handle_auto_clamped`
 * :class:`bpy.types.ThemeGraphEditor.handle_sel_auto_clamped`
 
-bpy.types.MultiresModifier
---------------------------
+bpy.types.CompositorNodeIDMask
+------------------------------
 
 Added
 ^^^^^
 
-* :class:`bpy.types.MultiresModifier.use_subsurf_uv`
+* :class:`bpy.types.CompositorNodeIDMask.use_smooth_mask`
 
 bpy.types.Node
 --------------
@@ -1013,27 +1196,6 @@ Added
 
 * :class:`bpy.types.Node.parent`
 
-bpy.types.KeyMap
-----------------
-
-Removed
-^^^^^^^
-
-* **copy_to_user**
-
-Renamed
-^^^^^^^
-
-* **is_user_defined** -> :class:`bpy.types.KeyMap.is_user_modified`
-
-bpy.types.SceneRenderLayer
---------------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.SceneRenderLayer.use_pass_material_index`
-
 bpy.types.Texture
 -----------------
 
@@ -1042,26 +1204,21 @@ Added
 
 * :class:`bpy.types.Texture.evaluate`
 
-bpy.types.ToolSettings
-----------------------
+bpy.types.UILayout
+------------------
 
 Added
 ^^^^^
 
-* :class:`bpy.types.ToolSettings.use_multipaint`
-
-Renamed
-^^^^^^^
-
-* **use_snap_project_self** -> :class:`bpy.types.ToolSettings.use_snap_self`
+* :class:`bpy.types.UILayout.template_keymap_item_properties`
 
-bpy.types.RenderEngine
+bpy.types.ToolSettings
 ----------------------
 
 Added
 ^^^^^
 
-* :class:`bpy.types.RenderEngine.report`
+* :class:`bpy.types.ToolSettings.use_multipaint`
 
 bpy.types.UserPreferencesInput
 ------------------------------
@@ -1069,26 +1226,12 @@ bpy.types.UserPreferencesInput
 Added
 ^^^^^
 
-* :class:`bpy.types.UserPreferencesInput.ndof_fly_helicopter`
-* :class:`bpy.types.UserPreferencesInput.ndof_lock_horizon`
-* :class:`bpy.types.UserPreferencesInput.ndof_orbit_invert_axes`
 * :class:`bpy.types.UserPreferencesInput.ndof_panx_invert_axis`
 * :class:`bpy.types.UserPreferencesInput.ndof_pany_invert_axis`
 * :class:`bpy.types.UserPreferencesInput.ndof_panz_invert_axis`
 * :class:`bpy.types.UserPreferencesInput.ndof_roll_invert_axis`
 * :class:`bpy.types.UserPreferencesInput.ndof_rotate_invert_axis`
-* :class:`bpy.types.UserPreferencesInput.ndof_sensitivity`
-* :class:`bpy.types.UserPreferencesInput.ndof_show_guide`
 * :class:`bpy.types.UserPreferencesInput.ndof_tilt_invert_axis`
-* :class:`bpy.types.UserPreferencesInput.ndof_zoom_invert`
-* :class:`bpy.types.UserPreferencesInput.ndof_zoom_updown`
-
-Removed
-^^^^^^^
-
-* **edited_keymaps**
-* **ndof_pan_speed**
-* **ndof_rotate_speed**
 
 bpy.types.LockedTrackConstraint
 -------------------------------
@@ -1101,10 +1244,18 @@ Added
 bpy.types.SpaceGraphEditor
 --------------------------
 
-Renamed
-^^^^^^^
+Moved
+^^^^^
+
+* use_fancy_drawing -> :class:`bpy.types.SpaceGraphEditor.use_beauty_drawing`
+
+bpy.types.ParticleSystem
+------------------------
+
+Added
+^^^^^
 
-* **use_fancy_drawing** -> :class:`bpy.types.SpaceGraphEditor.use_beauty_drawing`
+* :class:`bpy.types.ParticleSystem.dt_frac`
 
 bpy.types.Mesh
 --------------
@@ -1176,14 +1327,6 @@ Added
 * :class:`bpy.types.EnvironmentMap.is_valid`
 * :class:`bpy.types.EnvironmentMap.save`
 
-bpy.types.IDMaterials
----------------------
-
-Function Arguments
-^^^^^^^^^^^^^^^^^^
-
-* :class:`bpy.types.IDMaterials.save` (index, update_data), *was (index)*
-
 bpy.types.UserPreferencesSystem
 -------------------------------
 
@@ -1213,7 +1356,7 @@ bpy.types.MovieSequence
 Added
 ^^^^^
 
-* :class:`bpy.types.MovieSequence.streamindex`
+* :class:`bpy.types.MovieSequence.stream_index`
 
 bpy.types.Material
 ------------------
@@ -1222,15 +1365,6 @@ Added
 ^^^^^
 
 * :class:`bpy.types.Material.game_settings`
-* :class:`bpy.types.Material.pass_index`
-
-bpy.types.RenderLayer
----------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.RenderLayer.use_pass_material_index`
 
 bpy.types.Object
 ----------------
@@ -1238,17 +1372,8 @@ bpy.types.Object
 Added
 ^^^^^
 
-* :class:`bpy.types.Object.closest_point_on_mesh`
 * :class:`bpy.types.Object.matrix_parent_inverse`
 
-bpy.types.ThemeNodeEditor
--------------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.ThemeNodeEditor.noodle_curving`
-
 bpy.types.SequenceProxy
 -----------------------
 
@@ -1265,14 +1390,6 @@ Added
 * :class:`bpy.types.SequenceProxy.quality`
 * :class:`bpy.types.SequenceProxy.timecode`
 
-bpy.types.SpaceUVEditor
------------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.SpaceUVEditor.show_faces`
-
 bpy.types.Sequence
 ------------------
 
@@ -1281,14 +1398,6 @@ Added
 
 * :class:`bpy.types.Sequence.waveform`
 
-bpy.types.ChildOfConstraint
----------------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.ChildOfConstraint.inverse_matrix`
-
 bpy.types.DopeSheet
 -------------------
 
@@ -1311,15 +1420,6 @@ Added
 * :class:`bpy.types.ActionActuator.use_force`
 * :class:`bpy.types.ActionActuator.use_local`
 
-bpy.types.KeyConfigurations
----------------------------
-
-Added
-^^^^^
-
-* :class:`bpy.types.KeyConfigurations.addon`
-* :class:`bpy.types.KeyConfigurations.user`
-
 bpy.types.VertexGroup
 ---------------------
 
@@ -1344,7 +1444,6 @@ Added
 
 * :class:`bpy.types.Image.pack`
 * :class:`bpy.types.Image.unpack`
-* :class:`bpy.types.Image.use_generated_float`
 
 bpy.types.Curve
 ---------------
@@ -1360,13 +1459,14 @@ Removed
 * **use_fill_back**
 * **use_fill_front**
 
-bpy.types.KeyMapItem
---------------------
+bpy.types.ParticleSettings
+--------------------------
 
 Added
 ^^^^^
 
-* :class:`bpy.types.KeyMapItem.is_user_modified`
+* :class:`bpy.types.ParticleSettings.adaptive_subframes`
+* :class:`bpy.types.ParticleSettings.courant_target`
 
 bpy.types.SceneGameData
 -----------------------
@@ -1380,27 +1480,3 @@ Added
 * :class:`bpy.types.SceneGameData.restrict_animation_updates`
 * :class:`bpy.types.SceneGameData.show_obstacle_simulation`
 
-bpy.types.MeshTextureFace
--------------------------
-
-Removed
-^^^^^^^
-
-* **use_image**
-* **use_object_color**
-* **use_blend_shared**
-
-Moved
-^^^^^
-
-* **hide** -> :class:`bpy.types.Material.game_settings.invisible`
-* **use_collision** -> :class:`bpy.types.Material.game_settings.physics`
-* **use_light** -> :class:`bpy.types.Material.game_settings.use_shadeless`
-* **use_twoside** -> :class:`bpy.types.Material.game_settings.backface_culling`
-* **use_bitmap_text** -> :class:`bpy.types.Material.game_settings.text`
-* **blend_type** -> :class:`bpy.types.Material.game_settings.alpha_blend`
-* **use_alpha_sort** -> :class:`bpy.types.Material.game_settings.alpha_blend`
-* **use_billboard** -> :class:`bpy.types.Material.game_settings.face_orientation`
-* **use_halo** -> :class:`bpy.types.Material.game_settings.face_orientation`
-* **use_shadow_cast** -> :class:`bpy.types.Material.game_settings.face_orientation`
-
index bc1619b..3ded103 100644 (file)
@@ -302,7 +302,7 @@ def api_changelog(api_from, api_to, api_out):
             for func_id, args_old, args_new in func_args:
                 args_new = ", ".join(args_new)
                 args_old = ", ".join(args_old)
-                fw("* :class:`%s.%s.%s` (%s), *was (%s)*\n" % (mod_id, class_name, prop_id, args_new, args_old))
+                fw("* :class:`%s.%s.%s` (%s), *was (%s)*\n" % (mod_id, class_name, func_id, args_new, args_old))
             fw("\n")
 
     fout.close()
index ca37030..c1bed08 100644 (file)
@@ -161,7 +161,7 @@ def range_str(val):
 
 
 def example_extract_docstring(filepath):
-    file = open(filepath, 'r')
+    file = open(filepath, "r", encoding="utf-8")
     line = file.readline()
     line_no = 0
     text = []
@@ -360,7 +360,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
     if module_all:
         module_dir = module_all
 
-    file = open(filepath, "w")
+    file = open(filepath, "w", encoding="utf-8")
 
     fw = file.write
 
@@ -510,7 +510,7 @@ def pycontext2sphinx(BASEPATH):
     # Only use once. very irregular
 
     filepath = os.path.join(BASEPATH, "bpy.context.rst")
-    file = open(filepath, "w")
+    file = open(filepath, "w", encoding="utf-8")
     fw = file.write
     fw("Context Access (bpy.context)\n")
     fw("============================\n\n")
@@ -698,7 +698,7 @@ def pyrna2sphinx(BASEPATH):
         #    return
 
         filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % struct.identifier)
-        file = open(filepath, "w")
+        file = open(filepath, "w", encoding="utf-8")
         fw = file.write
 
         base_id = getattr(struct.base, "identifier", "")
@@ -912,7 +912,7 @@ def pyrna2sphinx(BASEPATH):
 
         def fake_bpy_type(class_value, class_name, descr_str, use_subclasses=True):
             filepath = os.path.join(BASEPATH, "bpy.types.%s.rst" % class_name)
-            file = open(filepath, "w")
+            file = open(filepath, "w", encoding="utf-8")
             fw = file.write
 
             write_title(fw, class_name, "=")
@@ -963,7 +963,7 @@ def pyrna2sphinx(BASEPATH):
 
         for op_module_name, ops_mod in op_modules.items():
             filepath = os.path.join(BASEPATH, "bpy.ops.%s.rst" % op_module_name)
-            file = open(filepath, "w")
+            file = open(filepath, "w", encoding="utf-8")
             fw = file.write
 
             title = "%s Operators" % op_module_name.replace("_", " ").title()
@@ -1017,7 +1017,7 @@ def rna2sphinx(BASEPATH):
 
     # conf.py - empty for now
     filepath = os.path.join(BASEPATH, "conf.py")
-    file = open(filepath, "w")
+    file = open(filepath, "w", encoding="utf-8")
     fw = file.write
 
     version_string = ".".join(str(v) for v in bpy.app.version)
@@ -1053,7 +1053,7 @@ def rna2sphinx(BASEPATH):
 
     # main page needed for sphinx (index.html)
     filepath = os.path.join(BASEPATH, "contents.rst")
-    file = open(filepath, "w")
+    file = open(filepath, "w", encoding="utf-8")
     fw = file.write
 
     fw("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")
@@ -1169,7 +1169,7 @@ def rna2sphinx(BASEPATH):
     # internal modules
     if "bpy.ops" not in EXCLUDE_MODULES:
         filepath = os.path.join(BASEPATH, "bpy.ops.rst")
-        file = open(filepath, "w")
+        file = open(filepath, "w", encoding="utf-8")
         fw = file.write
         fw("Operators (bpy.ops)\n")
         fw("===================\n\n")
@@ -1181,7 +1181,7 @@ def rna2sphinx(BASEPATH):
 
     if "bpy.types" not in EXCLUDE_MODULES:
         filepath = os.path.join(BASEPATH, "bpy.types.rst")
-        file = open(filepath, "w")
+        file = open(filepath, "w", encoding="utf-8")
         fw = file.write
         fw("Types (bpy.types)\n")
         fw("=================\n\n")
@@ -1194,7 +1194,7 @@ def rna2sphinx(BASEPATH):
         # not actually a module, only write this file so we
         # can reference in the TOC
         filepath = os.path.join(BASEPATH, "bpy.data.rst")
-        file = open(filepath, "w")
+        file = open(filepath, "w", encoding="utf-8")
         fw = file.write
         fw("Data Access (bpy.data)\n")
         fw("======================\n\n")
@@ -1284,7 +1284,7 @@ def rna2sphinx(BASEPATH):
 
     if 0:
         filepath = os.path.join(BASEPATH, "bpy.rst")
-        file = open(filepath, "w")
+        file = open(filepath, "w", encoding="utf-8")
         fw = file.write
 
         fw("\n")
index 660b881..3d8b7ab 100644 (file)
@@ -53,18 +53,19 @@ set(SRC
                Detour/Include/DetourTileNavMeshBuilder.h
 
                Recast/Source/Recast.cpp
+               Recast/Source/RecastAlloc.cpp
+               Recast/Source/RecastArea.cpp
                Recast/Source/RecastContour.cpp
                Recast/Source/RecastFilter.cpp
-               Recast/Source/RecastLog.cpp
+               Recast/Source/RecastLayers.cpp
                Recast/Source/RecastMesh.cpp
                Recast/Source/RecastMeshDetail.cpp
                Recast/Source/RecastRasterization.cpp
                Recast/Source/RecastRegion.cpp
-               Recast/Source/RecastTimer.cpp
 
                Recast/Include/Recast.h
-               Recast/Include/RecastLog.h
-               Recast/Include/RecastTimer.h
+               Recast/Include/RecastAlloc.h
+               Recast/Include/RecastAssert.h
 )
 
 blender_add_lib(extern_recastnavigation "${SRC}" "${INC}" "${INC_SYS}")
index f25ab47..4e20b0f 100644 (file)
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2009 Mikko Mononen memon@inside.org
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
 //
 // This software is provided 'as-is', without any express or implied
 // warranty.  In no event will the authors be held liable for any damages
 #ifndef RECAST_H
 #define RECAST_H
 
-// The units of the parameters are specified in parenthesis as follows:
-// (vx) voxels, (wu) world units
-struct rcConfig
+/// The value of PI used by Recast.
+static const float RC_PI = 3.14159265f;
+
+/// Recast log categories.
+/// @see rcContext
+enum rcLogCategory
 {
-       int width, height;                              // Dimensions of the rasterized heighfield (vx)
-       int tileSize;                                   // Width and Height of a tile (vx)
-       int borderSize;                                 // Non-navigable Border around the heightfield (vx)
-       float cs, ch;                                   // Grid cell size and height (wu)
-       float bmin[3], bmax[3];                 // Grid bounds (wu)
-       float walkableSlopeAngle;               // Maximum walkble slope angle in degrees.
-       int walkableHeight;                             // Minimum height where the agent can still walk (vx)
-       int walkableClimb;                              // Maximum height between grid cells the agent can climb (vx)
-       int walkableRadius;                             // Radius of the agent in cells (vx)
-       int maxEdgeLen;                                 // Maximum contour edge length (vx)
-       float maxSimplificationError;   // Maximum distance error from contour to cells (vx)
-       int minRegionSize;                              // Minimum regions size. Smaller regions will be deleted (vx)
-       int mergeRegionSize;                    // Minimum regions size. Smaller regions will be merged (vx)
-       int maxVertsPerPoly;                    // Max number of vertices per polygon
-       float detailSampleDist;                 // Detail mesh sample spacing.
-       float detailSampleMaxError;             // Detail mesh simplification max sample error.
+       RC_LOG_PROGRESS = 1,    ///< A progress log entry.
+       RC_LOG_WARNING,             ///< A warning log entry.
+       RC_LOG_ERROR,               ///< An error log entry.
 };
 
-// Heightfield span.
-struct rcSpan
+/// Recast performance timer categories.
+/// @see rcContext
+enum rcTimerLabel
+{
+       /// The user defined total time of the build.
+       RC_TIMER_TOTAL,
+       /// A user defined build time.
+       RC_TIMER_TEMP,
+       /// The time to rasterize the triangles. (See: #rcRasterizeTriangle)
+       RC_TIMER_RASTERIZE_TRIANGLES,
+       /// The time to build the compact heightfield. (See: #rcBuildCompactHeightfield)
+       RC_TIMER_BUILD_COMPACTHEIGHTFIELD,
+       /// The total time to build the contours. (See: #rcBuildContours)
+       RC_TIMER_BUILD_CONTOURS,
+       /// The time to trace the boundaries of the contours. (See: #rcBuildContours)
+       RC_TIMER_BUILD_CONTOURS_TRACE,
+       /// The time to simplify the contours. (See: #rcBuildContours)
+       RC_TIMER_BUILD_CONTOURS_SIMPLIFY,
+       /// The time to filter ledge spans. (See: #rcFilterLedgeSpans)
+       RC_TIMER_FILTER_BORDER,
+       /// The time to filter low height spans. (See: #rcFilterWalkableLowHeightSpans)
+       RC_TIMER_FILTER_WALKABLE,
+       /// The time to apply the median filter. (See: #rcMedianFilterWalkableArea)
+       RC_TIMER_MEDIAN_AREA,
+       /// The time to filter low obstacles. (See: #rcFilterLowHangingWalkableObstacles)
+       RC_TIMER_FILTER_LOW_OBSTACLES,
+       /// The time to build the polygon mesh. (See: #rcBuildPolyMesh)
+       RC_TIMER_BUILD_POLYMESH,
+       /// The time to merge polygon meshes. (See: #rcMergePolyMeshes)
+       RC_TIMER_MERGE_POLYMESH,
+       /// The time to erode the walkable area. (See: #rcErodeWalkableArea)
+       RC_TIMER_ERODE_AREA,
+       /// The time to mark a box area. (See: #rcMarkBoxArea)
+       RC_TIMER_MARK_BOX_AREA,
+       /// The time to mark a cylinder area. (See: #rcMarkCylinderArea)
+       RC_TIMER_MARK_CYLINDER_AREA,
+       /// The time to mark a convex polygon area. (See: #rcMarkConvexPolyArea)
+       RC_TIMER_MARK_CONVEXPOLY_AREA,
+       /// The total time to build the distance field. (See: #rcBuildDistanceField)
+       RC_TIMER_BUILD_DISTANCEFIELD,
+       /// The time to build the distances of the distance field. (See: #rcBuildDistanceField)
+       RC_TIMER_BUILD_DISTANCEFIELD_DIST,
+       /// The time to blur the distance field. (See: #rcBuildDistanceField)
+       RC_TIMER_BUILD_DISTANCEFIELD_BLUR,
+       /// The total time to build the regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
+       RC_TIMER_BUILD_REGIONS,
+       /// The total time to apply the watershed algorithm. (See: #rcBuildRegions)
+       RC_TIMER_BUILD_REGIONS_WATERSHED,
+       /// The time to expand regions while applying the watershed algorithm. (See: #rcBuildRegions)
+       RC_TIMER_BUILD_REGIONS_EXPAND,
+       /// The time to flood regions while applying the watershed algorithm. (See: #rcBuildRegions)
+       RC_TIMER_BUILD_REGIONS_FLOOD,
+       /// The time to filter out small regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
+       RC_TIMER_BUILD_REGIONS_FILTER,
+       /// The time to build heightfield layers. (See: #rcBuildHeightfieldLayers)
+       RC_TIMER_BUILD_LAYERS, 
+       /// The time to build the polygon mesh detail. (See: #rcBuildPolyMeshDetail)
+       RC_TIMER_BUILD_POLYMESHDETAIL,
+       /// The time to merge polygon mesh details. (See: #rcMergePolyMeshDetails)
+       RC_TIMER_MERGE_POLYMESHDETAIL,
+       /// The maximum number of timers.  (Used for iterating timers.)
+       RC_MAX_TIMERS
+};
+
+/// Provides an interface for optional logging and performance tracking of the Recast 
+/// build process.
+/// @ingroup recast
+class rcContext
+{
+public:
+
+       /// Contructor.
+       ///  @param[in] state  TRUE if the logging and performance timers should be enabled.  [Default: true]
+       inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {}
+       virtual ~rcContext() {}
+
+       /// Enables or disables logging.
+       ///  @param[in] state TRUE if logging should be enabled.
+       inline void enableLog(bool state) { m_logEnabled = state; }
+
+       /// Clears all log entries.
+       inline void resetLog() { if (m_logEnabled) doResetLog(); }
+
+       /// Logs a message.
+       ///  @param[in] category The category of the message.
+       ///  @param[in] format The message.
+       void log(const rcLogCategory category, const char* format, ...);
+
+       /// Enables or disables the performance timers.
+       ///  @param[in] state  TRUE if timers should be enabled.
+       inline void enableTimer(bool state) { m_timerEnabled = state; }
+
+       /// Clears all peformance timers. (Resets all to unused.)
+       inline void resetTimers() { if (m_timerEnabled) doResetTimers(); }
+
+       /// Starts the specified performance timer.
+       ///  @param label  The category of timer.
+       inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); }
+
+       /// Stops the specified performance timer.
+       ///  @param label  The category of the timer.
+       inline void stopTimer(const rcTimerLabel label) { if (m_timerEnabled) doStopTimer(label); }
+
+       /// Returns the total accumulated time of the specified performance timer.
+       ///  @param label  The category of the timer.
+       ///  @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started.
+       inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; }
+
+protected:
+
+       /// Clears all log entries.
+       virtual void doResetLog() {}
+
+       /// Logs a message.
+       ///  @param[in] category The category of the message.
+       ///  @param[in] msg The formatted message.
+       ///  @param[in] len The length of the formatted message.
+       virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {}
+
+       /// Clears all timers. (Resets all to unused.)
+       virtual void doResetTimers() {}
+
+       /// Starts the specified performance timer.
+       ///  @param[in] label  The category of timer.
+       virtual void doStartTimer(const rcTimerLabel /*label*/) {}
+
+       /// Stops the specified performance timer.
+       ///  @param[in] label  The category of the timer.
+       virtual void doStopTimer(const rcTimerLabel /*label*/) {}
+
+       /// Returns the total accumulated time of the specified performance timer.
+       ///  @param[in] label  The category of the timer.
+       ///  @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started.
+       virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; }
+       
+       /// True if logging is enabled.
+       bool m_logEnabled;
+
+       /// True if the performance timers are enabled.
+       bool m_timerEnabled;
+};
+
+/// Specifies a configuration to use when performing Recast builds.
+/// @ingroup recast
+struct rcConfig
 {
-       unsigned int smin : 15;                 // Span min height.
-       unsigned int smax : 15;                 // Span max height.
-       unsigned int flags : 2;                 // Span flags.
-       rcSpan* next;                                   // Next span in column.
+       /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx]
+       int width;
+
+       /// The height of the field along the z-axis. [Limit: >= 0] [Units: vx]
+       int height;     
+       
+       /// The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx]
+       int tileSize;   
+       
+       /// The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]
+       int borderSize;
+
+       /// The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu] 
+       float cs;
+
+       /// The y-axis cell size to use for fields. [Limit: > 0] [Units: wu]
+       float ch;
+
+       /// The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu]
+       float bmin[3]; 
+
+       /// The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu]
+       float bmax[3];
+
+       /// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees] 
+       float walkableSlopeAngle;
+
+       /// Minimum floor to 'ceiling' height that will still allow the floor area to 
+       /// be considered walkable. [Limit: >= 3] [Units: vx] 
+       int walkableHeight;                             
+       
+       /// Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx] 
+       int walkableClimb;                              
+       
+       /// The distance to erode/shrink the walkable area of the heightfield away from 
+       /// obstructions.  [Limit: >=0] [Units: vx] 
+       int walkableRadius;                             
+       
+       /// The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx] 
+       int maxEdgeLen;                                 
+       
+       /// The maximum distance a simplfied contour's border edges should deviate 
+       /// the original raw contour. [Limit: >=0] [Units: wu]
+       float maxSimplificationError;   
+       
+       /// The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx] 
+       int minRegionArea;                              
+       
+       /// Any regions with a span count smaller than this value will, if possible, 
+       /// be merged with larger regions. [Limit: >=0] [Units: vx] 
+       int mergeRegionArea;                    
+       
+       /// The maximum number of vertices allowed for polygons generated during the 
+       /// contour to polygon conversion process. [Limit: >= 3] 
+       int maxVertsPerPoly;
+       
+       /// Sets the sampling distance to use when generating the detail mesh.
+       /// (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu] 
+       float detailSampleDist;
+       
+       /// The maximum distance the detail mesh surface should deviate from heightfield
+       /// data. (For height detail only.) [Limit: >=0] [Units: wu] 
+       float detailSampleMaxError;
 };
 
+/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax.
+static const int RC_SPAN_HEIGHT_BITS = 13;
+/// Defines the maximum value for rcSpan::smin and rcSpan::smax.
+static const int RC_SPAN_MAX_HEIGHT = (1<<RC_SPAN_HEIGHT_BITS)-1;
+
+/// The number of spans allocated per span spool.
+/// @see rcSpanPool
 static const int RC_SPANS_PER_POOL = 2048;
 
-// Memory pool used for quick span allocation.
+/// Represents a span in a heightfield.
+/// @see rcHeightfield
+struct rcSpan
+{
+    unsigned int smin : 13;                    ///< The lower limit of the span. [Limit: < #smax]
+    unsigned int smax : 13;                    ///< The upper limit of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT]
+       unsigned int area : 6;                  ///< The area id assigned to the span.
+       rcSpan* next;                                   ///< The next span higher up in column.
+};
+
+/// A memory pool used for quick allocation of spans within a heightfield.
+/// @see rcHeightfield
 struct rcSpanPool
 {
-       rcSpanPool* next;       // Pointer to next pool.
-       rcSpan items[1];        // Array of spans (size RC_SPANS_PER_POOL).
+       rcSpanPool* next;                                       ///< The next span pool.
+       rcSpan items[RC_SPANS_PER_POOL];        ///< Array of spans in the pool.
 };
 
-// Dynamic span-heightfield.
+/// A dynamic heightfield representing obstructed space.
+/// @ingroup recast
 struct rcHeightfield
 {
-       inline rcHeightfield() : width(0), height(0), spans(0), pools(0), freelist(0) {}
-       inline ~rcHeightfield()
-       {
-               // Delete span array.
-               delete [] spans;
-               // Delete span pools.
-               while (pools)
-               {
-                       rcSpanPool* next = pools->next;
-                       delete [] reinterpret_cast<unsigned char*>(pools);
-                       pools = next;
-               }
-       }
-       int width, height;                      // Dimension of the heightfield.
-       float bmin[3], bmax[3];         // Bounding box of the heightfield
-       float cs, ch;                           // Cell size and height.
-       rcSpan** spans;                         // Heightfield of spans (width*height).
-       rcSpanPool* pools;                      // Linked list of span pools.
-       rcSpan* freelist;                       // Pointer to next free span.
+       int width;                  ///< The width of the heightfield. (Along the x-axis in cell units.)
+       int height;                     ///< The height of the heightfield. (Along the z-axis in cell units.)
+       float bmin[3];          ///< The minimum bounds in world space. [(x, y, z)]
+       float bmax[3];          ///< The maximum bounds in world space. [(x, y, z)]
+       float cs;                   ///< The size of each cell. (On the xz-plane.)
+       float ch;                       ///< The height of each cell. (The minimum increment along the y-axis.)
+       rcSpan** spans;         ///< Heightfield of spans (width*height).
+       rcSpanPool* pools;      ///< Linked list of span pools.
+       rcSpan* freelist;       ///< The next free span.
 };
 
+/// Provides information on the content of a cell column in a compact heightfield. 
 struct rcCompactCell
 {
-       unsigned int index : 24;        // Index to first span in column.
-       unsigned int count : 8;         // Number of spans in this column.
+       unsigned int index : 24;        ///< Index to the first span in the column.
+       unsigned int count : 8;         ///< Number of spans in the column.
 };
 
+/// Represents a span of unobstructed space within a compact heightfield.
 struct rcCompactSpan
 {
-       unsigned short y;                       // Bottom coordinate of the span.
-       unsigned short reg;                     // Region ID
-       unsigned short dist;            // Distance to border
-       unsigned short con;                     // Connections to neighbour cells.
-       unsigned char h;                        // Height of the span.
-       unsigned char flags;            // Flags.
+       unsigned short y;                       ///< The lower extent of the span. (Measured from the heightfield's base.)
+       unsigned short reg;                 ///< The id of the region the span belongs to. (Or zero if not in a region.)
+       unsigned int con : 24;          ///< Packed neighbor connection data.
+       unsigned int h : 8;                     ///< The height of the span.  (Measured from #y.)
 };
 
-// Compact static heightfield. 
+/// A compact, static heightfield representing unobstructed space.
+/// @ingroup recast
 struct rcCompactHeightfield
 {
-       inline rcCompactHeightfield() : maxDistance(0), maxRegions(0), cells(0), spans(0) {}
-       inline ~rcCompactHeightfield() { delete [] cells; delete [] spans; }
-       int width, height;                                      // Width and height of the heighfield.
-       int spanCount;                                          // Number of spans in the heightfield.
-       int walkableHeight, walkableClimb;      // Agent properties.
-       unsigned short maxDistance;                     // Maximum distance value stored in heightfield.
-       unsigned short maxRegions;                      // Maximum Region Id stored in heightfield.
-       float bmin[3], bmax[3];                         // Bounding box of the heightfield.
-       float cs, ch;                                           // Cell size and height.
-       rcCompactCell* cells;                           // Pointer to width*height cells.
-       rcCompactSpan* spans;                           // Pointer to spans.
+       int width;                                  ///< The width of the heightfield. (Along the x-axis in cell units.)
+       int height;                                     ///< The height of the heightfield. (Along the z-axis in cell units.)
+       int spanCount;                          ///< The number of spans in the heightfield.
+       int walkableHeight;                 ///< The walkable height used during the build of the field.  (See: rcConfig::walkableHeight)
+       int walkableClimb;                      ///< The walkable climb used during the build of the field. (See: rcConfig::walkableClimb)
+       int borderSize;                         ///< The AABB border size used during the build of the field. (See: rcConfig::borderSize)
+       unsigned short maxDistance;     ///< The maximum distance value of any span within the field. 
+       unsigned short maxRegions;      ///< The maximum region id of any span within the field. 
+       float bmin[3];                      ///< The minimum bounds in world space. [(x, y, z)]
+       float bmax[3];                          ///< The maximum bounds in world space. [(x, y, z)]
+       float cs;                                   ///< The size of each cell. (On the xz-plane.)
+       float ch;                                       ///< The height of each cell. (The minimum increment along the y-axis.)
+       rcCompactCell* cells;           ///< Array of cells. [Size: #width*#height]
+       rcCompactSpan* spans;           ///< Array of spans. [Size: #spanCount]
+       unsigned short* dist;           ///< Array containing border distance data. [Size: #spanCount]
+       unsigned char* areas;           ///< Array containing area id data. [Size: #spanCount]
+};
+
+/// Represents a heightfield layer within a layer set.
+/// @see rcHeightfieldLayerSet
+struct rcHeightfieldLayer
+{
+       float bmin[3];                      ///< The minimum bounds in world space. [(x, y, z)]
+       float bmax[3];                          ///< The maximum bounds in world space. [(x, y, z)]
+       float cs;                                   ///< The size of each cell. (On the xz-plane.)
+       float ch;                                       ///< The height of each cell. (The minimum increment along the y-axis.)
+       int width;                                  ///< The width of the heightfield. (Along the x-axis in cell units.)
+       int height;                                     ///< The height of the heightfield. (Along the z-axis in cell units.)
+       int minx;                                   ///< The minimum x-bounds of usable data.
+       int maxx;                                   ///< The maximum x-bounds of usable data.
+       int miny;                                   ///< The minimum y-bounds of usable data. (Along the z-axis.)
+       int maxy;                                       ///< The maximum y-bounds of usable data. (Along the z-axis.)
+       int hmin;                                   ///< The minimum height bounds of usable data. (Along the y-axis.)
+       int hmax;                                       ///< The maximum height bounds of usable data. (Along the y-axis.)
+       unsigned char* heights;         ///< The heightfield. [Size: (width - borderSize*2) * (h - borderSize*2)]
+       unsigned char* areas;           ///< Area ids. [Size: Same as #heights]
+       unsigned char* cons;            ///< Packed neighbor connection information. [Size: Same as #heights]
+};
+
+/// Represents a set of heightfield layers.
+/// @ingroup recast
+/// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet 
+struct rcHeightfieldLayerSet
+{
+       rcHeightfieldLayer* layers;                     ///< The layers in the set. [Size: #nlayers]
+       int nlayers;                                            ///< The number of layers in the set.
 };
 
+/// Represents a simple, non-overlapping contour in field space.
 struct rcContour
 {
-       inline rcContour() : verts(0), nverts(0), rverts(0), nrverts(0) { }
-       inline ~rcContour() { delete [] verts; delete [] rverts; }
-       int* verts;                     // Vertex coordinates, each vertex contains 4 components.
-       int nverts;                     // Number of vertices.
-       int* rverts;            // Raw vertex coordinates, each vertex contains 4 components.
-       int nrverts;            // Number of raw vertices.
-       unsigned short reg;     // Region ID of the contour.
+       int* verts;                     ///< Simplified contour vertex and connection data. [Size: 4 * #nverts]
+       int nverts;                     ///< The number of vertices in the simplified contour. 
+       int* rverts;            ///< Raw contour vertex and connection data. [Size: 4 * #nrverts]
+       int nrverts;            ///< The number of vertices in the raw contour. 
+       unsigned short reg;     ///< The region id of the contour.
+       unsigned char area;     ///< The area id of the contour.
 };
 
+/// Represents a group of related contours.
+/// @ingroup recast
 struct rcContourSet
 {
-       inline rcContourSet() : conts(0), nconts(0) {}
-       inline ~rcContourSet() { delete [] conts; }
-       rcContour* conts;               // Pointer to all contours.
-       int nconts;                             // Number of contours.
-       float bmin[3], bmax[3]; // Bounding box of the heightfield.
-       float cs, ch;                   // Cell size and height.
+       rcContour* conts;       ///< An array of the contours in the set. [Size: #nconts]
+       int nconts;                     ///< The number of contours in the set.
+       float bmin[3];          ///< The minimum bounds in world space. [(x, y, z)]
+       float bmax[3];          ///< The maximum bounds in world space. [(x, y, z)]
+       float cs;                   ///< The size of each cell. (On the xz-plane.)
+       float ch;                       ///< The height of each cell. (The minimum increment along the y-axis.)
+       int width;                  ///< The width of the set. (Along the x-axis in cell units.) 
+       int height;                 ///< The height of the set. (Along the z-axis in cell units.) 
+       int borderSize;         ///< The AABB border size used to generate the source data from which the contours were derived.
 };
 
-// Polymesh store a connected mesh of polygons.
-// The polygons are store in an array where each polygons takes
-// 'nvp*2' elements. The first 'nvp' elements are indices to vertices
-// and the second 'nvp' elements are indices to neighbour polygons.
-// If a polygona has less than 'bvp' vertices, the remaining indices
-// are set os 0xffff. If an polygon edge does not have a neighbour
-// the neighbour index is set to 0xffff.
-// Vertices can be transformed into world space as follows:
-//   x = bmin[0] + verts[i*3+0]*cs;
-//   y = bmin[1] + verts[i*3+1]*ch;
-//   z = bmin[2] + verts[i*3+2]*cs;
+/// Represents a polygon mesh suitable for use in building a navigation mesh. 
+/// @ingroup recast
 struct rcPolyMesh
-{
-       inline rcPolyMesh() : verts(0), polys(0), regs(0), nverts(0), npolys(0), nvp(3) {}
-       inline ~rcPolyMesh() { delete [] verts; delete [] polys; delete [] regs; }
-       unsigned short* verts;  // Vertices of the mesh, 3 elements per vertex.
-       unsigned short* polys;  // Polygons of the mesh, nvp*2 elements per polygon.
-       unsigned short* regs;   // Regions of the polygons.
-       int nverts;                             // Number of vertices.
-       int npolys;                             // Number of polygons.
-       int nvp;                                // Max number of vertices per polygon.
-       float bmin[3], bmax[3]; // Bounding box of the mesh.
-       float cs, ch;                   // Cell size and height.
+{      
+       unsigned short* verts;  ///< The mesh vertices. [Form: (x, y, z) * #nverts]
+       unsigned short* polys;  ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp]
+       unsigned short* regs;   ///< The region id assigned to each polygon. [Length: #maxpolys]
+       unsigned short* flags;  ///< The user defined flags for each polygon. [Length: #maxpolys]
+       unsigned char* areas;   ///< The area id assigned to each polygon. [Length: #maxpolys]
+       int nverts;                             ///< The number of vertices.
+       int npolys;                             ///< The number of polygons.
+       int maxpolys;                   ///< The number of allocated polygons.
+       int nvp;                                ///< The maximum number of vertices per polygon.
+       float bmin[3];              ///< The minimum bounds in world space. [(x, y, z)]
+       float bmax[3];              ///< The maximum bounds in world space. [(x, y, z)]
+       float cs;                           ///< The size of each cell. (On the xz-plane.)
+       float ch;                               ///< The height of each cell. (The minimum increment along the y-axis.)
+       int borderSize;                 ///< The AABB border size used to generate the source data from which the mesh was derived.
 };
 
-// Detail mesh generated from a rcPolyMesh.
-// Each submesh represents a polygon in the polymesh and they are stored in
-// excatly same order. Each submesh is described as 4 values:
-// base vertex, vertex count, base triangle, triangle count. That is,
-//   const unsigned char* t = &dtl.tris[(tbase+i)*3]; and
-//   const float* v = &dtl.verts[(vbase+t[j])*3];
-// If the input polygon has 'n' vertices, those vertices are first in the
-// submesh vertex list. This allows to compres the mesh by not storing the
-// first vertices and using the polymesh vertices instead.
-
+/// Contains triangle meshes that represent detailed height data associated 
+/// with the polygons in its associated polygon mesh object.
+/// @ingroup recast
 struct rcPolyMeshDetail
 {
-       inline rcPolyMeshDetail() :
-               meshes(0), verts(0), tris(0),
-               nmeshes(0), nverts(0), ntris(0) {}
-       inline ~rcPolyMeshDetail()
-       {
-               delete [] meshes; delete [] verts; delete [] tris;
-       }
-       
-       unsigned short* meshes; // Pointer to all mesh data.
-       float* verts;                   // Pointer to all vertex data.
-       unsigned char* tris;    // Pointer to all triangle data.
-       int nmeshes;                    // Number of meshes.
-       int nverts;                             // Number of total vertices.
-       int ntris;                              // Number of triangles.
+    unsigned int* meshes;      ///< The sub-mesh data. [Size: 4*#nmeshes] 
+    float* verts;                      ///< The mesh vertices. [Size: 3*#nverts] 
+    unsigned char* tris;       ///< The mesh triangles. [Size: 4*#ntris] 
+    int nmeshes;                       ///< The number of sub-meshes defined by #meshes.
+    int nverts;                                ///< The number of vertices in #verts.
+    int ntris;                         ///< The number of triangles in #tris.
 };
 
+/// @name Allocation Functions
+/// Functions used to allocate and de-allocate Recast objects.
+/// @see rcAllocSetCustom
+/// @{
 
-// Simple dynamic array ints.
-class rcIntArray
-{
-       int* m_data;
-       int m_size, m_cap;
-public:
-       inline rcIntArray() : m_data(0), m_size(0), m_cap(0) {}
-       inline rcIntArray(int n) : m_data(0), m_size(0), m_cap(n) { m_data = new int[n]; }
-       inline ~rcIntArray() { delete [] m_data; }
-       void resize(int n);
-       inline void push(int item) { resize(m_size+1); m_data[m_size-1] = item; }
-       inline int pop() { if (m_size > 0) m_size--; return m_data[m_size]; }
-       inline const int& operator[](int i) const { return m_data[i]; }
-       inline int& operator[](int i) { return m_data[i]; }
-       inline int size() const { return m_size; }
-};
+/// Allocates a heightfield object using the Recast allocator.
+///  @return A heightfield that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcCreateHeightfield, rcFreeHeightField
+rcHeightfield* rcAllocHeightfield();
 
-enum rcSpanFlags
-{
-       RC_WALKABLE = 0x01,
-       RC_REACHABLE = 0x02,
-};
+/// Frees the specified heightfield object using the Recast allocator.
+///  @param[in] hf  A heightfield allocated using #rcAllocHeightfield
+///  @ingroup recast
+///  @see rcAllocHeightfield
+void rcFreeHeightField(rcHeightfield* hf);
+
+/// Allocates a compact heightfield object using the Recast allocator.
+///  @return A compact heightfield that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcBuildCompactHeightfield, rcFreeCompactHeightfield
+rcCompactHeightfield* rcAllocCompactHeightfield();
+
+/// Frees the specified compact heightfield object using the Recast allocator.
+///  @param[in] chf  A compact heightfield allocated using #rcAllocCompactHeightfield
+///  @ingroup recast
+///  @see rcAllocCompactHeightfield
+void rcFreeCompactHeightfield(rcCompactHeightfield* chf);
+
+/// Allocates a heightfield layer set using the Recast allocator.
+///  @return A heightfield layer set that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcBuildHeightfieldLayers, rcFreeHeightfieldLayerSet
+rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet();
+
+/// Frees the specified heightfield layer set using the Recast allocator.
+///  @param[in] lset  A heightfield layer set allocated using #rcAllocHeightfieldLayerSet
+///  @ingroup recast
+///  @see rcAllocHeightfieldLayerSet
+void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset);
+
+/// Allocates a contour set object using the Recast allocator.
+///  @return A contour set that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcBuildContours, rcFreeContourSet
+rcContourSet* rcAllocContourSet();
+
+/// Frees the specified contour set using the Recast allocator.
+///  @param[in] cset  A contour set allocated using #rcAllocContourSet
+///  @ingroup recast
+///  @see rcAllocContourSet
+void rcFreeContourSet(rcContourSet* cset);
+
+/// Allocates a polygon mesh object using the Recast allocator.
+///  @return A polygon mesh that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcBuildPolyMesh, rcFreePolyMesh
+rcPolyMesh* rcAllocPolyMesh();
+
+/// Frees the specified polygon mesh using the Recast allocator.
+///  @param[in] pmesh  A polygon mesh allocated using #rcAllocPolyMesh
+///  @ingroup recast
+///  @see rcAllocPolyMesh
+void rcFreePolyMesh(rcPolyMesh* pmesh);
+
+/// Allocates a detail mesh object using the Recast allocator.
+///  @return A detail mesh that is ready for initialization, or null on failure.
+///  @ingroup recast
+///  @see rcBuildPolyMeshDetail, rcFreePolyMeshDetail
+rcPolyMeshDetail* rcAllocPolyMeshDetail();
+
+/// Frees the specified detail mesh using the Recast allocator.
+///  @param[in] dmesh  A detail mesh allocated using #rcAllocPolyMeshDetail
+///  @ingroup recast
+///  @see rcAllocPolyMeshDetail
+void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh);
 
-// If heightfield region ID has the following bit set, the region is on border area
-// and excluded from many calculations.
+/// @}
+
+/// Heighfield border flag.
+/// If a heightfield region ID has this bit set, then the region is a border 
+/// region and its spans are considered unwalkable.
+/// (Used during the region and contour build process.)
+/// @see rcCompactSpan::reg
 static const unsigned short RC_BORDER_REG = 0x8000;
 
-// If contour region ID has the following bit set, the vertex will be later
-// removed in order to match the segments and vertices at tile boundaries.
+/// Border vertex flag.
+/// If a region ID has this bit set, then the associated element lies on
+/// a tile border. If a contour vertex's region ID has this bit set, the 
+/// vertex will later be removed in order to match the segments and vertices 
+/// at tile boundaries.
+/// (Used during the build process.)
+/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
 static const int RC_BORDER_VERTEX = 0x10000;
 
-// Compact span neighbour helpers.
-inline int rcGetCon(const rcCompactSpan& s, int dir)
-{
-       return (s.con >> (dir*4)) & 0xf;
-}
+/// Area border flag.
+/// If a region ID has this bit set, then the associated element lies on
+/// the border of an area.
+/// (Used during the region and contour build process.)
+/// @see rcCompactSpan::reg, #rcContour::verts, #rcContour::rverts
+static const int RC_AREA_BORDER = 0x20000;
 
-inline int rcGetDirOffsetX(int dir)
+/// Contour build flags.
+/// @see rcBuildContours
+enum rcBuildContoursFlags
 {
-       const int offset[4] = { -1, 0, 1, 0, };
-       return offset[dir&0x03];
-}
+       RC_CONTOUR_TESS_WALL_EDGES = 0x01,      ///< Tessellate solid (impassable) edges during contour simplification.
+       RC_CONTOUR_TESS_AREA_EDGES = 0x02,      ///< Tessellate edges between areas during contour simplification.
+};
 
-inline int rcGetDirOffsetY(int dir)
-{
-       const int offset[4] = { 0, 1, 0, -1 };
-       return offset[dir&0x03];
-}
+/// Applied to the region id field of contour vertices in order to extract the region id.
+/// The region id field of a vertex may have several flags applied to it.  So the
+/// fields value can't be used directly.
+/// @see rcContour::verts, rcContour::rverts
+static const int RC_CONTOUR_REG_MASK = 0xffff;
+
+/// An value which indicates an invalid index within a mesh.
+/// @note This does not necessarily indicate an error.
+/// @see rcPolyMesh::polys
+static const unsigned short RC_MESH_NULL_IDX = 0xffff;
+
+/// Represents the null area.
+/// When a data element is given this value it is considered to no longer be 
+/// assigned to a usable area.  (E.g. It is unwalkable.)
+static const unsigned char RC_NULL_AREA = 0;
+
+/// The default area id used to indicate a walkable polygon. 
+/// This is also the maximum allowed area id, and the only non-null area id 
+/// recognized by some steps in the build process. 
+static const unsigned char RC_WALKABLE_AREA = 63;
+
+/// The value returned by #rcGetCon if the specified direction is not connected
+/// to another span. (Has no neighbor.)
+static const int RC_NOT_CONNECTED = 0x3f;
+
+/// @name General helper functions
+/// @{
 
-// Common helper functions
+/// Swaps the values of the two parameters.
+///  @param[in,out] a  Value A
+///  @param[in,out] b  Value B
 template<class T> inline void rcSwap(T& a, T& b) { T t = a; a = b; b = t; }
+
+/// Returns the minimum of two values.
+///  @param[in] a  Value A
+///  @param[in] b  Value B
+///  @return The minimum of the two values.
 template<class T> inline T rcMin(T a, T b) { return a < b ? a : b; }
+
+/// Returns the maximum of two values.
+///  @param[in] a  Value A
+///  @param[in] b  Value B
+///  @return The maximum of the two values.
 template<class T> inline T rcMax(T a, T b) { return a > b ? a : b; }
+
+/// Returns the absolute value.
+///  @param[in] a  The value.
+///  @return The absolute value of the specified value.
 template<class T> inline T rcAbs(T a) { return a < 0 ? -a : a; }
+
+/// Return the square of a value.
+///  @param[in] a  The value.
+///  @return The square of the value.
 template<class T> inline T rcSqr(T a) { return a*a; }
+
+/// Clamps the value to the specified range.
+///  @param[in] v   The value to clamp.
+///  @param[in] mn  The minimum permitted return value.
+///  @param[in] mx  The maximum permitted return value.
+///  @return The value, clamped to the specified range.
 template<class T> inline T rcClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); }
 
-// Common vector helper functions.
-inline void vcross(float* dest, const float* v1, const float* v2)
+/// Returns the square root of the value.
+///  @param[in] x  The value.
+///  @return The square root of the vlaue.
+float rcSqrt(float x);
+
+/// Not documented.  Internal use only.
+///  @param[in] x  Not documented.
+///  @return Not documented.
+inline int rcAlign4(int x) { return (x+3) & ~3; }
+
+/// @}
+/// @name Vector helper functions.
+/// @{
+
+/// Derives the cross product of two vectors. (v1 x v2)
+///   @param[out] dest  The cross product. [(x, y, z)]
+///   @param[in]  v1    A Vector [(x, y, z)]
+///   @param[in]  v2    A vector [(x, y, z)]
+inline void rcVcross(float* dest, const float* v1, const float* v2)
 {
        dest[0] = v1[1]*v2[2] - v1[2]*v2[1];
        dest[1] = v1[2]*v2[0] - v1[0]*v2[2];
-       dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; 
+       dest[2] = v1[0]*v2[1] - v1[1]*v2[0];
 }
 
-inline float vdot(const float* v1, const float* v2)
+/// Derives the dot product of two vectors. (v1 . v2)
+///   @param[in]  v1    A Vector [(x, y, z)]
+///   @param[in]  v2    A vector [(x, y, z)]
+///   @return The dot product.
+inline float rcVdot(const float* v1, const float* v2)
 {
        return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
 }
 
-inline void vmad(float* dest, const float* v1, const float* v2, const float s)
+/// Performs a scaled vector addition. (v1 + (v2 * s))
+///   @param[out] dest  The result vector. [(x, y, z)]
+///   @param[in]  v1    The base vector [(x, y, z)]
+///   @param[in]  v2    The vector to scale and add to @p v1. [(x, y, z)]
+///   @param[in]  s     The amount to scale @p v2 by before adding to @p v1.
+inline void rcVmad(float* dest, const float* v1, const float* v2, const float s)
 {
        dest[0] = v1[0]+v2[0]*s;
        dest[1] = v1[1]+v2[1]*s;
        dest[2] = v1[2]+v2[2]*s;
 }
 
-inline void vadd(float* dest, const float* v1, const float* v2)
+/// Performs a vector addition. (@p v1 + @p v2)
+///   @param[out] dest  The result vector. [(x, y, z)]
+///   @param[in]  v1    The base vector [(x, y, z)]
+///   @param[in]  v2    The vector to add to @p v1. [(x, y, z)]
+inline void rcVadd(float* dest, const float* v1, const float* v2)
 {
        dest[0] = v1[0]+v2[0];
        dest[1] = v1[1]+v2[1];
        dest[2] = v1[2]+v2[2];
 }
 
-inline void vsub(float* dest, const float* v1, const float* v2)
+/// Performs a vector subtraction. (@p v1 - @p v2)
+///   @param[out] dest  The result vector. [(x, y, z)]
+///   @param[in]  v1    The base vector [(x, y, z)]
+///   @param[in]  v2    The vector to subtract from @p v1. [(x, y, z)]
+inline void rcVsub(float* dest, const float* v1, const float* v2)
 {
        dest[0] = v1[0]-v2[0];
        dest[1] = v1[1]-v2[1];
        dest[2] = v1[2]-v2[2];
 }
 
-inline void vmin(float* mn, const float* v)
+/// Selects the minimum value of each element from the specified vectors.
+///  @param[in, out] mn  A vector.  (Will be updated with the result.) [(x, y, z)]
+///  @param[in]      v   A vector. [(x, y, z)]
+inline void rcVmin(float* mn, const float* v)
 {
        mn[0] = rcMin(mn[0], v[0]);
        mn[1] = rcMin(mn[1], v[1]);
        mn[2] = rcMin(mn[2], v[2]);
 }
 
-inline void vmax(float* mx, const float* v)
+/// Selects the maximum value of each element from the specified vectors.
+///  @param[in, out] mx  A vector.  (Will be updated with the result.) [(x, y, z)]
+///  @param[in]      v   A vector. [(x, y, z)]
+inline void rcVmax(float* mx, const float* v)
 {
        mx[0] = rcMax(mx[0], v[0]);
        mx[1] = rcMax(mx[1], v[1]);
        mx[2] = rcMax(mx[2], v[2]);
 }
 
-inline void vcopy(float* dest, const float* v)
+/// Performs a vector copy.
+///  @param[out] dest  The result. [(x, y, z)]
+///  @param[in]  v     The vector to copy [(x, y, z)]
+inline void rcVcopy(float* dest, const float* v)
 {
        dest[0] = v[0];
        dest[1] = v[1];
        dest[2] = v[2];
 }
 
-inline float vdist(const float* v1, const float* v2)
+/// Returns the distance between two points.
+///   @param[in] v1  A point. [(x, y, z)]
+///   @param[in] v2  A point. [(x, y, z)]
+///   @return The distance between the two points.
+inline float rcVdist(const float* v1, const float* v2)
 {
        float dx = v2[0] - v1[0];
        float dy = v2[1] - v1[1];
        float dz = v2[2] - v1[2];
-       return sqrtf(dx*dx + dy*dy + dz*dz);
+       return rcSqrt(dx*dx + dy*dy + dz*dz);
 }
 
-inline float vdistSqr(const float* v1, const float* v2)
+/// Returns the square of the distance between two points.
+///   @param[in] v1  A point. [(x, y, z)]
+///   @param[in] v2  A point. [(x, y, z)]
+///   @return The square of the distance between the two points.
+inline float rcVdistSqr(const float* v1, const float* v2)
 {
        float dx = v2[0] - v1[0];
        float dy = v2[1] - v1[1];
@@ -318,184 +705,424 @@ inline float vdistSqr(const float* v1, const float* v2)
        return dx*dx + dy*dy + dz*dz;
 }
 
-inline void vnormalize(float* v)
+/// Normalizes the vector.
+///  @param[in,out] v  The vector to normalize. [(x, y, z)]
+inline void rcVnormalize(float* v)
 {
-       float d = 1.0f / sqrtf(rcSqr(v[0]) + rcSqr(v[1]) + rcSqr(v[2]));
+       float d = 1.0f / rcSqrt(rcSqr(v[0]) + rcSqr(v[1]) + rcSqr(v[2]));
        v[0] *= d;
        v[1] *= d;
        v[2] *= d;
 }
 
-inline bool vequal(const float* p0, const float* p1)
+/// Not documented.  Internal use only.
+///  @param[in] p0  Not documented.
+///  @param[in] p1  Not documented.
+///  @return Not documented.
+inline bool rcVequal(const float* p0, const float* p1)
 {
        static const float thr = rcSqr(1.0f/16384.0f);
-       const float d = vdistSqr(p0, p1);
+       const float d = rcVdistSqr(p0, p1);
        return d < thr;
 }
 
+/// @}
+/// @name Heightfield Functions
+/// @see rcHeightfield
+/// @{
 
-// Calculated bounding box of array of vertices.
-// Params:
-//     verts - (in) array of vertices
-//     nv - (in) vertex count
-//     bmin, bmax - (out) bounding box
+/// Calculates the bounding box of an array of vertices.
+///  @ingroup recast
+///  @param[in]  verts  An array of vertices. [(x, y, z) * @p nv]
+///  @param[in]  nv     The number of vertices in the @p verts array.
+///  @param[out] bmin   The minimum bounds of the AABB. [(x, y, z)] [Units: wu]
+///  @param[out] bmax   The maximum bounds of the AABB. [(x, y, z)] [Units: wu]
 void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax);
 
-// Calculates grid size based on bounding box and grid cell size.
-// Params:
-//     bmin, bmax - (in) bounding box
-//     cs - (in) grid cell size
-//     w - (out) grid width
-//     h - (out) grid height
+/// Calculates the grid size based on the bounding box and grid cell size.
+///  @ingroup recast
+///  @param[in]  bmin  The minimum bounds of the AABB. [(x, y, z)] [Units: wu]
+///  @param[in]  bmax  The maximum bounds of the AABB. [(x, y, z)] [Units: wu]
+///  @param[in]  cs    The xz-plane cell size. [Limit: > 0] [Units: wu]
+///  @param[out] w     The width along the x-axis. [Limit: >= 0] [Units: vx]
+///  @param[out] h     The height along the z-axis. [Limit: >= 0] [Units: vx]
 void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int* h);
 
-// Creates and initializes new heightfield.
-// Params:
-//     hf - (in/out) heightfield to initialize.
-//     width - (in) width of the heightfield.
-//     height - (in) height of the heightfield.
-//     bmin, bmax - (in) bounding box of the heightfield
-//     cs - (in) grid cell size
-//     ch - (in) grid cell height
-bool rcCreateHeightfield(rcHeightfield& hf, int width, int height,
+/// Initializes a new heightfield.
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in,out] hf      The allocated heightfield to initialize.
+///  @param[in]     width   The width of the field along the x-axis. [Limit: >= 0] [Units: vx]
+///  @param[in]     height  The height of the field along the z-axis. [Limit: >= 0] [Units: vx]
+///  @param[in]     bmin    The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu]
+///  @param[in]     bmax    The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu]
+///  @param[in]     cs      The xz-plane cell size to use for the field. [Limit: > 0] [Units: wu]
+///  @param[in]     ch      The y-axis cell size to use for field. [Limit: > 0] [Units: wu]
+bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int height,
                                                 const float* bmin, const float* bmax,
                                                 float cs, float ch);
 
-// Sets the WALKABLE flag for every triangle whose slope is below
-// the maximun walkable slope angle.
-// Params:
-//     walkableSlopeAngle - (in) maximun slope angle in degrees.
-//     verts - (in) array of vertices
-//     nv - (in) vertex count
-//     tris - (in) array of triangle vertex indices
-//     nt - (in) triangle count
-//     flags - (out) array of triangle flags
-void rcMarkWalkableTriangles(const float walkableSlopeAngle,
-                                                        const float* verts, int nv,
-                                                        const int* tris, int nt,
-                                                        unsigned char* flags); 
-
-// Rasterizes a triangle into heightfield spans.
-// Params:
-//     v0,v1,v2 - (in) the vertices of the triangle.
-//     flags - (in) triangle flags (uses WALKABLE)
-//     solid - (in) heighfield where the triangle is rasterized
-void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
-                                                unsigned char flags, rcHeightfield& solid);
-
-// Rasterizes the triangles into heightfield spans.
-// Params:
-//     verts - (in) array of vertices
-//     nv - (in) vertex count
-//     tris - (in) array of triangle vertex indices
-//     norms - (in) array of triangle normals
-//     flags - (in) array of triangle flags (uses WALKABLE)
-//     nt - (in) triangle count
-//     solid - (in) heighfield where the triangles are rasterized
-void rcRasterizeTriangles(const float* verts, int nv,
-                                                 const int* tris, const unsigned char* flags, int nt,
-                                                 rcHeightfield& solid);
-
-// Removes WALKABLE flag from all spans that are at ledges. This filtering
-// removes possible overestimation of the conservative voxelization so that
-// the resulting mesh will not have regions hanging in air over ledges.
-// Params:
-//     walkableHeight - (in) minimum height where the agent can still walk
-//     walkableClimb - (in) maximum height between grid cells the agent can climb
-//     solid - (in/out) heightfield describing the solid space
-void rcFilterLedgeSpans(const int walkableHeight,
-                                               const int walkableClimb,
-                                               rcHeightfield& solid);
-
-// Removes WALKABLE flag from all spans which have smaller than
-// 'walkableHeight' clearane above them.
-// Params:
-//     walkableHeight - (in) minimum height where the agent can still walk
-//     solid - (in/out) heightfield describing the solid space
-void rcFilterWalkableLowHeightSpans(int walkableHeight,
-                                                                       rcHeightfield& solid);
-
-// Marks spans which are reachable from any of the topmost spans.
-// Params:
-//     walkableHeight - (in) minimum height where the agent can still walk
-//     walkableClimb - (in) maximum height between grid cells the agent can climb
-//     solid - (in/out) heightfield describing the solid space
-// Returns false if operation ran out of memory.
-bool rcMarkReachableSpans(const int walkableHeight,
-                                                 const int walkableClimb,
-                                                 rcHeightfield& solid);
-
-// Builds compact representation of the heightfield.
-// Params:
-//     walkableHeight - (in) minimum height where the agent can still walk
-//     walkableClimb - (in) maximum height between grid cells the agent can climb
-//     hf - (in) heightfield to be compacted
-//     chf - (out) compact heightfield representing the open space.
-// Returns false if operation ran out of memory.
-bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb,
-                                                          unsigned char flags,
-                                                          rcHeightfield& hf,
-                                                          rcCompactHeightfield& chf);
-
-// Builds distance field and stores it into the combat heightfield.
-// Params:
-//     chf - (in/out) compact heightfield representing the open space.
-// Returns false if operation ran out of memory.
-bool rcBuildDistanceField(rcCompactHeightfield& chf);
-
-// Divides the walkable heighfied into simple regions.
-// Each region has only one contour and no overlaps.
-// The regions are stored in the compact heightfield 'reg' field.
-// The regions will be shrinked by the radius of the agent.
-// The process sometimes creates small regions. The parameter
-// 'minRegionSize' specifies the smallest allowed regions size.
-// If the area of a regions is smaller than allowed, the regions is
-// removed or merged to neighbour region. 
-// Params:
-//     chf - (in/out) compact heightfield representing the open space.
-//     walkableRadius - (in) the radius of the agent.
-//     minRegionSize - (in) the smallest allowed regions size.
-//     maxMergeRegionSize - (in) the largest allowed regions size which can be merged.
-// Returns false if operation ran out of memory.
-bool rcBuildRegions(rcCompactHeightfield& chf,
-                                       int walkableRadius, int borderSize,
-                                       int minRegionSize, int mergeRegionSize);
-
-// Builds simplified contours from the regions outlines.
-// Params:
-//     chf - (in) compact heightfield which has regions set.
-//     maxError - (in) maximum allowed distance between simplified countour and cells.
-//     maxEdgeLen - (in) maximum allowed contour edge length in cells.
-//     cset - (out) Resulting contour set.
-// Returns false if operation ran out of memory.
-bool rcBuildContours(rcCompactHeightfield& chf,
+/// Sets the area id of all triangles with a slope below the specified value
+/// to #RC_WALKABLE_AREA.
+///  @ingroup recast
+///  @param[in,out] ctx                 The build context to use during the operation.
+///  @param[in]     walkableSlopeAngle  The maximum slope that is considered walkable. [Limits: 0 <= value < 90] 
+///                                     [Units: Degrees]
+///  @param[in]     verts               The vertices. [(x, y, z) * @p nv]
+///  @param[in]     nv                  The number of vertices.
+///  @param[in]     tris                The triangle vertex indices. [(vertA, vertB, vertC) * @p nt]
+///  @param[in]     nt                  The number of triangles.
+///  @param[out]    areas               The triangle area ids. [Length: >= @p nt]
+void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
+                                                        const int* tris, int nt, unsigned char* areas); 
+
+/// Sets the area id of all triangles with a slope greater than or equal to the specified value to #RC_NULL_AREA.
+///  @ingroup recast
+///  @param[in,out] ctx                 The build context to use during the operation.
+///  @param[in]     walkableSlopeAngle  The maximum slope that is considered walkable. [Limits: 0 <= value < 90] 
+///                                     [Units: Degrees]
+///  @param[in]     verts               The vertices. [(x, y, z) * @p nv]
+///  @param[in]     nv                  The number of vertices.
+///  @param[in]     tris                The triangle vertex indices. [(vertA, vertB, vertC) * @p nt]
+///  @param[in]     nt                  The number of triangles.
+///  @param[out]    areas               The triangle area ids. [Length: >= @p nt]
+void rcClearUnwalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
+                                                               const int* tris, int nt, unsigned char* areas); 
+
+/// Adds a span to the specified heightfield.
+///  @ingroup recast
+///  @param[in,out] ctx           The build context to use during the operation.
+///  @param[in,out] hf            An initialized heightfield.      
+///  @param[in]     x             The width index where the span is to be added. 
+///                               [Limits: 0 <= value < rcHeightfield::width]
+///  @param[in]     y             The height index where the span is to be added. 
+///                               [Limits: 0 <= value < rcHeightfield::height]
+///  @param[in]     smin          The minimum height of the span. [Limit: < @p smax] [Units: vx]
+///  @param[in]     smax          The maximum height of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT] [Units: vx]
+///  @param[in]     area          The area id of the span. [Limit: <= #RC_WALKABLE_AREA)
+///  @param[in]     flagMergeThr  The merge theshold. [Limit: >= 0] [Units: vx]
+void rcAddSpan(rcContext* ctx, rcHeightfield& hf, const int x, const int y,
+                          const unsigned short smin, const unsigned short smax,
+                          const unsigned char area, const int flagMergeThr);
+
+/// Rasterizes a triangle into the specified heightfield.
+///  @ingroup recast
+///  @param[in,out]  ctx           The build context to use during the operation.
+///  @param[in]      v0            Triangle vertex 0 [(x, y, z)]
+///  @param[in]      v1            Triangle vertex 1 [(x, y, z)]
+///  @param[in]      v2            Triangle vertex 2 [(x, y, z)]
+///  @param[in]      area          The area id of the triangle. [Limit: <= #RC_WALKABLE_AREA]
+///  @param[in, out] solid         An initialized heightfield.
+///  @param[in]      flagMergeThr  The distance where the walkable flag is favored over the non-walkable flag. 
+///                                [Limit: >= 0] [Units: vx]
+void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2,
+                                                const unsigned char area, rcHeightfield& solid,
+                                                const int flagMergeThr = 1);
+
+/// Rasterizes an indexed triangle mesh into the specified heightfield.
+///  @ingroup recast
+///  @param[in,out]  ctx           The build context to use during the operation.
+///  @param[in]      verts         The vertices. [(x, y, z) * @p nv]
+///  @param[in]      nv            The number of vertices.
+///  @param[in]      tris          The triangle indices. [(vertA, vertB, vertC) * @p nt]
+///  @param[in]      areas         The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt]
+///  @param[in]      nt            The number of triangles.
+///  @param[in, out] solid         An initialized heightfield.
+///  @param[in]      flagMergeThr  The distance where the walkable flag is favored over the non-walkable flag. 
+///                                [Limit: >= 0] [Units: vx]
+void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv,
+                                                 const int* tris, const unsigned char* areas, const int nt,
+                                                 rcHeightfield& solid, const int flagMergeThr = 1);
+
+/// Rasterizes an indexed triangle mesh into the specified heightfield.
+///  @ingroup recast
+///  @param[in,out]  ctx           The build context to use during the operation.
+///  @param[in]      verts         The vertices. [(x, y, z) * @p nv]
+///  @param[in]      nv            The number of vertices.
+///  @param[in]      tris          The triangle indices. [(vertA, vertB, vertC) * @p nt]
+///  @param[in]      areas         The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt]
+///  @param[in]      nt            The number of triangles.
+///  @param[in, out] solid         An initialized heightfield.
+///  @param[in]      flagMergeThr  The distance where the walkable flag is favored over the non-walkable flag. 
+///                                [Limit: >= 0] [Units: vx]
+void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv,
+                                                 const unsigned short* tris, const unsigned char* areas, const int nt,
+                                                 rcHeightfield& solid, const int flagMergeThr = 1);
+
+/// Rasterizes triangles into the specified heightfield.
+///  @ingroup recast
+///  @param[in,out]  ctx           The build context to use during the operation.
+///  @param[in]      verts         The triangle vertices. [(ax, ay, az, bx, by, bz, cx, by, cx) * @p nt]
+///  @param[in]      areas         The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt]
+///  @param[in]      nt            The number of triangles.
+///  @param[in, out] solid         An initialized heightfield.
+///  @param[in]      flagMergeThr  The distance where the walkable flag is favored over the non-walkable flag. 
+///                                [Limit: >= 0] [Units: vx]
+void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt,
+                                                 rcHeightfield& solid, const int flagMergeThr = 1);
+
+/// Marks non-walkable spans as walkable if their maximum is within @p walkableClimp of a walkable neihbor. 
+///  @ingroup recast
+///  @param[in,out] ctx            The build context to use during the operation.
+///  @param[in]     walkableClimb  Maximum ledge height that is considered to still be traversable. 
+///                                [Limit: >=0] [Units: vx]
+///  @param[in,out] solid          A fully built heightfield.  (All spans have been added.)
+void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid);
+
+/// Marks spans that are ledges as not-walkable. 
+///  @ingroup recast
+///  @param[in,out] ctx             The build context to use during the operation.
+///  @param[in]     walkableHeight  Minimum floor to 'ceiling' height that will still allow the floor area to 
+///                                 be considered walkable. [Limit: >= 3] [Units: vx]
+///  @param[in]     walkableClimb   Maximum ledge height that is considered to still be traversable. 
+///                                 [Limit: >=0] [Units: vx]
+///  @param[in,out] solid          A fully built heightfield.  (All spans have been added.)
+void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight,
+                                               const int walkableClimb, rcHeightfield& solid);
+
+/// Marks walkable spans as not walkable if the clearence above the span is less than the specified height. 
+///  @ingroup recast
+///  @param[in,out] ctx             The build context to use during the operation.
+///  @param[in]     walkableHeight  Minimum floor to 'ceiling' height that will still allow the floor area to 
+///                                 be considered walkable. [Limit: >= 3] [Units: vx]
+///  @param[in,out] solid           A fully built heightfield.  (All spans have been added.)
+void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid);
+
+/// Returns the number of spans contained in the specified heightfield.
+///  @ingroup recast
+///  @param[in,out] ctx  The build context to use during the operation.
+///  @param[in]     hf   An initialized heightfield.
+///  @returns The number of spans in the heightfield.
+int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf);
+
+/// @}
+/// @name Compact Heightfield Functions
+/// @see rcCompactHeightfield
+/// @{
+
+/// Builds a compact heightfield representing open space, from a heightfield representing solid space.
+///  @ingroup recast
+///  @param[in,out] ctx             The build context to use during the operation.
+///  @param[in]     walkableHeight  Minimum floor to 'ceiling' height that will still allow the floor area 
+///                                 to be considered walkable. [Limit: >= 3] [Units: vx]
+///  @param[in]     walkableClimb   Maximum ledge height that is considered to still be traversable. 
+///                                 [Limit: >=0] [Units: vx]
+///  @param[in]     hf              The heightfield to be compacted.
+///  @param[out]    chf             The resulting compact heightfield. (Must be pre-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb,
+                                                          rcHeightfield& hf, rcCompactHeightfield& chf);
+
+/// Erodes the walkable area within the heightfield by the specified radius. 
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in]     radius  The radius of erosion. [Limits: 0 < value < 255] [Units: vx]
+///  @param[in,out] chf     The populated compact heightfield to erode.
+///  @returns True if the operation completed successfully.
+bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf);
+
+/// Applies a median filter to walkable area types (based on area id), removing noise.
+///  @ingroup recast
+///  @param[in,out] ctx  The build context to use during the operation.
+///  @param[in,out] chf  A populated compact heightfield.
+///  @returns True if the operation completed successfully.
+bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf);
+
+/// Applies an area id to all spans within the specified bounding box. (AABB) 
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in]     bmin    The minimum of the bounding box. [(x, y, z)]
+///  @param[in]     bmax    The maximum of the bounding box. [(x, y, z)]
+///  @param[in]     areaId  The area id to apply. [Limit: <= #RC_WALKABLE_AREA]
+///  @param[in,out] chf     A populated compact heightfield.
+void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
+                                  rcCompactHeightfield& chf);
+
+/// Applies the area id to the all spans within the specified convex polygon. 
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in]     verts   The vertices of the polygon [Fomr: (x, y, z) * @p nverts]
+///  @param[in]     nverts  The number of vertices in the polygon.
+///  @param[in]     hmin    The height of the base of the polygon.
+///  @param[in]     hmax    The height of the top of the polygon.
+///  @param[in]     areaId  The area id to apply. [Limit: <= #RC_WALKABLE_AREA]
+///  @param[in,out] chf     A populated compact heightfield.
+void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
+                                                 const float hmin, const float hmax, unsigned char areaId,
+                                                 rcCompactHeightfield& chf);
+
+/// Applies the area id to all spans within the specified cylinder.
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in]     pos     The center of the base of the cylinder. [Form: (x, y, z)] 
+///  @param[in]     r       The radius of the cylinder.
+///  @param[in]     h       The height of the cylinder.
+///  @param[in]     areaId  The area id to apply. [Limit: <= #RC_WALKABLE_AREA]
+///  @param[in,out] chf     A populated compact heightfield.
+void rcMarkCylinderArea(rcContext* ctx, const float* pos,
+                                               const float r, const float h, unsigned char areaId,
+                                               rcCompactHeightfield& chf);
+
+/// Builds the distance field for the specified compact heightfield. 
+///  @ingroup recast
+///  @param[in,out] ctx  The build context to use during the operation.
+///  @param[in,out] chf  A populated compact heightfield.
+///  @returns True if the operation completed successfully.
+bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf);
+
+/// Builds region data for the heightfield using watershed partitioning. 
+///  @ingroup recast
+///  @param[in,out] ctx          The build context to use during the operation.
+///  @param[in,out] chf          A populated compact heightfield.
+///  @param[in] borderSize       The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]
+///  @param[in] minRegionArea    The minimum number of cells allowed to form isolated island areas. [Limit: >=0] 
+///                              [Units: vx].
+///  @param[in] mergeRegionArea  Any regions with a span count smaller than this value will, if possible, 
+///                              be merged with larger regions. [Limit: >=0] [Units: vx] 
+///  @returns True if the operation completed successfully.
+bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
+                                       const int borderSize, const int minRegionArea, const int mergeRegionArea);
+
+/// Builds region data for the heightfield using simple monotone partitioning.
+///  @ingroup recast 
+///  @param[in,out] ctx          The build context to use during the operation.
+///  @param[in,out] chf          A populated compact heightfield.
+///  @param[in] borderSize       The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]
+///  @param[in] minRegionArea    The minimum number of cells allowed to form isolated island areas. [Limit: >=0] 
+///                              [Units: vx].
+///  @param[in] mergeRegionArea  Any regions with a span count smaller than this value will, if possible, 
+///                              be merged with larger regions. [Limit: >=0] [Units: vx] 
+///  @returns True if the operation completed successfully.
+bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
+                                                       const int borderSize, const int minRegionArea, const int mergeRegionArea);
+
+
+/// Sets the neighbor connection data for the specified direction.
+///  @param[in] s    The span to update.
+///  @param[in] dir  The direction to set. [Limits: 0 <= value < 4]
+///  @param[in] i    The index of the neighbor span.
+inline void rcSetCon(rcCompactSpan& s, int dir, int i)
+{
+       const unsigned int shift = (unsigned int)dir*6;
+       unsigned int con = s.con;
+       s.con = (con & ~(0x3f << shift)) | (((unsigned int)i & 0x3f) << shift);
+}
+
+/// Gets neighbor connection data for the specified direction.
+///  @param[in] s    The span to check.
+///  @param[in] dir  The direction to check. [Limits: 0 <= value < 4]
+///  @return The neighbor connection data for the specified direction,
+///          or #RC_NOT_CONNECTED if there is no connection.
+inline int rcGetCon(const rcCompactSpan& s, int dir)
+{
+       const unsigned int shift = (unsigned int)dir*6;
+       return (s.con >> shift) & 0x3f;
+}
+
+/// Gets the standard width (x-axis) offset for the specified direction.
+///  @param[in] dir  The direction. [Limits: 0 <= value < 4]
+///  @return The width offset to apply to the current cell position to move
+///          in the direction.
+inline int rcGetDirOffsetX(int dir)
+{
+       const int offset[4] = { -1, 0, 1, 0, };
+       return offset[dir&0x03];
+}
+
+/// Gets the standard height (z-axis) offset for the specified direction.
+///  @param[in] dir  The direction. [Limits: 0 <= value < 4]
+///  @return The height offset to apply to the current cell position to move
+///          in the direction.
+inline int rcGetDirOffsetY(int dir)
+{
+       const int offset[4] = { 0, 1, 0, -1 };
+       return offset[dir&0x03];
+}
+
+/// @}
+/// @name Layer, Contour, Polymesh, and Detail Mesh Functions
+/// @see rcHeightfieldLayer, rcContourSet, rcPolyMesh, rcPolyMeshDetail
+/// @{
+
+/// Builds a layer set from the specified compact heightfield.
+///  @ingroup recast
+///  @param[in,out] ctx             The build context to use during the operation.
+///  @param[in]     chf             A fully built compact heightfield.
+///  @param[in]     borderSize      The size of the non-navigable border around the heightfield. [Limit: >=0] 
+///                                 [Units: vx]
+///  @param[in]     walkableHeight  Minimum floor to 'ceiling' height that will still allow the floor area 
+///                                 to be considered walkable. [Limit: >= 3] [Units: vx]
+///  @param[out]    lset            The resulting layer set. (Must be pre-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf, 
+                                                         const int borderSize, const int walkableHeight,
+                                                         rcHeightfieldLayerSet& lset);
+
+/// Builds a contour set from the region outlines in the provided compact heightfield.
+///  @ingroup recast
+///  @param[in,out] ctx      The build context to use during the operation.
+///  @param[in] chf          A fully built compact heightfield.
+///  @param[in] maxError     The maximum distance a simplfied contour's border edges should deviate 
+///                          the original raw contour. [Limit: >=0] [Units: wu]
+///  @param[in] maxEdgeLen   The maximum allowed length for contour edges along the border of the mesh. 
+///                          [Limit: >=0] [Units: vx]
+///  @param[out] cset        The resulting contour set. (Must be pre-allocated.)
+///  @param[in]  buildFlags  The build flags. (See: #rcBuildContoursFlags)
+///  @returns True if the operation completed successfully.
+bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
                                         const float maxError, const int maxEdgeLen,
-                                        rcContourSet& cset);
-
-// Builds connected convex polygon mesh from contour polygons.
-// Params:
-//     cset - (in) contour set.
-//     nvp - (in) maximum number of vertices per polygon.
-//     mesh - (out) poly mesh.
-// Returns false if operation ran out of memory.
-bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh);
-
-bool rcMergePolyMeshes(rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh);
-
-// Builds detail triangle mesh for each polygon in the poly mesh.
-// Params:
-//     mesh - (in) poly mesh to detail.
-//     chf - (in) compacy height field, used to query height for new vertices.
-//  sampleDist - (in) spacing between height samples used to generate more detail into mesh.
-//  sampleMaxError - (in) maximum allowed distance between simplified detail mesh and height sample.
-//     pmdtl - (out) detail mesh.
-// Returns false if operation ran out of memory.
-bool rcBuildPolyMeshDetail(const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
+                                        rcContourSet& cset, const int flags = RC_CONTOUR_TESS_WALL_EDGES);
+
+/// Builds a polygon mesh from the provided contours.
+///  @ingroup recast
+///  @param[in,out] ctx     The build context to use during the operation.
+///  @param[in]     cset    A fully built contour set.
+///  @param[in]     nvp     The maximum number of vertices allowed for polygons generated during the 
+///                         contour to polygon conversion process. [Limit: >= 3] 
+///  @param[out]    mesh    The resulting polygon mesh. (Must be re-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh);
+
+/// Merges multiple polygon meshes into a single mesh.
+///  @ingroup recast
+///  @param[in,out] ctx      The build context to use during the operation.
+///  @param[in]     meshes   An array of polygon meshes to merge. [Size: @p nmeshes]
+///  @param[in]     nmeshes  The number of polygon meshes in the meshes array.
+///  @param[in]     mesh     The resulting polygon mesh. (Must be pre-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh);
+
+/// Builds a detail mesh from the provided polygon mesh.
+///  @ingroup recast
+///  @param[in,out] ctx             The build context to use during the operation.
+///  @param[in]     mesh            A fully built polygon mesh.
+///  @param[in]     chf             The compact heightfield used to build the polygon mesh.
+///  @param[in]     sampleDist      Sets the distance to use when samping the heightfield. [Limit: >=0] [Units: wu]
+///  @param[in]     sampleMaxError  The maximum distance the detail mesh surface should deviate from 
+///                                 heightfield data. [Limit: >=0] [Units: wu]
+///  @param[out]    dmesh           The resulting detail mesh.  (Must be pre-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
                                                   const float sampleDist, const float sampleMaxError,
                                                   rcPolyMeshDetail& dmesh);
 
-bool rcMergePolyMeshDetails(rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh);
+/// Merges multiple detail meshes into a single detail mesh.
+///  @ingroup recast
+///  @param[in,out] ctx      The build context to use during the operation.
+///  @param[in]     meshes   An array of detail meshes to merge. [Size: @p nmeshes]
+///  @param[in]     nmeshes  The number of detail meshes in the meshes array.
+///  @param[out]    mesh     The resulting detail mesh. (Must be pre-allocated.)
+///  @returns True if the operation completed successfully.
+bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh);
 
 bool buildMeshAdjacency(unsigned short* polys, const int npolys, const int nverts, const int vertsPerPoly);
 
+/// @}
+
 #endif // RECAST_H
+
+///////////////////////////////////////////////////////////////////////////
+
+// Due to the large amount of detail documentation for this file, 
+// the content normally located at the end of the header file has been separated
+// out to a file in /Docs/Extern.
diff --git a/extern/recastnavigation/Recast/Include/RecastAlloc.h b/extern/recastnavigation/Recast/Include/RecastAlloc.h
new file mode 100644 (file)
index 0000000..0038c1a
--- /dev/null
@@ -0,0 +1,122 @@
+//
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+
+#ifndef RECASTALLOC_H
+#define RECASTALLOC_H
+
+/// Provides hint values to the memory allocator on how long the
+/// memory is expected to be used.
+enum rcAllocHint
+{
+       RC_ALLOC_PERM,          ///< Memory will persist after a function call.
+       RC_ALLOC_TEMP           ///< Memory used temporarily within a function.
+};
+
+/// A memory allocation function.
+//  @param[in] size         The size, in bytes of memory, to allocate.
+//  @param[in] rcAllocHint  A hint to the allocator on how long the memory is expected to be in use.
+//  @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
+///  @see rcAllocSetCustom
+typedef void* (rcAllocFunc)(int size, rcAllocHint hint);
+
+/// A memory deallocation function.
+/// @see rcAllocSetCustom
+//  @param[in] ptr 
+typedef void (rcFreeFunc)(void* ptr);
+
+/// Sets the base custom allocation functions to be used by Recast.
+///  @param[in] allocFunc  The memory allocation function to be used by #rcAlloc
+///  @param[in] freeFunc   The memory de-allocation function to be used by #rcFree
+void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc);
+
+/// Allocates a memory block.
+///  @param[in] size  The size, in bytes of memory, to allocate.
+///  @param[in] hint  A hint to the allocator on how long the memory is expected to be in use.
+///  @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
+void* rcAlloc(int size, rcAllocHint hint);
+
+/// Deallocates a memory block.
+///  @param[in] ptr A pointer to a memory block previously allocated using #rcAlloc.
+void rcFree(void* ptr);
+
+
+/// A simple dynamic array of integers.
+class rcIntArray
+{
+       int* m_data;
+       int m_size, m_cap;
+       inline rcIntArray(const rcIntArray&);
+       inline rcIntArray& operator=(const rcIntArray&);
+public:
+
+       /// Constructs an instance with an initial array size of zero.
+       inline rcIntArray() : m_data(0), m_size(0), m_cap(0) {}
+
+       /// Constructs an instance initialized to the specified size.
+       ///  @param[in] n The initial size of the integer array.
+       inline rcIntArray(int n) : m_data(0), m_size(0), m_cap(0) { resize(n); }
+       inline ~rcIntArray() { rcFree(m_data); }
+
+       /// Specifies the new size of the integer array.
+       ///  @param[in] n  The new size of the integer array.
+       void resize(int n);
+
+       /// Push the specified integer onto the end of the array and increases the size by one.
+       ///  @param[in] item  The new value.
+       inline void push(int item) { resize(m_size+1); m_data[m_size-1] = item; }
+
+       /// Returns the value at the end of the array and reduces the size by one.
+       ///  @return The value at the end of the array.
+       inline int pop() { if (m_size > 0) m_size--; return m_data[m_size]; }
+
+       /// The value at the specified array index.
+       /// @warning Does not provide overflow protection.
+       ///  @param[in] i  The index of the value.
+       inline const int& operator[](int i) const { return m_data[i]; }
+
+       /// The value at the specified array index.
+       /// @warning Does not provide overflow protection.
+       ///  @param[in] i  The index of the value.
+       inline int& operator[](int i) { return m_data[i]; }
+
+       /// The current size of the integer array.
+       inline int size() const { return m_size; }
+};
+
+/// A simple helper class used to delete an array when it goes out of scope.
+/// @note This class is rarely if ever used by the end user.
+template<class T> class rcScopedDelete
+{
+       T* ptr;
+       inline T* operator=(T* p);
+public:
+
+       /// Constructs an instance with a null pointer.
+       inline rcScopedDelete() : ptr(0) {}
+
+       /// Constructs an instance with the specified pointer.
+       ///  @param[in] p  An pointer to an allocated array.
+       inline rcScopedDelete(T* p) : ptr(p) {}
+       inline ~rcScopedDelete() { rcFree(ptr); }
+
+       /// The root array pointer.
+       ///  @return The root array pointer.
+       inline operator T*() { return ptr; }
+};
+
+#endif
diff --git a/extern/recastnavigation/Recast/Include/RecastAssert.h b/extern/recastnavigation/Recast/Include/RecastAssert.h
new file mode 100644 (file)
index 0000000..b58b8fc
--- /dev/null
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+
+#ifndef RECASTASSERT_H
+#define RECASTASSERT_H
+
+// Note: This header file's only purpose is to include define assert.
+// Feel free to change the file and include your own implementation instead.
+
+#ifdef NDEBUG
+// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/
+#      define rcAssert(x) do { (void)sizeof(x); } while(__LINE__==-1,false)  
+#else
+#      include <assert.h> 
+#      define rcAssert assert
+#endif
+
+#endif // RECASTASSERT_H
index 0db26c2..283cf0c 100644 (file)
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2009 Mikko Mononen memon@inside.org
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
 //
 // This software is provided 'as-is', without any express or implied
 // warranty.  In no event will the authors be held liable for any damages
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include "Recast.h"
-#include "RecastLog.h"
-#include "RecastTimer.h"
+#include "RecastAlloc.h"
+#include "RecastAssert.h"
 
+float rcSqrt(float x)
+{
+       return sqrtf(x);
+}
+
+/// @class rcContext
+/// @par
+///
+/// This class does not provide logging or timer functionality on its 
+/// own.  Both must be provided by a concrete implementation 
+/// by overriding the protected member functions.  Also, this class does not 
+/// provide an interface for extracting log messages. (Only adding them.) 
+/// So concrete implementations must provide one.
+///
+/// If no logging or timers are required, just pass an instance of this 
+/// class through the Recast build process.
+///
 
-void rcIntArray::resize(int n)
+/// @par
+///
+/// Example:
+/// @code
+/// // Where ctx is an instance of rcContext and filepath is a char array.
+/// ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath);
+/// @endcode
+void rcContext::log(const rcLogCategory category, const char* format, ...)
 {
-       if (n > m_cap)
+       if (!m_logEnabled)
+               return;
+       static const int MSG_SIZE = 512;
+       char msg[MSG_SIZE];
+       va_list ap;
+       va_start(ap, format);
+       int len = vsnprintf(msg, MSG_SIZE, format, ap);
+       if (len >= MSG_SIZE)
        {
-               if (!m_cap) m_cap = 8;
-               while (m_cap < n) m_cap *= 2;
-               int* newData = new int[m_cap];
-               if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int));
-               delete [] m_data;
-               m_data = newData;
+               len = MSG_SIZE-1;
+               msg[MSG_SIZE-1] = '\0';
        }
-       m_size = n;
+       va_end(ap);
+       doLog(category, msg, len);
+}
+
+rcHeightfield* rcAllocHeightfield()
+{
+       rcHeightfield* hf = (rcHeightfield*)rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM);
+       memset(hf, 0, sizeof(rcHeightfield));
+       return hf;
+}
+
+void rcFreeHeightField(rcHeightfield* hf)
+{
+       if (!hf) return;
+       // Delete span array.
+       rcFree(hf->spans);
+       // Delete span pools.
+       while (hf->pools)
+       {
+               rcSpanPool* next = hf->pools->next;
+               rcFree(hf->pools);
+               hf->pools = next;
+       }
+       rcFree(hf);
+}
+
+rcCompactHeightfield* rcAllocCompactHeightfield()
+{
+       rcCompactHeightfield* chf = (rcCompactHeightfield*)rcAlloc(sizeof(rcCompactHeightfield), RC_ALLOC_PERM);
+       memset(chf, 0, sizeof(rcCompactHeightfield));
+       return chf;
+}
+
+void rcFreeCompactHeightfield(rcCompactHeightfield* chf)
+{
+       if (!chf) return;
+       rcFree(chf->cells);
+       rcFree(chf->spans);
+       rcFree(chf->dist);
+       rcFree(chf->areas);
+       rcFree(chf);
+}
+
+
+rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
+{
+       rcHeightfieldLayerSet* lset = (rcHeightfieldLayerSet*)rcAlloc(sizeof(rcHeightfieldLayerSet), RC_ALLOC_PERM);
+       memset(lset, 0, sizeof(rcHeightfieldLayerSet));
+       return lset;
+}
+
+void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset)
+{
+       if (!lset) return;
+       for (int i = 0; i < lset->nlayers; ++i)
+       {
+               rcFree(lset->layers[i].heights);
+               rcFree(lset->layers[i].areas);
+               rcFree(lset->layers[i].cons);
+       }
+       rcFree(lset->layers);
+       rcFree(lset);
+}
+
+
+rcContourSet* rcAllocContourSet()
+{
+       rcContourSet* cset = (rcContourSet*)rcAlloc(sizeof(rcContourSet), RC_ALLOC_PERM);
+       memset(cset, 0, sizeof(rcContourSet));
+       return cset;
+}
+
+void rcFreeContourSet(rcContourSet* cset)
+{
+       if (!cset) return;
+       for (int i = 0; i < cset->nconts; ++i)
+       {
+               rcFree(cset->conts[i].verts);
+               rcFree(cset->conts[i].rverts);
+       }
+       rcFree(cset->conts);
+       rcFree(cset);
+}
+
+rcPolyMesh* rcAllocPolyMesh()
+{
+       rcPolyMesh* pmesh = (rcPolyMesh*)rcAlloc(sizeof(rcPolyMesh), RC_ALLOC_PERM);
+       memset(pmesh, 0, sizeof(rcPolyMesh));
+       return pmesh;
+}
+
+void rcFreePolyMesh(rcPolyMesh* pmesh)
+{
+       if (!pmesh) return;
+       rcFree(pmesh->verts);
+       rcFree(pmesh->polys);
+       rcFree(pmesh->regs);
+       rcFree(pmesh->flags);
+       rcFree(pmesh->areas);
+       rcFree(pmesh);
+}
+
+rcPolyMeshDetail* rcAllocPolyMeshDetail()
+{
+       rcPolyMeshDetail* dmesh = (rcPolyMeshDetail*)rcAlloc(sizeof(rcPolyMeshDetail), RC_ALLOC_PERM);
+       memset(dmesh, 0, sizeof(rcPolyMeshDetail));
+       return dmesh;
+}
+
+void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh)
+{
+       if (!dmesh) return;
+       rcFree(dmesh->meshes);
+       rcFree(dmesh->verts);
+       rcFree(dmesh->tris);
+       rcFree(dmesh);
 }
 
 void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax)
 {
        // Calculate bounding box.
-       vcopy(bmin, verts);
-       vcopy(bmax, verts);
+       rcVcopy(bmin, verts);
+       rcVcopy(bmax, verts);
        for (int i = 1; i < nv; ++i)
        {
                const float* v = &verts[i*3];
-               vmin(bmin, v);
-               vmax(bmax, v);
+               rcVmin(bmin, v);
+               rcVmax(bmax, v);
        }
 }
 
@@ -60,17 +203,25 @@ void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int*
        *h = (int)((bmax[2] - bmin[2])/cs+0.5f);
 }
 
-bool rcCreateHeightfield(rcHeightfield& hf, int width, int height,
+/// @par
+///
+/// See the #rcConfig documentation for more information on the configuration parameters.
+/// 
+/// @see rcAllocHeightfield, rcHeightfield 
+bool rcCreateHeightfield(rcContext* /*ctx*/, rcHeightfield& hf, int width, int height,
                                                 const float* bmin, const float* bmax,
                                                 float cs, float ch)
 {
+       // TODO: VC complains about unref formal variable, figure out a way to handle this better.
+//     rcAssert(ctx);
+       
        hf.width = width;
        hf.height = height;
-       hf.spans = new rcSpan*[hf.width*hf.height];
-       vcopy(hf.bmin, bmin);
-       vcopy(hf.bmax, bmax);
+       rcVcopy(hf.bmin, bmin);
+       rcVcopy(hf.bmax, bmax);
        hf.cs = cs;
        hf.ch = ch;
+       hf.spans = (rcSpan**)rcAlloc(sizeof(rcSpan*)*hf.width*hf.height, RC_ALLOC_PERM);
        if (!hf.spans)
                return false;
        memset(hf.spans, 0, sizeof(rcSpan*)*hf.width*hf.height);
@@ -80,18 +231,29 @@ bool rcCreateHeightfield(rcHeightfield& hf, int width, int height,
 static void calcTriNormal(const float* v0, const float* v1, const float* v2, float* norm)
 {
        float e0[3], e1[3];
-       vsub(e0, v1, v0);
-       vsub(e1, v2, v0);
-       vcross(norm, e0, e1);
-       vnormalize(norm);
+       rcVsub(e0, v1, v0);
+       rcVsub(e1, v2, v0);
+       rcVcross(norm, e0, e1);
+       rcVnormalize(norm);
 }
 
-void rcMarkWalkableTriangles(const float walkableSlopeAngle,
-                                                        const float* verts, int nv,
+/// @par
+///
+/// Only sets the aread id's for the walkable triangles.  Does not alter the
+/// area id's for unwalkable triangles.
+/// 
+/// See the #rcConfig documentation for more information on the configuration parameters.
+/// 
+/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles
+void rcMarkWalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle,
+                                                        const float* verts, int /*nv*/,
                                                         const int* tris, int nt,
-                                                        unsigned char* flags)
+                                                        unsigned char* areas)
 {
-       const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI);
+       // TODO: VC complains about unref formal variable, figure out a way to handle this better.
+//     rcAssert(ctx);
+       
+       const float walkableThr = cosf(walkableSlopeAngle/180.0f*RC_PI);
 
        float norm[3];
        
@@ -101,12 +263,45 @@ void rcMarkWalkableTriangles(const float walkableSlopeAngle,
                calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
                // Check if the face is walkable.
                if (norm[1] > walkableThr)
-                       flags[i] |= RC_WALKABLE;
+                       areas[i] = RC_WALKABLE_AREA;
+       }
+}
+
+/// @par
+///
+/// Only sets the aread id's for the unwalkable triangles.  Does not alter the
+/// area id's for walkable triangles.
+/// 
+/// See the #rcConfig documentation for more information on the configuration parameters.
+/// 
+/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles
+void rcClearUnwalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle,
+                                                               const float* verts, int /*nv*/,
+                                                               const int* tris, int nt,
+                                                               unsigned char* areas)
+{
+       // TODO: VC complains about unref formal variable, figure out a way to handle this better.
+//     rcAssert(ctx);
+       
+       const float walkableThr = cosf(walkableSlopeAngle/180.0f*RC_PI);
+       
+       float norm[3];
+       
+       for (int i = 0; i < nt; ++i)
+       {
+               const int* tri = &tris[i*3];
+               calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
+               // Check if the face is walkable.
+               if (norm[1] <= walkableThr)
+                       areas[i] = RC_NULL_AREA;
        }
 }
 
-static int getSpanCount(unsigned char flags, rcHeightfield& hf)
+int rcGetHeightFieldSpanCount(rcContext* /*ctx*/, rcHeightfield& hf)
 {
+       // TODO: VC complains about unref formal variable, figure out a way to handle this better.
+//     rcAssert(ctx);
+       
        const int w = hf.width;
        const int h = hf.height;
        int spanCount = 0;
@@ -116,7 +311,7 @@ static int getSpanCount(unsigned char flags, rcHeightfield& hf)
                {
                        for (rcSpan* s = hf.spans[x + y*w]; s; s = s->next)
                        {
-                               if (s->flags == flags)
+                               if (s->area != RC_NULL_AREA)
                                        spanCount++;
                        }
                }
@@ -124,21 +319,25 @@ static int getSpanCount(unsigned char flags, rcHeightfield& hf)
        return spanCount;
 }
 
-inline void setCon(rcCompactSpan& s, int dir, int i)
-{
-       s.con &= ~(0xf << (dir*4));
-       s.con |= (i&0xf) << (dir*4);
-}
-
-bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb,
-                                                          unsigned char flags, rcHeightfield& hf,
-                                                          rcCompactHeightfield& chf)
+/// @par
+///
+/// This is just the beginning of the process of fully building a compact heightfield.
+/// Various filters may be applied applied, then the distance field and regions built.
+/// E.g: #rcBuildDistanceField and #rcBuildRegions
+///
+/// See the #rcConfig documentation for more information on the configuration parameters.
+///
+/// @see rcAllocCompactHeightfield, rcHeightfield, rcCompactHeightfield, rcConfig
+bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb,
+                                                          rcHeightfield& hf, rcCompactHeightfield& chf)
 {
-       rcTimeVal startTime = rcGetPerformanceTimer();
+       rcAssert(ctx);
+       
+       ctx->startTimer(RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
        
        const int w = hf.width;
        const int h = hf.height;
-       const int spanCount = getSpanCount(flags, hf);
+       const int spanCount = rcGetHeightFieldSpanCount(ctx, hf);
 
        // Fill in header.
        chf.width = w;
@@ -147,27 +346,32 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
        chf.walkableHeight = walkableHeight;
        chf.walkableClimb = walkableClimb;
        chf.maxRegions = 0;
-       vcopy(chf.bmin, hf.bmin);
-       vcopy(chf.bmax, hf.bmax);
+       rcVcopy(chf.bmin, hf.bmin);
+       rcVcopy(chf.bmax, hf.bmax);
        chf.bmax[1] += walkableHeight*hf.ch;
        chf.cs = hf.cs;
        chf.ch = hf.ch;
-       chf.cells = new rcCompactCell[w*h];
+       chf.cells = (rcCompactCell*)rcAlloc(sizeof(rcCompactCell)*w*h, RC_ALLOC_PERM);
        if (!chf.cells)
        {
-               if (rcGetLog())
-                       rcGetLog()->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.cells' (%d)", w*h);
+               ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.cells' (%d)", w*h);
                return false;
        }
        memset(chf.cells, 0, sizeof(rcCompactCell)*w*h);
-       chf.spans = new rcCompactSpan[spanCount];
+       chf.spans = (rcCompactSpan*)rcAlloc(sizeof(rcCompactSpan)*spanCount, RC_ALLOC_PERM);
        if (!chf.spans)
        {
-               if (rcGetLog())
-                       rcGetLog()->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.spans' (%d)", spanCount);
+               ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.spans' (%d)", spanCount);
                return false;
        }
        memset(chf.spans, 0, sizeof(rcCompactSpan)*spanCount);
+       chf.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*spanCount, RC_ALLOC_PERM);
+       if (!chf.areas)
+       {
+               ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.areas' (%d)", spanCount);
+               return false;
+       }
+       memset(chf.areas, RC_NULL_AREA, sizeof(unsigned char)*spanCount);
        
        const int MAX_HEIGHT = 0xffff;
        
@@ -185,12 +389,13 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
                        c.count = 0;
                        while (s)
                        {
-                               if (s->flags == flags)
+                               if (s->area != RC_NULL_AREA)
                                {
                                        const int bot = (int)s->smax;
                                        const int top = s->next ? (int)s->next->smin : MAX_HEIGHT;
                                        chf.spans[idx].y = (unsigned short)rcClamp(bot, 0, 0xffff);
                                        chf.spans[idx].h = (unsigned char)rcClamp(top - bot, 0, 0xff);
+                                       chf.areas[idx] = s->area;
                                        idx++;
                                        c.count++;
                                }
@@ -200,6 +405,8 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
        }
 
        // Find neighbour connections.
+       const int MAX_LAYERS = RC_NOT_CONNECTED-1;
+       int tooHighNeighbour = 0;
        for (int y = 0; y < h; ++y)
        {
                for (int x = 0; x < w; ++x)
@@ -208,14 +415,16 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
                        for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
                        {
                                rcCompactSpan& s = chf.spans[i];
+                               
                                for (int dir = 0; dir < 4; ++dir)
                                {
-                                       setCon(s, dir, 0xf);
+                                       rcSetCon(s, dir, RC_NOT_CONNECTED);
                                        const int nx = x + rcGetDirOffsetX(dir);
                                        const int ny = y + rcGetDirOffsetY(dir);
                                        // First check that the neighbour cell is in bounds.
                                        if (nx < 0 || ny < 0 || nx >= w || ny >= h)
                                                continue;
+                                               
                                        // Iterate over all neighbour spans and check if any of the is
                                        // accessible from current cell.
                                        const rcCompactCell& nc = chf.cells[nx+ny*w];
@@ -230,23 +439,34 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
                                                if ((top - bot) >= walkableHeight && rcAbs((int)ns.y - (int)s.y) <= walkableClimb)
                                                {
                                                        // Mark direction as walkable.
-                                                       setCon(s, dir, k - (int)nc.index);
+                                                       const int idx = k - (int)nc.index;
+                                                       if (idx < 0 || idx > MAX_LAYERS)
+                                                       {
+                                                               tooHighNeighbour = rcMax(tooHighNeighbour, idx);
+                                                               continue;
+                                                       }
+                                                       rcSetCon(s, dir, idx);
                                                        break;
                                                }
                                        }
+                                       
                                }
                        }
                }
        }
        
-       rcTimeVal endTime = rcGetPerformanceTimer();
-       
-       if (rcGetBuildTimes())
-               rcGetBuildTimes()->buildCompact += rcGetDeltaTimeUsec(startTime, endTime);
+       if (tooHighNeighbour > MAX_LAYERS)
+       {
+               ctx->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Heightfield has too many layers %d (max: %d)",
+                                tooHighNeighbour, MAX_LAYERS);
+       }
+               
+       ctx->stopTimer(RC_TIMER_BUILD_COMPACTHEIGHTFIELD);
        
        return true;
 }
 
+/*
 static int getHeightfieldMemoryUsage(const rcHeightfield& hf)
 {
        int size = 0;
@@ -270,3 +490,4 @@ static int getCompactHeightFieldMemoryusage(const rcCompactHeightfield& chf)
        size += sizeof(rcCompactCell) * chf.width * chf.height;
        return size;
 }
+*/
\ No newline at end of file
diff --git a/extern/recastnavigation/Recast/Source/RecastAlloc.cpp b/extern/recastnavigation/Recast/Source/RecastAlloc.cpp
new file mode 100644 (file)
index 0000000..b5ec151
--- /dev/null
@@ -0,0 +1,88 @@
+//
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+
+#include <stdlib.h>
+#include <string.h>
+#include "RecastAlloc.h"
+
+static void *rcAllocDefault(int size, rcAllocHint)
+{
+       return malloc(size);
+}
+
+static void rcFreeDefault(void *ptr)
+{
+       free(ptr);
+}
+
+static rcAllocFunc* sRecastAllocFunc = rcAllocDefault;
+static rcFreeFunc* sRecastFreeFunc = rcFreeDefault;
+
+/// @see rcAlloc, rcFree
+void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc)
+{
+       sRecastAllocFunc = allocFunc ? allocFunc : rcAllocDefault;
+       sRecastFreeFunc = freeFunc ? freeFunc : rcFreeDefault;
+}
+
+/// @see rcAllocSetCustom
+void* rcAlloc(int size, rcAllocHint hint)
+{
+       return sRecastAllocFunc(size, hint);
+}
+
+/// @par
+///
+/// @warning This function leaves the value of @p ptr unchanged.  So it still
+/// points to the same (now invalid) location, and not to null.
+/// 
+/// @see rcAllocSetCustom
+void rcFree(void* ptr)
+{
+       if (ptr)
+               sRecastFreeFunc(ptr);
+}
+
+/// @class rcIntArray
+///
+/// While it is possible to pre-allocate a specific array size during 
+/// construction or by using the #resize method, certain methods will 
+/// automatically resize the array as needed.
+///
+/// @warning The array memory is not initialized to zero when the size is 
+/// manually set during construction or when using #resize.
+
+/// @par
+///
+/// Using this method ensures the array is at least large enough to hold
+/// the specified number of elements.  This can improve performance by
+/// avoiding auto-resizing during use.
+void rcIntArray::resize(int n)
+{
+       if (n > m_cap)
+       {
+               if (!m_cap) m_cap = n;
+               while (m_cap < n) m_cap *= 2;
+               int* newData = (int*)rcAlloc(m_cap*sizeof(int), RC_ALLOC_TEMP);
+               if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int));
+               rcFree(m_data);
+               m_data = newData;
+       }
+       m_size = n;
+}
+
diff --git a/extern/recastnavigation/Recast/Source/RecastArea.cpp b/extern/recastnavigation/Recast/Source/RecastArea.cpp
new file mode 100644 (file)
index 0000000..a59acc5
--- /dev/null
@@ -0,0 +1,524 @@
+//
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
+//
+// This software is provided 'as-is', without any express or implied
+// warranty.  In no event will the authors be held liable for any damages
+// arising from the use of this software.
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would be
+//    appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+//    misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+
+#include <float.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "Recast.h"
+#include "RecastAlloc.h"
+#include "RecastAssert.h"
+
+/// @par 
+/// 
+/// Basically, any spans that are closer to a boundary or obstruction than the specified radius 
+/// are marked as unwalkable.
+///
+/// This method is usually called immediately after the heightfield has been built.
+///
+/// @see rcCompactHeightfield, rcBuildCompactHeightfield, rcConfig::walkableRadius
+bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf)
+{
+       rcAssert(ctx);
+       
+       const int w = chf.width;
+       const int h = chf.height;
+       
+       ctx->startTimer(RC_TIMER_ERODE_AREA);
+       
+       unsigned char* dist = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
+       if (!dist)
+       {
+               ctx->log(RC_LOG_ERROR, "erodeWalkableArea: Out of memory 'dist' (%d).", chf.spanCount);
+               return false;
+       }
+       
+       // Init distance.
+       memset(dist, 0xff, sizeof(unsigned char)*chf.spanCount);
+       
+       // Mark boundary cells.
+       for (int y = 0; y < h; ++y)
+       {
+               for (int x = 0; x < w; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+y*w];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               if (chf.areas[i] == RC_NULL_AREA)
+                               {
+                                       dist[i] = 0;
+                               }
+                               else
+                               {
+                                       const rcCompactSpan& s = chf.spans[i];
+                                       int nc = 0;
+                                       for (int dir = 0; dir < 4; ++dir)
+                                       {
+                                               if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
+                                               {
+                                                       const int nx = x + rcGetDirOffsetX(dir);
+                                                       const int ny = y + rcGetDirOffsetY(dir);
+                                                       const int ni = (int)chf.cells[nx+ny*w].index + rcGetCon(s, dir);
+                                                       if (chf.areas[ni] != RC_NULL_AREA)
+                                                       {
+                                                               nc++;
+                                                       }
+                                               }
+                                       }
+                                       // At least one missing neighbour.
+                                       if (nc != 4)
+                                               dist[i] = 0;
+                               }
+                       }
+               }
+       }
+       
+       unsigned char nd;
+       
+       // Pass 1
+       for (int y = 0; y < h; ++y)
+       {
+               for (int x = 0; x < w; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+y*w];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               const rcCompactSpan& s = chf.spans[i];
+                               
+                               if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
+                               {
+                                       // (-1,0)
+                                       const int ax = x + rcGetDirOffsetX(0);
+                                       const int ay = y + rcGetDirOffsetY(0);
+                                       const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
+                                       const rcCompactSpan& as = chf.spans[ai];
+                                       nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
+                                       if (nd < dist[i])
+                                               dist[i] = nd;
+                                       
+                                       // (-1,-1)
+                                       if (rcGetCon(as, 3) != RC_NOT_CONNECTED)
+                                       {
+                                               const int aax = ax + rcGetDirOffsetX(3);
+                                               const int aay = ay + rcGetDirOffsetY(3);
+                                               const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 3);
+                                               nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
+                                               if (nd < dist[i])
+                                                       dist[i] = nd;
+                                       }
+                               }
+                               if (rcGetCon(s, 3) != RC_NOT_CONNECTED)
+                               {
+                                       // (0,-1)
+                                       const int ax = x + rcGetDirOffsetX(3);
+                                       const int ay = y + rcGetDirOffsetY(3);
+                                       const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3);
+                                       const rcCompactSpan& as = chf.spans[ai];
+                                       nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
+                                       if (nd < dist[i])
+                                               dist[i] = nd;
+                                       
+                                       // (1,-1)
+                                       if (rcGetCon(as, 2) != RC_NOT_CONNECTED)
+                                       {
+                                               const int aax = ax + rcGetDirOffsetX(2);
+                                               const int aay = ay + rcGetDirOffsetY(2);
+                                               const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 2);
+                                               nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
+                                               if (nd < dist[i])
+                                                       dist[i] = nd;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       // Pass 2
+       for (int y = h-1; y >= 0; --y)
+       {
+               for (int x = w-1; x >= 0; --x)
+               {
+                       const rcCompactCell& c = chf.cells[x+y*w];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               const rcCompactSpan& s = chf.spans[i];
+                               
+                               if (rcGetCon(s, 2) != RC_NOT_CONNECTED)
+                               {
+                                       // (1,0)
+                                       const int ax = x + rcGetDirOffsetX(2);
+                                       const int ay = y + rcGetDirOffsetY(2);
+                                       const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 2);
+                                       const rcCompactSpan& as = chf.spans[ai];
+                                       nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
+                                       if (nd < dist[i])
+                                               dist[i] = nd;
+                                       
+                                       // (1,1)
+                                       if (rcGetCon(as, 1) != RC_NOT_CONNECTED)
+                                       {
+                                               const int aax = ax + rcGetDirOffsetX(1);
+                                               const int aay = ay + rcGetDirOffsetY(1);
+                                               const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 1);
+                                               nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
+                                               if (nd < dist[i])
+                                                       dist[i] = nd;
+                                       }
+                               }
+                               if (rcGetCon(s, 1) != RC_NOT_CONNECTED)
+                               {
+                                       // (0,1)
+                                       const int ax = x + rcGetDirOffsetX(1);
+                                       const int ay = y + rcGetDirOffsetY(1);
+                                       const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 1);
+                                       const rcCompactSpan& as = chf.spans[ai];
+                                       nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
+                                       if (nd < dist[i])
+                                               dist[i] = nd;
+                                       
+                                       // (-1,1)
+                                       if (rcGetCon(as, 0) != RC_NOT_CONNECTED)
+                                       {
+                                               const int aax = ax + rcGetDirOffsetX(0);
+                                               const int aay = ay + rcGetDirOffsetY(0);
+                                               const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 0);
+                                               nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
+                                               if (nd < dist[i])
+                                                       dist[i] = nd;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       const unsigned char thr = (unsigned char)(radius*2);
+       for (int i = 0; i < chf.spanCount; ++i)
+               if (dist[i] < thr)
+                       chf.areas[i] = RC_NULL_AREA;
+       
+       rcFree(dist);
+       
+       ctx->stopTimer(RC_TIMER_ERODE_AREA);
+       
+       return true;
+}
+
+static void insertSort(unsigned char* a, const int n)
+{
+       int i, j;
+       for (i = 1; i < n; i++)
+       {
+               const unsigned char value = a[i];
+               for (j = i - 1; j >= 0 && a[j] > value; j--)
+                       a[j+1] = a[j];
+               a[j+1] = value;
+       }
+}
+
+/// @par
+///
+/// This filter is usually applied after applying area id's using functions
+/// such as #rcMarkBoxArea, #rcMarkConvexPolyArea, and #rcMarkCylinderArea.
+/// 
+/// @see rcCompactHeightfield
+bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf)
+{
+       rcAssert(ctx);
+       
+       const int w = chf.width;
+       const int h = chf.height;
+       
+       ctx->startTimer(RC_TIMER_MEDIAN_AREA);
+       
+       unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
+       if (!areas)
+       {
+               ctx->log(RC_LOG_ERROR, "medianFilterWalkableArea: Out of memory 'areas' (%d).", chf.spanCount);
+               return false;
+       }
+       
+       // Init distance.
+       memset(areas, 0xff, sizeof(unsigned char)*chf.spanCount);
+       
+       for (int y = 0; y < h; ++y)
+       {
+               for (int x = 0; x < w; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+y*w];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               const rcCompactSpan& s = chf.spans[i];
+                               if (chf.areas[i] == RC_NULL_AREA)
+                               {
+                                       areas[i] = chf.areas[i];
+                                       continue;
+                               }
+                               
+                               unsigned char nei[9];
+                               for (int j = 0; j < 9; ++j)
+                                       nei[j] = chf.areas[i];
+                               
+                               for (int dir = 0; dir < 4; ++dir)
+                               {
+                                       if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
+                                       {
+                                               const int ax = x + rcGetDirOffsetX(dir);
+                                               const int ay = y + rcGetDirOffsetY(dir);
+                                               const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
+                                               if (chf.areas[ai] != RC_NULL_AREA)
+                                                       nei[dir*2+0] = chf.areas[ai];
+                                               
+                                               const rcCompactSpan& as = chf.spans[ai];
+                                               const int dir2 = (dir+1) & 0x3;
+                                               if (rcGetCon(as, dir2) != RC_NOT_CONNECTED)
+                                               {
+                                                       const int ax2 = ax + rcGetDirOffsetX(dir2);
+                                                       const int ay2 = ay + rcGetDirOffsetY(dir2);
+                                                       const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
+                                                       if (chf.areas[ai2] != RC_NULL_AREA)
+                                                               nei[dir*2+1] = chf.areas[ai2];
+                                               }
+                                       }
+                               }
+                               insertSort(nei, 9);
+                               areas[i] = nei[4];
+                       }
+               }
+       }
+       
+       memcpy(chf.areas, areas, sizeof(unsigned char)*chf.spanCount);
+       
+       rcFree(areas);
+
+       ctx->stopTimer(RC_TIMER_MEDIAN_AREA);
+       
+       return true;
+}
+
+/// @par
+///
+/// The value of spacial parameters are in world units.
+/// 
+/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
+void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId,
+                                  rcCompactHeightfield& chf)
+{
+       rcAssert(ctx);
+       
+       ctx->startTimer(RC_TIMER_MARK_BOX_AREA);
+
+       int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs);
+       int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch);
+       int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs);
+       int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs);
+       int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch);
+       int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs);
+       
+       if (maxx < 0) return;
+       if (minx >= chf.width) return;
+       if (maxz < 0) return;
+       if (minz >= chf.height) return;
+
+       if (minx < 0) minx = 0;
+       if (maxx >= chf.width) maxx = chf.width-1;
+       if (minz < 0) minz = 0;
+       if (maxz >= chf.height) maxz = chf.height-1;    
+       
+       for (int z = minz; z <= maxz; ++z)
+       {
+               for (int x = minx; x <= maxx; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+z*chf.width];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               rcCompactSpan& s = chf.spans[i];
+                               if ((int)s.y >= miny && (int)s.y <= maxy)
+                               {
+                                       if (chf.areas[i] != RC_NULL_AREA)
+                                               chf.areas[i] = areaId;
+                               }
+                       }
+               }
+       }
+
+       ctx->stopTimer(RC_TIMER_MARK_BOX_AREA);
+
+}
+
+
+static int pointInPoly(int nvert, const float* verts, const float* p)
+{
+       int i, j, c = 0;
+       for (i = 0, j = nvert-1; i < nvert; j = i++)
+       {
+               const float* vi = &verts[i*3];
+               const float* vj = &verts[j*3];
+               if (((vi[2] > p[2]) != (vj[2] > p[2])) &&
+                       (p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
+                       c = !c;
+       }
+       return c;
+}
+
+/// @par
+///
+/// The value of spacial parameters are in world units.
+/// 
+/// The y-values of the polygon vertices are ignored. So the polygon is effectively 
+/// projected onto the xz-plane at @p hmin, then extruded to @p hmax.
+/// 
+/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
+void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
+                                                 const float hmin, const float hmax, unsigned char areaId,
+                                                 rcCompactHeightfield& chf)
+{
+       rcAssert(ctx);
+       
+       ctx->startTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
+
+       float bmin[3], bmax[3];
+       rcVcopy(bmin, verts);
+       rcVcopy(bmax, verts);
+       for (int i = 1; i < nverts; ++i)
+       {
+               rcVmin(bmin, &verts[i*3]);
+               rcVmax(bmax, &verts[i*3]);
+       }
+       bmin[1] = hmin;
+       bmax[1] = hmax;
+
+       int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs);
+       int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch);
+       int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs);
+       int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs);
+       int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch);
+       int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs);
+       
+       if (maxx < 0) return;
+       if (minx >= chf.width) return;
+       if (maxz < 0) return;
+       if (minz >= chf.height) return;
+       
+       if (minx < 0) minx = 0;
+       if (maxx >= chf.width) maxx = chf.width-1;
+       if (minz < 0) minz = 0;
+       if (maxz >= chf.height) maxz = chf.height-1;    
+       
+       
+       // TODO: Optimize.
+       for (int z = minz; z <= maxz; ++z)
+       {
+               for (int x = minx; x <= maxx; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+z*chf.width];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               rcCompactSpan& s = chf.spans[i];
+                               if (chf.areas[i] == RC_NULL_AREA)
+                                       continue;
+                               if ((int)s.y >= miny && (int)s.y <= maxy)
+                               {
+                                       float p[3];
+                                       p[0] = chf.bmin[0] + (x+0.5f)*chf.cs; 
+                                       p[1] = 0;
+                                       p[2] = chf.bmin[2] + (z+0.5f)*chf.cs; 
+
+                                       if (pointInPoly(nverts, verts, p))
+                                       {
+                                               chf.areas[i] = areaId;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
+}
+
+/// @par
+///
+/// The value of spacial parameters are in world units.
+/// 
+/// @see rcCompactHeightfield, rcMedianFilterWalkableArea
+void rcMarkCylinderArea(rcContext* ctx, const float* pos,
+                                               const float r, const float h, unsigned char areaId,
+                                               rcCompactHeightfield& chf)
+{
+       rcAssert(ctx);
+       
+       ctx->startTimer(RC_TIMER_MARK_CYLINDER_AREA);
+       
+       float bmin[3], bmax[3];
+       bmin[0] = pos[0] - r;
+       bmin[1] = pos[1];
+       bmin[2] = pos[2] - r;
+       bmax[0] = pos[0] + r;
+       bmax[1] = pos[1] + h;
+       bmax[2] = pos[2] + r;
+       const float r2 = r*r;
+       
+       int minx = (int)((bmin[0]-chf.bmin[0])/chf.cs);
+       int miny = (int)((bmin[1]-chf.bmin[1])/chf.ch);
+       int minz = (int)((bmin[2]-chf.bmin[2])/chf.cs);
+       int maxx = (int)((bmax[0]-chf.bmin[0])/chf.cs);
+       int maxy = (int)((bmax[1]-chf.bmin[1])/chf.ch);
+       int maxz = (int)((bmax[2]-chf.bmin[2])/chf.cs);
+       
+       if (maxx < 0) return;
+       if (minx >= chf.width) return;
+       if (maxz < 0) return;
+       if (minz >= chf.height) return;
+       
+       if (minx < 0) minx = 0;
+       if (maxx >= chf.width) maxx = chf.width-1;
+       if (minz < 0) minz = 0;
+       if (maxz >= chf.height) maxz = chf.height-1;    
+       
+       
+       for (int z = minz; z <= maxz; ++z)
+       {
+               for (int x = minx; x <= maxx; ++x)
+               {
+                       const rcCompactCell& c = chf.cells[x+z*chf.width];
+                       for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
+                       {
+                               rcCompactSpan& s = chf.spans[i];
+                               
+                               if (chf.areas[i] == RC_NULL_AREA)
+                                       continue;
+                               
+                               if ((int)s.y >= miny && (int)s.y <= maxy)
+                               {
+                                       const float sx = chf.bmin[0] + (x+0.5f)*chf.cs; 
+                                       const float sz = chf.bmin[2] + (z+0.5f)*chf.cs; 
+                                       const float dx = sx - pos[0];
+                                       const float dz = sz - pos[2];
+                                       
+                                       if (dx*dx + dz*dz < r2)
+                                       {
+                                               chf.areas[i] = areaId;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       ctx->stopTimer(RC_TIMER_MARK_CYLINDER_AREA);
+}
index 96f763a..078c464 100644 (file)
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2009 Mikko Mononen memon@inside.org
+// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
 //
 // This software is provided 'as-is', without any express or implied
 // warranty.  In no event will the authors be held liable for any damages
@@ -21,8 +21,8 @@
 #include <string.h>
 #include <stdio.h>
 #include "Recast.h"
-#include "RecastLog.h"
-#include "RecastTimer.h"
+#include "RecastAlloc.h"
+#include "RecastAssert.h"
 
 
 static int getCornerHeight(int x, int y, int i, int dir,
@@ -33,44 +33,46 @@ static int getCornerHeight(int x, int y, int i, int dir,
        int ch = (int)s.y;
        int dirp = (dir+1) & 0x3;
        
-       unsigned short regs[4] = {0,0,0,0};
+       unsigned int regs[4] = {0,0,0,0};
        
-       regs[0] = s.reg;
+       // Combine region and area codes in order to prevent
+       // border vertices which are in between two areas to be removed. 
+       regs[0] = chf.spans[i].reg | (chf.areas[i] << 16);
        
-       if (rcGetCon(s, dir) != 0xf)
+       if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
        {
                const int ax = x + rcGetDirOffsetX(dir);
                const int ay = y + rcGetDirOffsetY(dir);
                const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir);
                const rcCompactSpan& as = chf.spans[ai];
                ch = rcMax(ch, (int)as.y);
-               regs[1] = as.reg;
-               if (rcGetCon(as, dirp) != 0xf)
+               regs[1] = chf.spans[ai].reg | (chf.areas[ai] << 16);
+               if (rcGetCon(as, dirp) != RC_NOT_CONNECTED)
                {
                        const int ax2 = ax + rcGetDirOffsetX(dirp);
                        const int ay2 = ay + rcGetDirOffsetY(dirp);
                        const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dirp);
                        const rcCompactSpan& as2 = chf.spans[ai2];
                        ch = rcMax(ch, (int)as2.y);
-                       regs[2] = as2.reg;
+                       regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16);
                }
        }
-       if (rcGetCon(s, dirp) != 0xf)
+       if (rcGetCon(s, dirp) != RC_NOT_CONNECTED)
        {
                const int ax = x + rcGetDirOffsetX(dirp);
                const int ay = y + rcGetDirOffsetY(dirp);
                const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dirp);
                const rcCompactSpan& as = chf.spans[ai];
                ch = rcMax(ch, (int)as.y);
-               regs[3] = as.reg;
-               if (rcGetCon(as, dir) != 0xf)
+               regs[3] = chf.spans[ai].reg | (chf.areas[ai] << 16);
+               if (rcGetCon(as, dir) != RC_NOT_CONNECTED)
                {
                        const int ax2 = ax + rcGetDirOffsetX(dir);
                        const int ay2 = ay + rcGetDirOffsetY(dir);
                        const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dir);
                        const rcCompactSpan& as2 = chf.spans[ai2];
                        ch = rcMax(ch, (int)as2.y);
-                       regs[2] = as2.reg;
+                       regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16);
                }
        }
 
@@ -86,8 +88,9 @@ static int getCornerHeight(int x, int y, int i, int dir,
                // followed by two interior cells and none of the regions are out of bounds.
                const bool twoSameExts = (regs[a] & regs[b] & RC_BORDER_REG) != 0 && regs[a] == regs[b];
                const bool twoInts = ((regs[c] | regs[d]) & RC_BORDER_REG) == 0;
+               const bool intsSameArea = (regs[c]>>16) == (regs[d]>>16);
                const bool noZeros = regs[a] != 0 && regs[b] != 0 && regs[c] != 0 && regs[d] != 0;
-               if (twoSameExts && twoInts && noZeros)
+               if (twoSameExts && twoInts && intsSameArea && noZeros)
                {
                        isBorderVertex = true;
                        break;
@@ -109,6 +112,8 @@ static void walkContour(int x, int y, int i,
        unsigned char startDir = dir;
        int starti = i;
        
+       const unsigned char area = chf.areas[i];
+       
        int iter = 0;
        while (++iter < 40000)
        {
@@ -116,6 +121,7 @@ static void walkContour(int x, int y, int i,
                {
                        // Choose the edge corner
                        bool isBorderVertex = false;
+                       bool isAreaBorder = false;
                        int px = x;
                        int py = getCornerHeight(x, y, i, dir, chf, isBorderVertex);
                        int pz = y;
@@ -127,16 +133,19 @@ static void walkContour(int x, int y, int i,
                        }
                        int r = 0;
                        const rcCompactSpan& s = chf.spans[i];
-                       if (rcGetCon(s, dir) != 0xf)
+                       if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
                        {
                                const int ax = x + rcGetDirOffsetX(dir);
                                const int ay = y + rcGetDirOffsetY(dir);
                                const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir);
-                               const rcCompactSpan& as = chf.spans[ai];
-                               r = (int)as.reg;
+                               r = (int)chf.spans[ai].reg;
+                               if (area != chf.areas[ai])
+                                       isAreaBorder = true;
                        }
                        if (isBorderVertex)
                                r |= RC_BORDER_VERTEX;
+                       if (isAreaBorder)
+                               r |= RC_AREA_BORDER;
                        points.push(px);
                        points.push(py);
                        points.push(pz);
@@ -151,7 +160,7 @@ static void walkContour(int x, int y, int i,
                        const int nx = x + rcGetDirOffsetX(dir);
                        const int ny = y + rcGetDirOffsetY(dir);
                        const rcCompactSpan& s = chf.spans[i];
-                       if (rcGetCon(s, dir) != 0xf)
+                       if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
                        {
                                const rcCompactCell& nc = chf.cells[nx+ny*chf.width];
                                ni = (int)nc.index + rcGetCon(s, dir);
@@ -174,9 +183,9 @@ static void walkContour(int x, int y, int i,
        }
 }
 
-static float distancePtSeg(int x, int y, int z,
-                                                  int px, int py, int pz,
-                                                  int qx, int qy, int qz)
+static float distancePtSeg(const int x, const int z,
+                                                  const int px, const int pz,
+                                                  const int qx, const int qz)
 {
 /*     float pqx = (float)(qx - px);
        float pqy = (float)(qy - py);
@@ -218,20 +227,40 @@ static float distancePtSeg(int x, int y, int z,
        return dx*dx + dz*dz;
 }
 
-static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float maxError, int maxEdgeLen)
+static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
+                                                       const float maxError, const int maxEdgeLen, const int buildFlags)
 {
        // Add initial points.
-       bool noConnections = true;
+       bool hasConnections = false;
        for (int i = 0; i < points.size(); i += 4)
        {
-               if ((points[i+3] & 0xffff) != 0)
+               if ((points[i+3] & RC_CONTOUR_REG_MASK) != 0)
                {
-                       noConnections = false;
+                       hasConnections = true;
                        break;
                }
        }
        
-       if (noConnections)
+       if (hasConnections)
+       {
+               // The contour has some portals to other regions.
+               // Add a new point to every location where the region changes.
+               for (int i = 0, ni = points.size()/4; i < ni; ++i)
+               {
+                       int ii = (i+1) % ni;
+                       const bool differentRegs = (points[i*4+3] & RC_CONTOUR_REG_MASK) != (points[ii*4+3] & RC_CONTOUR_REG_MASK);
+                       const bool areaBorders = (points[i*4+3] & RC_AREA_BORDER) != (points[ii*4+3] & RC_AREA_BORDER);
+                       if (differentRegs || areaBorders)
+                       {
+                               simplified.push(points[i*4+0]);
+                               simplified.push(points[i*4+1]);
+                               simplified.push(points[i*4+2]);
+                               simplified.push(i);
+                       }
+               }       
+       }
+       
+       if (simplified.size() == 0)
        {
                // If there is no connections at all,
                // create some initial points for the simplification process. 
@@ -256,7 +285,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
                                llz = z;
                                lli = i/4;
                        }
-                       if (x >= urx || (x == urx && z > urz))
+                       if (x > urx || (x == urx && z > urz))
                        {
                                urx = x;
                                ury = y;
@@ -274,22 +303,6 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
                simplified.push(urz);
                simplified.push(uri);
        }
-       else
-       {
-               // The contour has some portals to other regions.
-               // Add a new point to every location where the region changes.
-               for (int i = 0, ni = points.size()/4; i < ni; ++i)
-               {
-                       int ii = (i+1) % ni;
-                       if ((points[i*4+3] & 0xffff) != (points[ii*4+3] & 0xffff))
-                       {
-                               simplified.push(points[i*4+0]);
-                               simplified.push(points[i*4+1]);
-                               simplified.push(points[i*4+2]);
-                               simplified.push(i);
-                       }
-               }       
-       }
        
        // Add points until all raw points are within
        // error tolerance to the simplified shape.
@@ -298,34 +311,48 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
        {
                int ii = (i+1) % (simplified.size()/4);
                
-               int ax = simplified[i*4+0];
-               int ay = simplified[i*4+1];
-               int az = simplified[i*4+2];
-               int ai = simplified[i*4+3];
-               
-               int bx = simplified[ii*4+0];
-               int by = simplified[ii*4+1];
-               int bz = simplified[ii*4+2];
-               int bi = simplified[ii*4+3];
+               const int ax = simplified[i*4+0];
+               const int az = simplified[i*4+2];
+               const int ai = simplified[i*4+3];
                
+               const int bx = simplified[ii*4+0];
+               const int bz = simplified[ii*4+2];
+               const int bi = simplified[ii*4+3];
+
                // Find maximum deviation from the segment.
                float maxd = 0;
                int maxi = -1;
-               int ci = (ai+1) % pn;
+               int ci, cinc, endi;
                
-               // Tesselate only outer edges.
-               if ((points[ci*4+3] & 0xffff) == 0)
+               // Traverse the segment in lexilogical order so that the
+               // max deviation is calculated similarly when traversing
+               // opposite segments.
+               if (bx > ax || (bx == ax && bz > az))
                {
-                       while (ci != bi)
+                       cinc = 1;
+                       ci = (ai+cinc) % pn;
+                       endi = bi;
+               }
+               else
+               {
+                       cinc = pn-1;
+                       ci = (bi+cinc) % pn;
+                       endi = ai;
+               }
+               
+               // Tessellate only outer edges or edges between areas.
+               if ((points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0 ||
+                       (points[ci*4+3] & RC_AREA_BORDER))
+               {
+                       while (ci != endi)
                        {
-                               float d = distancePtSeg(points[ci*4+0], points[ci*4+1]/4, points[ci*4+2],
-                                                                               ax, ay/4, az, bx, by/4, bz);
+                               float d = distancePtSeg(points[ci*4+0], points[ci*4+2], ax, az, bx, bz);
                                if (d > maxd)
                                {
                                        maxd = d;
                                        maxi = ci;
                                }
-                               ci = (ci+1) % pn;
+                               ci = (ci+cinc) % pn;
                        }
                }
                
@@ -336,7 +363,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
                {
                        // Add space for the new point.
                        simplified.resize(simplified.size()+4);
-                       int n = simplified.size()/4;
+                       const int n = simplified.size()/4;
                        for (int j = n-1; j > i; --j)
                        {
                                simplified[j*4+0] = simplified[(j-1)*4+0];
@@ -357,33 +384,52 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
        }
        
        // Split too long edges.
-       if (maxEdgeLen > 0)
+       if (maxEdgeLen > 0 && (buildFlags & (RC_CONTOUR_TESS_WALL_EDGES|RC_CONTOUR_TESS_AREA_EDGES)) != 0)
        {
                for (int i = 0; i < simplified.size()/4; )
                {
-                       int ii = (i+1) % (simplified.size()/4);
-                       
-                       int ax = simplified[i*4+0];
-                       int az = simplified[i*4+2];
-                       int ai = simplified[i*4+3];
+                       const int ii = (i+1) % (simplified.size()/4);
                        
-                       int bx = simplified[ii*4+0];
-                       int bz = simplified[ii*4+2];
-                       int bi = simplified[ii*4+3];
+                       const int ax = simplified[i*4+0];
+                       const int az = simplified[i*4+2];
+                       const int ai = simplified[i*4+3];
                        
+                       const int bx = simplified[ii*4+0];
+                       const int bz = simplified[ii*4+2];
+                       const int bi = simplified[ii*4+3];
+
                        // Find maximum deviation from the segment.
                        int maxi = -1;
                        int ci = (ai+1) % pn;
+
+                       // Tessellate only outer edges or edges between areas.
+                       bool tess = false;
+                       // Wall edges.
+                       if ((buildFlags & RC_CONTOUR_TESS_WALL_EDGES) && (points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0)
+                               tess = true;
+                       // Edges between areas.
+                       if ((buildFlags & RC_CONTOUR_TESS_AREA_EDGES) && (points[ci*4+3] & RC_AREA_BORDER))
+                               tess = true;
                        
-                       // Tesselate only outer edges.
-                       if ((points[ci*4+3] & 0xffff) == 0)
+                       if (tess)
                        {
                                int dx = bx - ax;
                                int dz = bz - az;
                                if (dx*dx + dz*dz > maxEdgeLen*maxEdgeLen)
                                {
-                                       int n = bi < ai ? (bi+pn - ai) : (bi - ai);
-                                       maxi = (ai + n/2) % pn;
+                                       // Round based on the segments in lexilogical order so that the
+                                       // max tesselation is consistent regardles in which direction
+                                       // segments are traversed.
+                                       if (bx > ax || (bx == ax && bz > az))
+                                       {
+                                               const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
+                                               maxi = (ai + n/2) % pn;
+                                       }
+                                       else
+                                       {
+                                               const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
+                                               maxi = (ai + (n+1)/2) % pn;
+                                       }
                                }
                        }
                        
@@ -393,7 +439,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
                        {
                                // Add space for the new point.
                                simplified.resize(simplified.size()+4);
-                               int n = simplified.size()/4;
+                               const int n = simplified.size()/4;
                                for (int j = n-1; j > i; --j)
                                {
                                        simplified[j*4+0] = simplified[(j-1)*4+0];
@@ -420,7 +466,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
                // and the neighbour region is take from the next raw point.
                const int ai = (simplified[i*4+3]+1) % pn;
                const int bi = simplified[i*4+3];
-               simplified[i*4+3] = (points[ai*4+3] & 0xffff) | (points[bi*4+3] & RC_BORDER_VERTEX);
+               simplified[i*4+3] = (points[ai*4+3] & RC_CONTOUR_REG_MASK) | (points[bi*4+3] & RC_BORDER_VERTEX);
        }
        
 }
@@ -446,7 +492,7 @@ static void removeDegenerateSegments(rcIntArray& simplified)
                                simplified[j*4+2] = simplified[(j+1)*4+2];
                                simplified[j*4+3] = simplified[(j+1)*4+3];
                        }
-                       simplified.pop();
+                       simplified.resize(simplified.size()-4);
                }
        }
 }
@@ -463,25 +509,40 @@ static int calcAreaOfPolygon2D(const int* verts, const int nverts)
        return (area+1) / 2;
 }
 
+inline bool ileft(const int* a, const int* b, const int* c)
+{
+       return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]) <= 0;
+}
+
 static void getClosestIndices(const int* vertsa, const int nvertsa,
                                                          const int* vertsb, const int nvertsb,
                                                          int& ia, int& ib)
 {
        int closestDist = 0xfffffff;
+       ia = -1, ib = -1;
        for (int i = 0; i < nvertsa; ++i)
        {
+               const int in = (i+1) % nvertsa;
+               const int ip = (i+nvertsa-1) % nvertsa;
                const int* va = &vertsa[i*4];
+               const int* van = &vertsa[in*4];
+               const int* vap = &vertsa[ip*4];
+               
                for (int j = 0; j < nvertsb; ++j)
                {
                        const int* vb = &vertsb[j*4];
-                       const int dx = vb[0] - va[0];
-                       const int dz = vb[2] - va[2];
-                       const int d = dx*dx + dz*dz;
-                       if (d < closestDist)
+                       // vb must be "infront" of va.
+                       if (ileft(vap,va,vb) && ileft(va,van,vb))
                        {
-                               ia = i;
-                               ib = j;
-                               closestDist = d;
+                               const int dx = vb[0] - va[0];
+                               const int dz = vb[2] - va[2];
+                               const int d = dx*dx + dz*dz;
+                               if (d < closestDist)
+                               {
+                                       ia = i;
+                                       ib = j;
+                                       closestDist = d;
+                               }
                        }
                }
        }
@@ -490,7 +551,7 @@ static void getClosestIndices(const int* vertsa, const int nvertsa,
 static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib)
 {
        const int maxVerts = ca.nverts + cb.nverts + 2;
-       int* verts = new int[maxVerts*4];
+       int* verts = (int*)rcAlloc(sizeof(int)*maxVerts*4, RC_ALLOC_PERM);
        if (!verts)
                return false;
 
@@ -520,47 +581,73 @@ static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib)
                nv++;
        }
        
-       delete [] ca.verts;
+       rcFree(ca.verts);
        ca.verts = verts;
        ca.nverts = nv;
 
-       delete [] cb.verts;
+       rcFree(cb.verts);
        cb.verts = 0;
        cb.nverts = 0;
        
        return true;
 }
 
-bool rcBuildContours(rcCompactHeightfield& chf,
+/// @par
+///
+/// The raw contours will match the region outlines exactly. The @p maxError and @p maxEdgeLen
+/// parameters control how closely the simplified contours will match the raw contours.
+///
+/// Simplified contours are generated such that the vertices for portals between areas match up. 
+/// (They are considered mandatory vertices.)
+///
+/// Setting @p maxEdgeLength to zero will disabled the edge length feature.
+/// 
+/// See the #rcConfig documentation for more information on the configuration parameters.
+/// 
+/// @see rcAllocContourSet, rcCompactHeightfield, rcContourSet, rcConfig
+bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
                                         const float maxError, const int maxEdgeLen,
-                                        rcContourSet& cset)
+                                        rcContourSet& cset, const int buildFlags)
 {
+       rcAssert(ctx);
+       
        const int w = chf.width;
        const int h = chf.height;
+       const int borderSize = chf.borderSize;
        
-       rcTimeVal startTime = rcGetPerformanceTimer();
+       ctx->startTimer(RC_TIMER_BUILD_CONTOURS);
        
-       vcopy(cset.bmin, chf.bmin);
-       vcopy(cset.bmax, chf.bmax);
+       rcVcopy(cset.bmin, chf.bmin);
+       rcVcopy(cset.bmax, chf.bmax);
+       if (borderSize > 0)
+       {
+               // If the heightfield was build with bordersize, remove the offset.
+               const float pad = borderSize*chf.cs;
+               cset.bmin[0] += pad;
+               cset.bmin[2] += pad;
+               cset.bmax[0] -= pad;
+               cset.bmax[2] -= pad;
+       }
        cset.cs = chf.cs;
        cset.ch = chf.ch;
+       cset.width = chf.width - chf.borderSize*2;
+       cset.height = chf.height - chf.borderSize*2;
+       cset.borderSize = chf.borderSize;
        
-       const int maxContours = chf.maxRegions*2;
-       cset.conts = new rcContour[maxContours];
+       int maxContours = rcMax((int)chf.maxRegions, 8);
+       cset.conts = (rcContour*)rcAlloc(sizeof(rcContour)*maxContours, RC_ALLOC_PERM);
        if (!cset.conts)
                return false;
        cset.nconts = 0;
        
-       unsigned char* flags = new unsigned char[chf.spanCount];
+       rcScopedDelete<unsigned char> flags = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
        if (!flags)
        {
-               if (rcGetLog())
-                       rcGetLog()->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'flags'.");
+               ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'flags' (%d).", chf.spanCount);
                return false;
        }
        
-       rcTimeVal traceStartTime = rcGetPerformanceTimer();
-                                       
+       ctx->startTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
        
        // Mark boundaries.
        for (int y = 0; y < h; ++y)
@@ -572,7 +659,7 @@ bool rcBuildContours(rcCompactHeightfield& chf,
                        {
                                unsigned char res = 0;
                                const rcCompactSpan& s = chf.spans[i];
-                               if (!s.reg || (s.reg & RC_BORDER_REG))
+                               if (!chf.spans[i].reg || (chf.spans[i].reg & RC_BORDER_REG))
                                {
                                        flags[i] = 0;
                                        continue;
@@ -580,15 +667,14 @@ bool rcBuildContours(rcCompactHeightfield& chf,
                                for (int dir = 0; dir < 4; ++dir)
                                {
                                        unsigned short r = 0;
-                                       if (rcGetCon(s, dir) != 0xf)
+                                       if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
                                        {
                                                const int ax = x + rcGetDirOffsetX(dir);
                                                const int ay = y + rcGetDirOffsetY(dir);
                                                const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
-                                               const rcCompactSpan& as = chf.spans[ai];
-                                               r = as.reg;
+                                               r = chf.spans[ai].reg;
                                        }
-                                       if (r == s.reg)
+                                       if (r == chf.spans[i].reg)
                                                res |= (1 << dir);
                                }
                                flags[i] = res ^ 0xf; // Inverse, mark non connected edges.
@@ -596,9 +682,7 @@ bool rcBuildContours(rcCompactHeightfield& chf,
                }
        }
        
-       rcTimeVal traceEndTime = rcGetPerformanceTimer();
-       
-       rcTimeVal simplifyStartTime = rcGetPerformanceTimer();
+       ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
        
        rcIntArray verts(256);
        rcIntArray simplified(64);
@@ -615,36 +699,87 @@ bool rcBuildContours(rcCompactHeightfield& chf,
                                        flags[i] = 0;
                                        continue;
                                }
-                               unsigned short reg = chf.spans[i].reg;
+                               const unsigned short reg = chf.spans[i].reg;
                                if (!reg || (reg & RC_BORDER_REG))
                                        continue;
+                               const unsigned char area = chf.areas[i];
                                
                                verts.resize(0);
                                simplified.resize(0);
+
+                               ctx->startTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
                                walkContour(x, y, i, chf, flags, verts);
-                               simplifyContour(verts, simplified, maxError, maxEdgeLen);
+                               ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_TRACE);
+
+                               ctx->startTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
+                               simplifyContour(verts, simplified, maxError, maxEdgeLen, buildFlags);
                                removeDegenerateSegments(simplified);
+                               ctx->stopTimer(RC_TIMER_BUILD_CONTOURS_SIMPLIFY);
                                
+
                                // Store region->contour remap info.
                                // Create contour.
                                if (simplified.size()/4 >= 3)
                                {
                                        if (cset.nconts >= maxContours)
                                        {
-                                               if (rcGetLog())
-                                                       rcGetLog()->log(RC_LOG_ERROR, "rcBuildContours: Too many contours %d, max %d.", cset.nconts, maxContours);
-                                               return false;
+                                               // Allocate more contours.
+                                               // This can happen when there are tiny holes in the heightfield.
+                                               const int oldMax = maxContours;
+                                               maxContours *= 2;
+                                               rcContour* newConts = (rcContour*)rcAlloc(sizeof(rcContour)*maxContours, RC_ALLOC_PERM);
+                                               for (int j = 0; j < cset.nconts; ++j)
+                                               {
+                                                       newConts[j] = cset.conts[j];
+                                                       // Reset source pointers to prevent data deletion.
+                           &