forked from bartvdbraak/blender
Merged changes in the trunk up to revision 40911.
Conflicts resolved: source/blender/blenloader/intern/readfile.c
This commit is contained in:
commit
d546002476
211
CMakeLists.txt
211
CMakeLists.txt
@ -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)
|
||||
@ -197,7 +196,7 @@ option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)"
|
||||
|
||||
# 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()
|
||||
@ -273,7 +272,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)
|
||||
@ -286,8 +285,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)
|
||||
@ -298,26 +297,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 \
|
||||
@ -329,7 +328,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}")
|
||||
@ -381,10 +380,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)
|
||||
@ -428,11 +429,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()
|
||||
|
||||
@ -443,13 +446,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)
|
||||
@ -488,17 +484,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)
|
||||
@ -519,16 +515,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")
|
||||
@ -551,7 +547,7 @@ elseif(WIN32)
|
||||
message("64 bit compiler detected.")
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
|
||||
endif()
|
||||
|
||||
|
||||
add_definitions(-DWIN32)
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
@ -561,13 +557,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
|
||||
@ -576,7 +565,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)
|
||||
@ -641,9 +630,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)
|
||||
@ -684,7 +673,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
|
||||
@ -741,7 +730,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
|
||||
)
|
||||
@ -800,9 +789,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)
|
||||
@ -817,7 +806,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)
|
||||
@ -837,13 +826,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)
|
||||
@ -870,7 +859,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()
|
||||
@ -908,7 +897,7 @@ elseif(APPLE)
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin-8.0.0-powerpc)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
if(WITH_OPENAL)
|
||||
find_package(OpenAL)
|
||||
@ -952,8 +941,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()
|
||||
|
||||
@ -991,22 +980,15 @@ 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)
|
||||
if(SYSTEMSTUBS_LIBRARY)
|
||||
set(PLATFORM_LINKLIBS stdc++ SystemStubs)
|
||||
else()
|
||||
else()
|
||||
set(PLATFORM_LINKLIBS stdc++)
|
||||
endif()
|
||||
|
||||
@ -1018,13 +1000,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
|
||||
@ -1101,11 +1083,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")
|
||||
@ -1124,43 +1106,34 @@ 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()
|
||||
|
||||
|
||||
# set the endian define
|
||||
include(TestBigEndian)
|
||||
test_big_endian(_SYSTEM_BIG_ENDIAN)
|
||||
if(_SYSTEM_BIG_ENDIAN)
|
||||
add_definitions(-D__BIG_ENDIAN__)
|
||||
else()
|
||||
if(MSVC)
|
||||
# for some reason this fails on msvc
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
else()
|
||||
include(TestBigEndian)
|
||||
test_big_endian(_SYSTEM_BIG_ENDIAN)
|
||||
if(_SYSTEM_BIG_ENDIAN)
|
||||
add_definitions(-D__BIG_ENDIAN__)
|
||||
else()
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
endif()
|
||||
unset(_SYSTEM_BIG_ENDIAN)
|
||||
endif()
|
||||
unset(_SYSTEM_BIG_ENDIAN)
|
||||
|
||||
|
||||
if(WITH_IMAGE_OPENJPEG)
|
||||
@ -1179,7 +1152,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")
|
||||
|
||||
@ -1191,13 +1164,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}")
|
||||
@ -1209,9 +1182,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
|
||||
@ -1226,8 +1201,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()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -1235,7 +1212,7 @@ endif()
|
||||
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_definitions(-DPy_ENABLE_SHARED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Extra compile flags
|
||||
@ -1244,7 +1221,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")
|
||||
@ -1269,7 +1246,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEFINED -Wundef)
|
||||
|
||||
# # this causes too many warnings, disable
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEFINED -Wundef)
|
||||
|
||||
# disable because it gives warnings for printf() & friends.
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
|
||||
@ -1277,7 +1257,9 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
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)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEFINED -Wundef)
|
||||
|
||||
# # this causes too many warnings, disable
|
||||
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEFINED -Wundef)
|
||||
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
@ -1289,6 +1271,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
|
||||
@ -1389,8 +1375,8 @@ if(FIRST_RUN)
|
||||
macro(info_cfg_text
|
||||
_text)
|
||||
set(_config_msg "${_config_msg}\n\n ${_text}")
|
||||
|
||||
|
||||
|
||||
|
||||
endmacro()
|
||||
|
||||
info_cfg_text("Build Options:")
|
||||
@ -1428,7 +1414,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)
|
||||
|
@ -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
|
||||
|
16
SConstruct
16
SConstruct
@ -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']:
|
||||
|
@ -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']
|
||||
|
@ -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']
|
||||
|
@ -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']
|
||||
|
@ -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']
|
||||
|
@ -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})
|
||||
# only search for the dirs if we havn't already
|
||||
IF((NOT DEFINED PYTHON_INCLUDE_DIR) OR (NOT DEFINED PYTHON_LIBRARY))
|
||||
|
||||
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}
|
||||
SET(_python_ABI_FLAGS
|
||||
"m;mu;u; " # release
|
||||
"md;mud;ud;d" # debug
|
||||
)
|
||||
|
||||
FIND_LIBRARY(PYTHON_LIBRARY
|
||||
NAMES
|
||||
"python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}"
|
||||
HINTS
|
||||
${_python_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
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}"
|
||||
)
|
||||
|
||||
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()
|
||||
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})
|
||||
|
||||
UNSET(_CURRENT_ABI_FLAGS)
|
||||
UNSET(_CURRENT_PATH)
|
||||
FIND_PATH(PYTHON_INCLUDE_DIR
|
||||
NAMES
|
||||
Python.h
|
||||
HINTS
|
||||
${_python_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
|
||||
)
|
||||
|
||||
UNSET(_python_ABI_FLAGS)
|
||||
UNSET(_python_SEARCH_DIRS)
|
||||
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
|
||||
|
@ -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
|
||||
)
|
@ -58,8 +58,8 @@ def main():
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
|
||||
process_functions = []
|
||||
|
||||
def my_process(i, c, cmd):
|
||||
percent = 100.0 * (i / (len(check_commands) - 1))
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
@ -482,7 +490,7 @@ macro(get_blender_version)
|
||||
if(${_out_version_char_empty})
|
||||
set(BLENDER_VERSION_CHAR_INDEX "0")
|
||||
else()
|
||||
set(_char_ls a b c d e f g h i j k l m n o p q r s t u v w q y z)
|
||||
set(_char_ls a b c d e f g h i j k l m n o p q r s t u v w x y z)
|
||||
list(FIND _char_ls ${BLENDER_VERSION_CHAR} _out_version_char_index)
|
||||
math(EXPR BLENDER_VERSION_CHAR_INDEX "${_out_version_char_index} + 1")
|
||||
unset(_char_ls)
|
||||
@ -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)
|
||||
|
||||
|
@ -161,8 +161,6 @@ def queue_processes(process_funcs, job_total=-1):
|
||||
del multiprocessing
|
||||
|
||||
if job_total == 1:
|
||||
import os
|
||||
import sys
|
||||
for func, args in process_funcs:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
@ -171,14 +169,13 @@ def queue_processes(process_funcs, job_total=-1):
|
||||
process.wait()
|
||||
else:
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
processes = []
|
||||
for func, args in process_funcs:
|
||||
# wait until a thread is free
|
||||
while 1:
|
||||
processes[:] = [p for p in processes if p.poll() is None]
|
||||
|
||||
|
||||
if len(processes) <= job_total:
|
||||
break
|
||||
else:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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']
|
||||
|
@ -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']
|
||||
|
@ -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'])
|
||||
@ -561,25 +554,24 @@ def AppIt(target=None, source=None, env=None):
|
||||
cmd = 'cp %s/%s %s/%s.app/Contents/MacOS/%s'%(builddir, binary,installdir, binary, binary)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/'%(installdir, binary, VERSION)
|
||||
# print cmd
|
||||
commands.getoutput(cmd)
|
||||
cmd = installdir + '/%s.app/Contents/MacOS/%s'%(binary,VERSION)
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/datafiles'%(installdir, binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/bin/.blender/locale %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
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)
|
||||
|
||||
# blenderplayer doesn't need all the files
|
||||
if binary == 'blender':
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/datafiles'%(installdir, binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/bin/.blender/locale %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
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 -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
if env['WITH_OSX_STATICPYTHON']:
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
if binary == 'blender':#not copy everything for blenderplayer
|
||||
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
|
||||
@ -633,7 +625,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)
|
||||
@ -695,7 +691,7 @@ class BlenderEnvironment(SConsEnvironment):
|
||||
SConsEnvironment.Default(self, res)
|
||||
resources.append(res)
|
||||
|
||||
def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None):
|
||||
def BlenderLib(self=None, libname=None, sources=None, includes=[], defines=[], libtype='common', priority = 100, compileflags=None, cc_compileflags=None, cxx_compileflags=None, cc_compilerchange=None, cxx_compilerchange=None):
|
||||
global vcp
|
||||
if not self or not libname or not sources:
|
||||
print bc.FAIL+'Cannot continue. Missing argument for BuildBlenderLib '+libname+bc.ENDC
|
||||
@ -733,6 +729,10 @@ class BlenderEnvironment(SConsEnvironment):
|
||||
lenv.Replace(CCFLAGS = cc_compileflags)
|
||||
if cxx_compileflags:
|
||||
lenv.Replace(CXXFLAGS = cxx_compileflags)
|
||||
if cc_compilerchange:
|
||||
lenv.Replace(CC = cc_compilerchange)
|
||||
if cxx_compilerchange:
|
||||
lenv.Replace(CXX = cxx_compilerchange)
|
||||
lenv.Append(CFLAGS = lenv['C_WARN'])
|
||||
lenv.Append(CCFLAGS = lenv['CC_WARN'])
|
||||
lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
|
||||
|
@ -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', ''),
|
||||
|
@ -11,7 +11,7 @@ $Id$
|
||||
3. Obtaining Dependencies
|
||||
4. Deciding on a Build Environment
|
||||
5. Configuring the build for the first time
|
||||
6. Configuring the build after CVS updates
|
||||
6. Configuring the build after SVN updates
|
||||
7. Specify alternate Python library versions and locations
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ $Id$
|
||||
http://www.blender.org/cms/Getting_Dependencies.135.0.html that you
|
||||
have all dependencies needed for building Blender. Note that for
|
||||
windows many of these dependencies already come in the lib/windows
|
||||
module from CVS.
|
||||
module from SVN.
|
||||
|
||||
4. Deciding on a Build Environment
|
||||
----------------------------------
|
||||
@ -47,8 +47,8 @@ $Id$
|
||||
have been successfully used to generate build files for the following
|
||||
environments:
|
||||
|
||||
1. Microsoft Visual Studio 2005. There is a free version available
|
||||
at http://msdn.microsoft.com/vstudio/express/visualc/.
|
||||
1. Microsoft Visual Studio 2008. There is a free version available
|
||||
at http://http://www.microsoft.com/visualstudio/en-us/products/2008-editions/express
|
||||
|
||||
2. Xcode on Mac OSX
|
||||
|
||||
@ -65,7 +65,7 @@ $Id$
|
||||
with different Blender configurations (Audio/NoAudio, GameEngine/NoGameEngine etc.)
|
||||
while maintaining a clean source tree. It also makes it possible to generate files
|
||||
for different build systems on the same source tree. This also has benefits for
|
||||
general CVS management for the developer as patches and submit logs are much cleaner.
|
||||
general SVN management for the developer as patches and submit logs are much cleaner.
|
||||
|
||||
Create a directory outside the blender source tree where you would like to build
|
||||
Blender (from now on called $BLENDERBUILD). On the commandline you can then run
|
||||
@ -78,27 +78,27 @@ $Id$
|
||||
% cd $BLENDERBUILD
|
||||
% cmake
|
||||
|
||||
...
|
||||
...
|
||||
--version [file] = Show program name/version banner and exit.
|
||||
...
|
||||
...
|
||||
--version [file] = Show program name/version banner and exit.
|
||||
|
||||
Generators
|
||||
Generators
|
||||
|
||||
The following generators are available on this platform:
|
||||
KDevelop3 = Generates KDevelop 3 project files.
|
||||
Unix Makefiles = Generates standard UNIX makefiles.
|
||||
Xcode = Generate XCode project files.
|
||||
The following generators are available on this platform:
|
||||
KDevelop3 = Generates KDevelop 3 project files.
|
||||
Unix Makefiles = Generates standard UNIX makefiles.
|
||||
Xcode = Generate XCode project files.
|
||||
|
||||
|
||||
|
||||
% cmake -G Xcode $BLENDERSOURCE
|
||||
...
|
||||
...
|
||||
-- Configuring blender
|
||||
-- Configuring blenderplayer
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: $BLENDERBUILD
|
||||
...
|
||||
...
|
||||
-- Configuring blender
|
||||
-- Configuring blenderplayer
|
||||
-- Configuring done
|
||||
-- Generating done
|
||||
-- Build files have been written to: $BLENDERBUILD
|
||||
|
||||
This will generate the build files with default values. Specific features can
|
||||
be enabled or disabled by running the ccmake "GUI" from $BLENDERBUILD as follows:
|
||||
@ -114,15 +114,15 @@ $Id$
|
||||
It is also possible to use the commandline of 'cmake' to override certain
|
||||
of these settings.
|
||||
|
||||
6. Configuring the build after CVS updates
|
||||
6. Configuring the build after SVN updates
|
||||
------------------------------------------
|
||||
|
||||
The $BLENDERBUILD directory maintains a file called CMakeCache.txt which
|
||||
remembers the initial run's settings for subsequent generation runs. After
|
||||
every CVS update it may be a good idea to rerun the generation before building
|
||||
every SVN update it may be a good idea to rerun the generation before building
|
||||
Blender again. Just rerun the original 'cmake' run to do this, the settings
|
||||
will be remembered. For the example above the following will do after every
|
||||
'cvs up':
|
||||
'svn up':
|
||||
|
||||
% cmake -G Xcode $BLENDERSOURCE
|
||||
|
||||
@ -132,9 +132,9 @@ $Id$
|
||||
The commandline can be used to override detected/default settings, e.g:
|
||||
|
||||
On Unix:
|
||||
cmake -D PYTHON_LIBRARY=/usr/local/lib/python3.1/config/libpython3.1.so -D PYTHON_INCLUDE_DIRS=/usr/local/include/python3.1 -G "Unix Makefiles" ../blender
|
||||
cmake -D PYTHON_LIBRARY=/usr/local/lib/python3.2/config/libpython3.2.so -D PYTHON_INCLUDE_DIR=/usr/local/include/python3.2 ../blender
|
||||
On Macs:
|
||||
cmake -D PYTHON_INCLUDE_DIRS=/System/Library/Frameworks/Python.framework/Versions/3.1/include/python3.1 -G Xcode ../blender
|
||||
cmake -D PYTHON_INCLUDE_DIRS=/System/Library/Frameworks/Python.framework/Versions/3.2/include/python3.2 -G Xcode ../blender
|
||||
|
||||
Mote that this should only be needed once per build directory generation because it will keep the overrides in CMakeCache.txt for subsequent runs.
|
||||
|
||||
@ -153,4 +153,3 @@ $Id$
|
||||
on the various platforms.
|
||||
|
||||
/Jacques Beaurain (jbinto)
|
||||
|
||||
|
@ -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()
|
||||
|
@ -909,3 +909,574 @@ 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
|
||||
------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.RenderSettings.ffmpeg_audio_channels`
|
||||
|
||||
bpy.types.DriverTarget
|
||||
----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.DriverTarget.transform_space`
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
* **use_local_space_transform**
|
||||
|
||||
bpy.types.Sound
|
||||
---------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Sound.factory`
|
||||
* :class:`bpy.types.Sound.use_mono`
|
||||
|
||||
bpy.types.Camera
|
||||
----------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Camera.view_frame`
|
||||
|
||||
bpy.types.Scene
|
||||
---------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Scene.audio_volume`
|
||||
|
||||
bpy.types.KeyingSet
|
||||
-------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.KeyingSet.refresh`
|
||||
|
||||
bpy.types.Armature
|
||||
------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Armature.deform_method`
|
||||
|
||||
bpy.types.GameObjectSettings
|
||||
----------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.GameObjectSettings.obstacle_radius`
|
||||
* :class:`bpy.types.GameObjectSettings.use_obstacle_create`
|
||||
|
||||
bpy.types.BlendData
|
||||
-------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.BlendData.speakers`
|
||||
|
||||
bpy.types.SolidifyModifier
|
||||
--------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.SolidifyModifier.thickness_vertex_group`
|
||||
|
||||
bpy.types.ThemeGraphEditor
|
||||
--------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ThemeGraphEditor.handle_auto_clamped`
|
||||
* :class:`bpy.types.ThemeGraphEditor.handle_sel_auto_clamped`
|
||||
|
||||
bpy.types.CompositorNodeIDMask
|
||||
------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.CompositorNodeIDMask.use_smooth_mask`
|
||||
|
||||
bpy.types.Node
|
||||
--------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Node.parent`
|
||||
|
||||
bpy.types.Texture
|
||||
-----------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Texture.evaluate`
|
||||
|
||||
bpy.types.UILayout
|
||||
------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.UILayout.template_keymap_item_properties`
|
||||
|
||||
bpy.types.ToolSettings
|
||||
----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ToolSettings.use_multipaint`
|
||||
|
||||
bpy.types.UserPreferencesInput
|
||||
------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :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_tilt_invert_axis`
|
||||
|
||||
bpy.types.LockedTrackConstraint
|
||||
-------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.LockedTrackConstraint.head_tail`
|
||||
|
||||
bpy.types.SpaceGraphEditor
|
||||
--------------------------
|
||||
|
||||
Moved
|
||||
^^^^^
|
||||
|
||||
* use_fancy_drawing -> :class:`bpy.types.SpaceGraphEditor.use_beauty_drawing`
|
||||
|
||||
bpy.types.ParticleSystem
|
||||
------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ParticleSystem.dt_frac`
|
||||
|
||||
bpy.types.Mesh
|
||||
--------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Mesh.use_paint_mask_vertex`
|
||||
|
||||
bpy.types.FCurve
|
||||
----------------
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
* **use_auto_handle_clamp**
|
||||
|
||||
bpy.types.DampedTrackConstraint
|
||||
-------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.DampedTrackConstraint.head_tail`
|
||||
|
||||
bpy.types.ImageTexture
|
||||
----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ImageTexture.use_derivative_map`
|
||||
|
||||
bpy.types.SoundSequence
|
||||
-----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.SoundSequence.pan`
|
||||
* :class:`bpy.types.SoundSequence.pitch`
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
* **attenuation**
|
||||
|
||||
bpy.types.FModifier
|
||||
-------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.FModifier.blend_in`
|
||||
* :class:`bpy.types.FModifier.blend_out`
|
||||
* :class:`bpy.types.FModifier.frame_end`
|
||||
* :class:`bpy.types.FModifier.frame_start`
|
||||
* :class:`bpy.types.FModifier.influence`
|
||||
* :class:`bpy.types.FModifier.use_influence`
|
||||
* :class:`bpy.types.FModifier.use_restricted_range`
|
||||
|
||||
bpy.types.EnvironmentMap
|
||||
------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.EnvironmentMap.clear`
|
||||
* :class:`bpy.types.EnvironmentMap.is_valid`
|
||||
* :class:`bpy.types.EnvironmentMap.save`
|
||||
|
||||
bpy.types.UserPreferencesSystem
|
||||
-------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.UserPreferencesSystem.use_translate_interface`
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
* **use_translate_buttons**
|
||||
* **use_translate_toolbox**
|
||||
|
||||
bpy.types.LimitDistanceConstraint
|
||||
---------------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.LimitDistanceConstraint.head_tail`
|
||||
* :class:`bpy.types.LimitDistanceConstraint.use_transform_limit`
|
||||
|
||||
bpy.types.MovieSequence
|
||||
-----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.MovieSequence.stream_index`
|
||||
|
||||
bpy.types.Material
|
||||
------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Material.game_settings`
|
||||
|
||||
bpy.types.Object
|
||||
----------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Object.matrix_parent_inverse`
|
||||
|
||||
bpy.types.SequenceProxy
|
||||
-----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.SequenceProxy.build_100`
|
||||
* :class:`bpy.types.SequenceProxy.build_25`
|
||||
* :class:`bpy.types.SequenceProxy.build_50`
|
||||
* :class:`bpy.types.SequenceProxy.build_75`
|
||||
* :class:`bpy.types.SequenceProxy.build_free_run`
|
||||
* :class:`bpy.types.SequenceProxy.build_free_run_rec_date`
|
||||
* :class:`bpy.types.SequenceProxy.build_record_run`
|
||||
* :class:`bpy.types.SequenceProxy.quality`
|
||||
* :class:`bpy.types.SequenceProxy.timecode`
|
||||
|
||||
bpy.types.Sequence
|
||||
------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Sequence.waveform`
|
||||
|
||||
bpy.types.DopeSheet
|
||||
-------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.DopeSheet.show_datablock_filters`
|
||||
* :class:`bpy.types.DopeSheet.show_speakers`
|
||||
|
||||
bpy.types.ActionActuator
|
||||
------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ActionActuator.apply_to_children`
|
||||
* :class:`bpy.types.ActionActuator.layer`
|
||||
* :class:`bpy.types.ActionActuator.layer_weight`
|
||||
* :class:`bpy.types.ActionActuator.use_additive`
|
||||
* :class:`bpy.types.ActionActuator.use_force`
|
||||
* :class:`bpy.types.ActionActuator.use_local`
|
||||
|
||||
bpy.types.VertexGroup
|
||||
---------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.VertexGroup.lock_weight`
|
||||
|
||||
bpy.types.ThemeView3D
|
||||
---------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ThemeView3D.speaker`
|
||||
|
||||
bpy.types.Image
|
||||
---------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Image.pack`
|
||||
* :class:`bpy.types.Image.unpack`
|
||||
|
||||
bpy.types.Curve
|
||||
---------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.Curve.fill_mode`
|
||||
|
||||
Removed
|
||||
^^^^^^^
|
||||
|
||||
* **use_fill_back**
|
||||
* **use_fill_front**
|
||||
|
||||
bpy.types.ParticleSettings
|
||||
--------------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.ParticleSettings.adaptive_subframes`
|
||||
* :class:`bpy.types.ParticleSettings.courant_target`
|
||||
|
||||
bpy.types.SceneGameData
|
||||
-----------------------
|
||||
|
||||
Added
|
||||
^^^^^
|
||||
|
||||
* :class:`bpy.types.SceneGameData.level_height`
|
||||
* :class:`bpy.types.SceneGameData.obstacle_simulation`
|
||||
* :class:`bpy.types.SceneGameData.recast_data`
|
||||
* :class:`bpy.types.SceneGameData.restrict_animation_updates`
|
||||
* :class:`bpy.types.SceneGameData.show_obstacle_simulation`
|
||||
|
||||
|
@ -39,6 +39,9 @@ python doc/python_api/sphinx_changelog_gen.py \
|
||||
--api_to blender_api_2_57.py \
|
||||
--api_out changes.rst
|
||||
|
||||
# Save the latest API dump in this folder, renaming it with its revision.
|
||||
# This way the next person updating it doesn't need to build an old Blender only for that
|
||||
|
||||
"""
|
||||
|
||||
# format
|
||||
@ -299,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()
|
||||
|
@ -163,7 +163,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 = []
|
||||
@ -362,7 +362,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
|
||||
|
||||
@ -518,7 +518,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")
|
||||
@ -706,7 +706,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", "")
|
||||
@ -920,7 +920,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, "=")
|
||||
@ -971,7 +971,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()
|
||||
@ -1025,7 +1025,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)
|
||||
@ -1061,7 +1061,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")
|
||||
@ -1179,7 +1179,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")
|
||||
@ -1191,7 +1191,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")
|
||||
@ -1204,7 +1204,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")
|
||||
@ -1298,7 +1298,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")
|
||||
|
9
extern/recastnavigation/CMakeLists.txt
vendored
9
extern/recastnavigation/CMakeLists.txt
vendored
@ -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}")
|
||||
|
1275
extern/recastnavigation/Recast/Include/Recast.h
vendored
1275
extern/recastnavigation/Recast/Include/Recast.h
vendored
File diff suppressed because it is too large
Load Diff
122
extern/recastnavigation/Recast/Include/RecastAlloc.h
vendored
Normal file
122
extern/recastnavigation/Recast/Include/RecastAlloc.h
vendored
Normal file
@ -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
|
33
extern/recastnavigation/Recast/Include/RecastAssert.h
vendored
Normal file
33
extern/recastnavigation/Recast/Include/RecastAssert.h
vendored
Normal file
@ -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
|
337
extern/recastnavigation/Recast/Source/Recast.cpp
vendored
337
extern/recastnavigation/Recast/Source/Recast.cpp
vendored
@ -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
|
||||
@ -22,35 +22,178 @@
|
||||
#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"
|
||||
|
||||
|
||||
void rcIntArray::resize(int n)
|
||||
float rcSqrt(float x)
|
||||
{
|
||||
if (n > m_cap)
|
||||
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.
|
||||
///
|
||||
|
||||
/// @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 (!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;
|
||||
}
|
||||
}
|
||||
|
||||
static int getSpanCount(unsigned char flags, rcHeightfield& hf)
|
||||
/// @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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
/// @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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
*/
|
88
extern/recastnavigation/Recast/Source/RecastAlloc.cpp
vendored
Normal file
88
extern/recastnavigation/Recast/Source/RecastAlloc.cpp
vendored
Normal file
@ -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;
|
||||
}
|
||||
|
524
extern/recastnavigation/Recast/Source/RecastArea.cpp
vendored
Normal file
524
extern/recastnavigation/Recast/Source/RecastArea.cpp
vendored
Normal file
@ -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);
|
||||
}
|
@ -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);
|
||||
const 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];
|
||||
|
||||
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.
|
||||
cset.conts[j].verts = 0;
|
||||
cset.conts[j].rverts = 0;
|
||||
}
|
||||
rcFree(cset.conts);
|
||||
cset.conts = newConts;
|
||||
|
||||
ctx->log(RC_LOG_WARNING, "rcBuildContours: Expanding max contours from %d to %d.", oldMax, maxContours);
|
||||
}
|
||||
|
||||
rcContour* cont = &cset.conts[cset.nconts++];
|
||||
|
||||
cont->nverts = simplified.size()/4;
|
||||
cont->verts = new int[cont->nverts*4];
|
||||
cont->verts = (int*)rcAlloc(sizeof(int)*cont->nverts*4, RC_ALLOC_PERM);
|
||||
if (!cont->verts)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'verts' (%d).", cont->nverts);
|
||||
return false;
|
||||
}
|
||||
memcpy(cont->verts, &simplified[0], sizeof(int)*cont->nverts*4);
|
||||
if (borderSize > 0)
|
||||
{
|
||||
// If the heightfield was build with bordersize, remove the offset.
|
||||
for (int i = 0; i < cont->nverts; ++i)
|
||||
{
|
||||
int* v = &cont->verts[i*4];
|
||||
v[0] -= borderSize;
|
||||
v[2] -= borderSize;
|
||||
}
|
||||
}
|
||||
|
||||
cont->nrverts = verts.size()/4;
|
||||
cont->rverts = new int[cont->nrverts*4];
|
||||
cont->rverts = (int*)rcAlloc(sizeof(int)*cont->nrverts*4, RC_ALLOC_PERM);
|
||||
if (!cont->rverts)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'rverts' (%d).", cont->nrverts);
|
||||
return false;
|
||||
}
|
||||
memcpy(cont->rverts, &verts[0], sizeof(int)*cont->nrverts*4);
|
||||
if (borderSize > 0)
|
||||
{
|
||||
// If the heightfield was build with bordersize, remove the offset.
|
||||
for (int i = 0; i < cont->nrverts; ++i)
|
||||
{
|
||||
int* v = &cont->rverts[i*4];
|
||||
v[0] -= borderSize;
|
||||
v[2] -= borderSize;
|
||||
}
|
||||
}
|
||||
|
||||
/* cont->cx = cont->cy = cont->cz = 0;
|
||||
for (int i = 0; i < cont->nverts; ++i)
|
||||
@ -658,13 +793,14 @@ bool rcBuildContours(rcCompactHeightfield& chf,
|
||||
cont->cz /= cont->nverts;*/
|
||||
|
||||
cont->reg = reg;
|
||||
cont->area = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check and merge droppings.
|
||||
// Sometimes the previous algorithms can fail and create several countours
|
||||
// Sometimes the previous algorithms can fail and create several contours
|
||||
// per area. This pass will try to merge the holes into the main region.
|
||||
for (int i = 0; i < cset.nconts; ++i)
|
||||
{
|
||||
@ -689,44 +825,29 @@ bool rcBuildContours(rcCompactHeightfield& chf,
|
||||
}
|
||||
if (mergeIdx == -1)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "rcBuildContours: Could not find merge target for bad contour %d.", i);
|
||||
ctx->log(RC_LOG_WARNING, "rcBuildContours: Could not find merge target for bad contour %d.", i);
|
||||
}
|
||||
else
|
||||
{
|
||||
rcContour& mcont = cset.conts[mergeIdx];
|
||||
// Merge by closest points.
|
||||
int ia, ib;
|
||||
int ia = 0, ib = 0;
|
||||
getClosestIndices(mcont.verts, mcont.nverts, cont.verts, cont.nverts, ia, ib);
|
||||
if (ia == -1 || ib == -1)
|
||||
{
|
||||
ctx->log(RC_LOG_WARNING, "rcBuildContours: Failed to find merge points for %d and %d.", i, mergeIdx);
|
||||
continue;
|
||||
}
|
||||
if (!mergeContours(mcont, cont, ia, ib))
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "rcBuildContours: Failed to merge contours %d and %d.", i, mergeIdx);
|
||||
ctx->log(RC_LOG_WARNING, "rcBuildContours: Failed to merge contours %d and %d.", i, mergeIdx);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete [] flags;
|
||||
|
||||
rcTimeVal simplifyEndTime = rcGetPerformanceTimer();
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
|
||||
// if (rcGetLog())
|
||||
// {
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, "Create contours: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, " - boundary: %.3f ms", rcGetDeltaTimeUsec(boundaryStartTime, boundaryEndTime)/1000.0f);
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, " - contour: %.3f ms", rcGetDeltaTimeUsec(contourStartTime, contourEndTime)/1000.0f);
|
||||
// }
|
||||
|
||||
if (rcGetBuildTimes())
|
||||
{
|
||||
rcGetBuildTimes()->buildContours += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
rcGetBuildTimes()->buildContoursTrace += rcGetDeltaTimeUsec(traceStartTime, traceEndTime);
|
||||
rcGetBuildTimes()->buildContoursSimplify += rcGetDeltaTimeUsec(simplifyStartTime, simplifyEndTime);
|
||||
}
|
||||
ctx->stopTimer(RC_TIMER_BUILD_CONTOURS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -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
|
||||
@ -20,15 +20,73 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "Recast.h"
|
||||
#include "RecastLog.h"
|
||||
#include "RecastTimer.h"
|
||||
#include "RecastAssert.h"
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// Allows the formation of walkable regions that will flow over low lying
|
||||
/// objects such as curbs, and up structures such as stairways.
|
||||
///
|
||||
/// Two neighboring spans are walkable if: <tt>rcAbs(currentSpan.smax - neighborSpan.smax) < waklableClimb</tt>
|
||||
///
|
||||
/// @warning Will override the effect of #rcFilterLedgeSpans. So if both filters are used, call
|
||||
/// #rcFilterLedgeSpans after calling this filter.
|
||||
///
|
||||
/// @see rcHeightfield, rcConfig
|
||||
void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
void rcFilterLedgeSpans(const int walkableHeight,
|
||||
const int walkableClimb,
|
||||
ctx->startTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
rcSpan* ps = 0;
|
||||
bool previousWalkable = false;
|
||||
unsigned char previousArea = RC_NULL_AREA;
|
||||
|
||||
for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next)
|
||||
{
|
||||
const bool walkable = s->area != RC_NULL_AREA;
|
||||
// If current span is not walkable, but there is walkable
|
||||
// span just below it, mark the span above it walkable too.
|
||||
if (!walkable && previousWalkable)
|
||||
{
|
||||
if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb)
|
||||
s->area = previousArea;
|
||||
}
|
||||
// Copy walkable flag so that it cannot propagate
|
||||
// past multiple non-walkable objects.
|
||||
previousWalkable = walkable;
|
||||
previousArea = s->area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_FILTER_LOW_OBSTACLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// A ledge is a span with one or more neighbors whose maximum is further away than @p walkableClimb
|
||||
/// from the current span's maximum.
|
||||
/// This method removes the impact of the overestimation of conservative voxelization
|
||||
/// so the resulting mesh will not have regions hanging in the air over ledges.
|
||||
///
|
||||
/// A span is a ledge if: <tt>rcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb</tt>
|
||||
///
|
||||
/// @see rcHeightfield, rcConfig
|
||||
void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb,
|
||||
rcHeightfield& solid)
|
||||
{
|
||||
rcTimeVal startTime = rcGetPerformanceTimer();
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_FILTER_BORDER);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -42,15 +100,19 @@ void rcFilterLedgeSpans(const int walkableHeight,
|
||||
for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
|
||||
{
|
||||
// Skip non walkable spans.
|
||||
if ((s->flags & RC_WALKABLE) == 0)
|
||||
if (s->area == RC_NULL_AREA)
|
||||
continue;
|
||||
|
||||
const int bot = (int)s->smax;
|
||||
const int top = s->next ? (int)s->next->smin : MAX_HEIGHT;
|
||||
const int bot = (int)(s->smax);
|
||||
const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
|
||||
|
||||
// Find neighbours minimum height.
|
||||
int minh = MAX_HEIGHT;
|
||||
|
||||
// Min and max height of accessible neighbours.
|
||||
int asmin = s->smax;
|
||||
int asmax = s->smax;
|
||||
|
||||
for (int dir = 0; dir < 4; ++dir)
|
||||
{
|
||||
int dx = x + rcGetDirOffsetX(dir);
|
||||
@ -77,30 +139,49 @@ void rcFilterLedgeSpans(const int walkableHeight,
|
||||
ntop = ns->next ? (int)ns->next->smin : MAX_HEIGHT;
|
||||
// Skip neightbour if the gap between the spans is too small.
|
||||
if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight)
|
||||
{
|
||||
minh = rcMin(minh, nbot - bot);
|
||||
|
||||
// Find min/max accessible neighbour height.
|
||||
if (rcAbs(nbot - bot) <= walkableClimb)
|
||||
{
|
||||
if (nbot < asmin) asmin = nbot;
|
||||
if (nbot > asmax) asmax = nbot;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The current span is close to a ledge if the drop to any
|
||||
// neighbour span is less than the walkableClimb.
|
||||
if (minh < -walkableClimb)
|
||||
s->flags &= ~RC_WALKABLE;
|
||||
|
||||
s->area = RC_NULL_AREA;
|
||||
|
||||
// If the difference between all neighbours is too large,
|
||||
// we are at steep slope, mark the span as ledge.
|
||||
if ((asmax - asmin) > walkableClimb)
|
||||
{
|
||||
s->area = RC_NULL_AREA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
// if (rcGetLog())
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, "Filter border: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
|
||||
if (rcGetBuildTimes())
|
||||
rcGetBuildTimes()->filterBorder += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
ctx->stopTimer(RC_TIMER_FILTER_BORDER);
|
||||
}
|
||||
|
||||
void rcFilterWalkableLowHeightSpans(int walkableHeight,
|
||||
rcHeightfield& solid)
|
||||
/// @par
|
||||
///
|
||||
/// For this filter, the clearance above the span is the distance from the span's
|
||||
/// maximum to the next higher span's minimum. (Same grid column.)
|
||||
///
|
||||
/// @see rcHeightfield, rcConfig
|
||||
void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid)
|
||||
{
|
||||
rcTimeVal startTime = rcGetPerformanceTimer();
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
@ -114,136 +195,13 @@ void rcFilterWalkableLowHeightSpans(int walkableHeight,
|
||||
{
|
||||
for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
|
||||
{
|
||||
const int bot = (int)s->smax;
|
||||
const int top = s->next ? (int)s->next->smin : MAX_HEIGHT;
|
||||
const int bot = (int)(s->smax);
|
||||
const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
|
||||
if ((top - bot) <= walkableHeight)
|
||||
s->flags &= ~RC_WALKABLE;
|
||||
s->area = RC_NULL_AREA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
|
||||
// if (rcGetLog())
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, "Filter walkable: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
|
||||
if (rcGetBuildTimes())
|
||||
rcGetBuildTimes()->filterWalkable += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
}
|
||||
|
||||
|
||||
struct rcReachableSeed
|
||||
{
|
||||
inline void set(int ix, int iy, rcSpan* is)
|
||||
{
|
||||
x = (unsigned short)ix;
|
||||
y = (unsigned short)iy;
|
||||
s = is;
|
||||
}
|
||||
unsigned short x, y;
|
||||
rcSpan* s;
|
||||
};
|
||||
|
||||
bool rcMarkReachableSpans(const int walkableHeight,
|
||||
const int walkableClimb,
|
||||
rcHeightfield& solid)
|
||||
{
|
||||
const int w = solid.width;
|
||||
const int h = solid.height;
|
||||
const int MAX_HEIGHT = 0xffff;
|
||||
|
||||
rcTimeVal startTime = rcGetPerformanceTimer();
|
||||
|
||||
// Build navigable space.
|
||||
const int MAX_SEEDS = w*h;
|
||||
rcReachableSeed* stack = new rcReachableSeed[MAX_SEEDS];
|
||||
if (!stack)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "rcMarkReachableSpans: Out of memory 'stack' (%d).", MAX_SEEDS);
|
||||
return false;
|
||||
}
|
||||
int stackSize = 0;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
rcSpan* topSpan = solid.spans[x + y*w];
|
||||
if (!topSpan)
|
||||
continue;
|
||||
while (topSpan->next)
|
||||
topSpan = topSpan->next;
|
||||
|
||||
// If the span is not walkable, skip it.
|
||||
if ((topSpan->flags & RC_WALKABLE) == 0)
|
||||
continue;
|
||||
// If the span has been visited already, skip it.
|
||||
if (topSpan->flags & RC_REACHABLE)
|
||||
continue;
|
||||
|
||||
// Start flood fill.
|
||||
topSpan->flags |= RC_REACHABLE;
|
||||
stackSize = 0;
|
||||
stack[stackSize].set(x, y, topSpan);
|
||||
stackSize++;
|
||||
|
||||
while (stackSize)
|
||||
{
|
||||
// Pop a seed from the stack.
|
||||
stackSize--;
|
||||
rcReachableSeed cur = stack[stackSize];
|
||||
|
||||
const int bot = (int)cur.s->smax;
|
||||
const int top = cur.s->next ? (int)cur.s->next->smin : MAX_HEIGHT;
|
||||
|
||||
// Visit neighbours in all 4 directions.
|
||||
for (int dir = 0; dir < 4; ++dir)
|
||||
{
|
||||
int dx = (int)cur.x + rcGetDirOffsetX(dir);
|
||||
int dy = (int)cur.y + rcGetDirOffsetY(dir);
|
||||
// Skip neighbour which are out of bounds.
|
||||
if (dx < 0 || dy < 0 || dx >= w || dy >= h)
|
||||
continue;
|
||||
for (rcSpan* ns = solid.spans[dx + dy*w]; ns; ns = ns->next)
|
||||
{
|
||||
// Skip neighbour if it is not walkable.
|
||||
if ((ns->flags & RC_WALKABLE) == 0)
|
||||
continue;
|
||||
// Skip the neighbour if it has been visited already.
|
||||
if (ns->flags & RC_REACHABLE)
|
||||
continue;
|
||||
|
||||
const int nbot = (int)ns->smax;
|
||||
const int ntop = ns->next ? (int)ns->next->smin : MAX_HEIGHT;
|
||||
// Skip neightbour if the gap between the spans is too small.
|
||||
if (rcMin(top,ntop) - rcMax(bot,nbot) < walkableHeight)
|
||||
continue;
|
||||
// Skip neightbour if the climb height to the neighbour is too high.
|
||||
if (rcAbs(nbot - bot) >= walkableClimb)
|
||||
continue;
|
||||
|
||||
// This neighbour has not been visited yet.
|
||||
// Mark it as reachable and add it to the seed stack.
|
||||
ns->flags |= RC_REACHABLE;
|
||||
if (stackSize < MAX_SEEDS)
|
||||
{
|
||||
stack[stackSize].set(dx, dy, ns);
|
||||
stackSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete [] stack;
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
|
||||
// if (rcGetLog())
|
||||
// rcGetLog()->log(RC_LOG_PROGRESS, "Mark reachable: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
|
||||
if (rcGetBuildTimes())
|
||||
rcGetBuildTimes()->filterMarkReachable += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
|
||||
return true;
|
||||
ctx->stopTimer(RC_TIMER_FILTER_WALKABLE);
|
||||
}
|
||||
|
620
extern/recastnavigation/Recast/Source/RecastLayers.cpp
vendored
Normal file
620
extern/recastnavigation/Recast/Source/RecastLayers.cpp
vendored
Normal file
@ -0,0 +1,620 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
|
||||
static const int RC_MAX_LAYERS = RC_NOT_CONNECTED;
|
||||
static const int RC_MAX_NEIS = 16;
|
||||
|
||||
struct rcLayerRegion
|
||||
{
|
||||
unsigned char layers[RC_MAX_LAYERS];
|
||||
unsigned char neis[RC_MAX_NEIS];
|
||||
unsigned short ymin, ymax;
|
||||
unsigned char layerId; // Layer ID
|
||||
unsigned char nlayers; // Layer count
|
||||
unsigned char nneis; // Neighbour count
|
||||
unsigned char base; // Flag indicating if the region is hte base of merged regions.
|
||||
};
|
||||
|
||||
|
||||
static void addUnique(unsigned char* a, unsigned char& an, unsigned char v)
|
||||
{
|
||||
const int n = (int)an;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (a[i] == v)
|
||||
return;
|
||||
a[an] = v;
|
||||
an++;
|
||||
}
|
||||
|
||||
static bool contains(const unsigned char* a, const unsigned char an, const unsigned char v)
|
||||
{
|
||||
const int n = (int)an;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (a[i] == v)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool overlapRange(const unsigned short amin, const unsigned short amax,
|
||||
const unsigned short bmin, const unsigned short bmax)
|
||||
{
|
||||
return (amin > bmax || amax < bmin) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct rcLayerSweepSpan
|
||||
{
|
||||
unsigned short ns; // number samples
|
||||
unsigned char id; // region id
|
||||
unsigned char nei; // neighbour id
|
||||
};
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// See the #rcConfig documentation for more information on the configuration parameters.
|
||||
///
|
||||
/// @see rcAllocHeightfieldLayerSet, rcCompactHeightfield, rcHeightfieldLayerSet, rcConfig
|
||||
bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
||||
const int borderSize, const int walkableHeight,
|
||||
rcHeightfieldLayerSet& lset)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_BUILD_LAYERS);
|
||||
|
||||
const int w = chf.width;
|
||||
const int h = chf.height;
|
||||
|
||||
rcScopedDelete<unsigned char> srcReg = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
|
||||
if (!srcReg)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'srcReg' (%d).", chf.spanCount);
|
||||
return false;
|
||||
}
|
||||
memset(srcReg,0xff,sizeof(unsigned char)*chf.spanCount);
|
||||
|
||||
const int nsweeps = chf.width;
|
||||
rcScopedDelete<rcLayerSweepSpan> sweeps = (rcLayerSweepSpan*)rcAlloc(sizeof(rcLayerSweepSpan)*nsweeps, RC_ALLOC_TEMP);
|
||||
if (!sweeps)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'sweeps' (%d).", nsweeps);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Partition walkable area into monotone regions.
|
||||
int prevCount[256];
|
||||
unsigned char regId = 0;
|
||||
|
||||
for (int y = borderSize; y < h-borderSize; ++y)
|
||||
{
|
||||
memset(prevCount,0,sizeof(int)*regId);
|
||||
unsigned char sweepId = 0;
|
||||
|
||||
for (int x = borderSize; x < w-borderSize; ++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) continue;
|
||||
|
||||
unsigned char sid = 0xff;
|
||||
|
||||
// -x
|
||||
if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
|
||||
{
|
||||
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);
|
||||
if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xff)
|
||||
sid = srcReg[ai];
|
||||
}
|
||||
|
||||
if (sid == 0xff)
|
||||
{
|
||||
sid = sweepId++;
|
||||
sweeps[sid].nei = 0xff;
|
||||
sweeps[sid].ns = 0;
|
||||
}
|
||||
|
||||
// -y
|
||||
if (rcGetCon(s,3) != RC_NOT_CONNECTED)
|
||||
{
|
||||
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 unsigned char nr = srcReg[ai];
|
||||
if (nr != 0xff)
|
||||
{
|
||||
// Set neighbour when first valid neighbour is encoutered.
|
||||
if (sweeps[sid].ns == 0)
|
||||
sweeps[sid].nei = nr;
|
||||
|
||||
if (sweeps[sid].nei == nr)
|
||||
{
|
||||
// Update existing neighbour
|
||||
sweeps[sid].ns++;
|
||||
prevCount[nr]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is hit if there is nore than one neighbour.
|
||||
// Invalidate the neighbour.
|
||||
sweeps[sid].nei = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srcReg[i] = sid;
|
||||
}
|
||||
}
|
||||
|
||||
// Create unique ID.
|
||||
for (int i = 0; i < sweepId; ++i)
|
||||
{
|
||||
// If the neighbour is set and there is only one continuous connection to it,
|
||||
// the sweep will be merged with the previous one, else new region is created.
|
||||
if (sweeps[i].nei != 0xff && prevCount[sweeps[i].nei] == (int)sweeps[i].ns)
|
||||
{
|
||||
sweeps[i].id = sweeps[i].nei;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (regId == 255)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Region ID overflow.");
|
||||
return false;
|
||||
}
|
||||
sweeps[i].id = regId++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remap local sweep ids to region ids.
|
||||
for (int x = borderSize; x < w-borderSize; ++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 (srcReg[i] != 0xff)
|
||||
srcReg[i] = sweeps[srcReg[i]].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate and init layer regions.
|
||||
const int nregs = (int)regId;
|
||||
rcScopedDelete<rcLayerRegion> regs = (rcLayerRegion*)rcAlloc(sizeof(rcLayerRegion)*nregs, RC_ALLOC_TEMP);
|
||||
if (!regs)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'regs' (%d).", nregs);
|
||||
return false;
|
||||
}
|
||||
memset(regs, 0, sizeof(rcLayerRegion)*nregs);
|
||||
for (int i = 0; i < nregs; ++i)
|
||||
{
|
||||
regs[i].layerId = 0xff;
|
||||
regs[i].ymin = 0xffff;
|
||||
regs[i].ymax = 0;
|
||||
}
|
||||
|
||||
// Find region neighbours and overlapping regions.
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
const rcCompactCell& c = chf.cells[x+y*w];
|
||||
|
||||
unsigned char lregs[RC_MAX_LAYERS];
|
||||
int nlregs = 0;
|
||||
|
||||
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
|
||||
{
|
||||
const rcCompactSpan& s = chf.spans[i];
|
||||
const unsigned char ri = srcReg[i];
|
||||
if (ri == 0xff) continue;
|
||||
|
||||
regs[ri].ymin = rcMin(regs[ri].ymin, s.y);
|
||||
regs[ri].ymax = rcMax(regs[ri].ymax, s.y);
|
||||
|
||||
// Collect all region layers.
|
||||
if (nlregs < RC_MAX_LAYERS)
|
||||
lregs[nlregs++] = ri;
|
||||
|
||||
// Update neighbours
|
||||
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);
|
||||
const unsigned char rai = srcReg[ai];
|
||||
if (rai != 0xff && rai != ri)
|
||||
addUnique(regs[ri].neis, regs[ri].nneis, rai);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Update overlapping regions.
|
||||
for (int i = 0; i < nlregs-1; ++i)
|
||||
{
|
||||
for (int j = i+1; j < nlregs; ++j)
|
||||
{
|
||||
if (lregs[i] != lregs[j])
|
||||
{
|
||||
rcLayerRegion& ri = regs[lregs[i]];
|
||||
rcLayerRegion& rj = regs[lregs[j]];
|
||||
addUnique(ri.layers, ri.nlayers, lregs[j]);
|
||||
addUnique(rj.layers, rj.nlayers, lregs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Create 2D layers from regions.
|
||||
unsigned char layerId = 0;
|
||||
|
||||
static const int MAX_STACK = 64;
|
||||
unsigned char stack[MAX_STACK];
|
||||
int nstack = 0;
|
||||
|
||||
for (int i = 0; i < nregs; ++i)
|
||||
{
|
||||
rcLayerRegion& root = regs[i];
|
||||
// Skip alreadu visited.
|
||||
if (root.layerId != 0xff)
|
||||
continue;
|
||||
|
||||
// Start search.
|
||||
root.layerId = layerId;
|
||||
root.base = 1;
|
||||
|
||||
nstack = 0;
|
||||
stack[nstack++] = (unsigned char)i;
|
||||
|
||||
while (nstack)
|
||||
{
|
||||
// Pop front
|
||||
rcLayerRegion& reg = regs[stack[0]];
|
||||
nstack--;
|
||||
for (int j = 0; j < nstack; ++j)
|
||||
stack[j] = stack[j+1];
|
||||
|
||||
const int nneis = (int)reg.nneis;
|
||||
for (int j = 0; j < nneis; ++j)
|
||||
{
|
||||
const unsigned char nei = reg.neis[j];
|
||||
rcLayerRegion& regn = regs[nei];
|
||||
// Skip already visited.
|
||||
if (regn.layerId != 0xff)
|
||||
continue;
|
||||
// Skip if the neighbour is overlapping root region.
|
||||
if (contains(root.layers, root.nlayers, nei))
|
||||
continue;
|
||||
// Skip if the height range would become too large.
|
||||
const int ymin = rcMin(root.ymin, regn.ymin);
|
||||
const int ymax = rcMin(root.ymax, regn.ymax);
|
||||
if ((ymax - ymin) >= 255)
|
||||
continue;
|
||||
|
||||
if (nstack < MAX_STACK)
|
||||
{
|
||||
// Deepen
|
||||
stack[nstack++] = (unsigned char)nei;
|
||||
|
||||
// Mark layer id
|
||||
regn.layerId = layerId;
|
||||
// Merge current layers to root.
|
||||
for (int k = 0; k < regn.nlayers; ++k)
|
||||
addUnique(root.layers, root.nlayers, regn.layers[k]);
|
||||
root.ymin = rcMin(root.ymin, regn.ymin);
|
||||
root.ymax = rcMax(root.ymax, regn.ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layerId++;
|
||||
}
|
||||
|
||||
// Merge non-overlapping regions that are close in height.
|
||||
const unsigned short mergeHeight = (unsigned short)walkableHeight * 4;
|
||||
|
||||
for (int i = 0; i < nregs; ++i)
|
||||
{
|
||||
rcLayerRegion& ri = regs[i];
|
||||
if (!ri.base) continue;
|
||||
|
||||
unsigned char newId = ri.layerId;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned char oldId = 0xff;
|
||||
|
||||
for (int j = 0; j < nregs; ++j)
|
||||
{
|
||||
if (i == j) continue;
|
||||
rcLayerRegion& rj = regs[j];
|
||||
if (!rj.base) continue;
|
||||
|
||||
// Skip if teh regions are not close to each other.
|
||||
if (!overlapRange(ri.ymin,ri.ymax+mergeHeight, rj.ymin,rj.ymax+mergeHeight))
|
||||
continue;
|
||||
// Skip if the height range would become too large.
|
||||
const int ymin = rcMin(ri.ymin, rj.ymin);
|
||||
const int ymax = rcMin(ri.ymax, rj.ymax);
|
||||
if ((ymax - ymin) >= 255)
|
||||
continue;
|
||||
|
||||
// Make sure that there is no overlap when mergin 'ri' and 'rj'.
|
||||
bool overlap = false;
|
||||
// Iterate over all regions which have the same layerId as 'rj'
|
||||
for (int k = 0; k < nregs; ++k)
|
||||
{
|
||||
if (regs[k].layerId != rj.layerId)
|
||||
continue;
|
||||
// Check if region 'k' is overlapping region 'ri'
|
||||
// Index to 'regs' is the same as region id.
|
||||
if (contains(ri.layers,ri.nlayers, (unsigned char)k))
|
||||
{
|
||||
overlap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Cannot merge of regions overlap.
|
||||
if (overlap)
|
||||
continue;
|
||||
|
||||
// Can merge i and j.
|
||||
oldId = rj.layerId;
|
||||
break;
|
||||
}
|
||||
|
||||
// Could not find anything to merge with, stop.
|
||||
if (oldId == 0xff)
|
||||
break;
|
||||
|
||||
// Merge
|
||||
for (int j = 0; j < nregs; ++j)
|
||||
{
|
||||
rcLayerRegion& rj = regs[j];
|
||||
if (rj.layerId == oldId)
|
||||
{
|
||||
rj.base = 0;
|
||||
// Remap layerIds.
|
||||
rj.layerId = newId;
|
||||
// Add overlaid layers from 'rj' to 'ri'.
|
||||
for (int k = 0; k < rj.nlayers; ++k)
|
||||
addUnique(ri.layers, ri.nlayers, rj.layers[k]);
|
||||
// Update heigh bounds.
|
||||
ri.ymin = rcMin(ri.ymin, rj.ymin);
|
||||
ri.ymax = rcMax(ri.ymax, rj.ymax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compact layerIds
|
||||
unsigned char remap[256];
|
||||
memset(remap, 0, 256);
|
||||
|
||||
// Find number of unique layers.
|
||||
layerId = 0;
|
||||
for (int i = 0; i < nregs; ++i)
|
||||
remap[regs[i].layerId] = 1;
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
if (remap[i])
|
||||
remap[i] = layerId++;
|
||||
else
|
||||
remap[i] = 0xff;
|
||||
}
|
||||
// Remap ids.
|
||||
for (int i = 0; i < nregs; ++i)
|
||||
regs[i].layerId = remap[regs[i].layerId];
|
||||
|
||||
// No layers, return empty.
|
||||
if (layerId == 0)
|
||||
{
|
||||
ctx->stopTimer(RC_TIMER_BUILD_LAYERS);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create layers.
|
||||
rcAssert(lset.layers == 0);
|
||||
|
||||
const int lw = w - borderSize*2;
|
||||
const int lh = h - borderSize*2;
|
||||
|
||||
// Build contracted bbox for layers.
|
||||
float bmin[3], bmax[3];
|
||||
rcVcopy(bmin, chf.bmin);
|
||||
rcVcopy(bmax, chf.bmax);
|
||||
bmin[0] += borderSize*chf.cs;
|
||||
bmin[2] += borderSize*chf.cs;
|
||||
bmax[0] -= borderSize*chf.cs;
|
||||
bmax[2] -= borderSize*chf.cs;
|
||||
|
||||
lset.nlayers = (int)layerId;
|
||||
|
||||
lset.layers = (rcHeightfieldLayer*)rcAlloc(sizeof(rcHeightfieldLayer)*lset.nlayers, RC_ALLOC_PERM);
|
||||
if (!lset.layers)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'layers' (%d).", lset.nlayers);
|
||||
return false;
|
||||
}
|
||||
memset(lset.layers, 0, sizeof(rcHeightfieldLayer)*lset.nlayers);
|
||||
|
||||
|
||||
// Store layers.
|
||||
for (int i = 0; i < lset.nlayers; ++i)
|
||||
{
|
||||
unsigned char curId = (unsigned char)i;
|
||||
|
||||
// Allocate memory for the current layer.
|
||||
rcHeightfieldLayer* layer = &lset.layers[i];
|
||||
memset(layer, 0, sizeof(rcHeightfieldLayer));
|
||||
|
||||
const int gridSize = sizeof(unsigned char)*lw*lh;
|
||||
|
||||
layer->heights = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
|
||||
if (!layer->heights)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'heights' (%d).", gridSize);
|
||||
return false;
|
||||
}
|
||||
memset(layer->heights, 0xff, gridSize);
|
||||
|
||||
layer->areas = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
|
||||
if (!layer->areas)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'areas' (%d).", gridSize);
|
||||
return false;
|
||||
}
|
||||
memset(layer->areas, 0, gridSize);
|
||||
|
||||
layer->cons = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
|
||||
if (!layer->cons)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'cons' (%d).", gridSize);
|
||||
return false;
|
||||
}
|
||||
memset(layer->cons, 0, gridSize);
|
||||
|
||||
// Find layer height bounds.
|
||||
int hmin = 0, hmax = 0;
|
||||
for (int j = 0; j < nregs; ++j)
|
||||
{
|
||||
if (regs[j].base && regs[j].layerId == curId)
|
||||
{
|
||||
hmin = (int)regs[j].ymin;
|
||||
hmax = (int)regs[j].ymax;
|
||||
}
|
||||
}
|
||||
|
||||
layer->width = lw;
|
||||
layer->height = lh;
|
||||
layer->cs = chf.cs;
|
||||
layer->ch = chf.ch;
|
||||
|
||||
// Adjust the bbox to fit the heighfield.
|
||||
rcVcopy(layer->bmin, bmin);
|
||||
rcVcopy(layer->bmax, bmax);
|
||||
layer->bmin[1] = bmin[1] + hmin*chf.ch;
|
||||
layer->bmax[1] = bmin[1] + hmax*chf.ch;
|
||||
layer->hmin = hmin;
|
||||
layer->hmax = hmax;
|
||||
|
||||
// Update usable data region.
|
||||
layer->minx = layer->width;
|
||||
layer->maxx = 0;
|
||||
layer->miny = layer->height;
|
||||
layer->maxy = 0;
|
||||
|
||||
// Copy height and area from compact heighfield.
|
||||
for (int y = 0; y < lh; ++y)
|
||||
{
|
||||
for (int x = 0; x < lw; ++x)
|
||||
{
|
||||
const int cx = borderSize+x;
|
||||
const int cy = borderSize+y;
|
||||
const rcCompactCell& c = chf.cells[cx+cy*w];
|
||||
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
|
||||
{
|
||||
const rcCompactSpan& s = chf.spans[i];
|
||||
// Skip unassigned regions.
|
||||
if (srcReg[i] == 0xff)
|
||||
continue;
|
||||
// Skip of does nto belong to current layer.
|
||||
unsigned char lid = regs[srcReg[i]].layerId;
|
||||
if (lid != curId)
|
||||
continue;
|
||||
|
||||
// Update data bounds.
|
||||
layer->minx = rcMin(layer->minx, x);
|
||||
layer->maxx = rcMax(layer->maxx, x);
|
||||
layer->miny = rcMin(layer->miny, y);
|
||||
layer->maxy = rcMax(layer->maxy, y);
|
||||
|
||||
// Store height and area type.
|
||||
const int idx = x+y*lw;
|
||||
layer->heights[idx] = (unsigned char)(s.y - hmin);
|
||||
layer->areas[idx] = chf.areas[i];
|
||||
|
||||
// Check connection.
|
||||
unsigned char portal = 0;
|
||||
unsigned char con = 0;
|
||||
for (int dir = 0; dir < 4; ++dir)
|
||||
{
|
||||
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
|
||||
{
|
||||
const int ax = cx + rcGetDirOffsetX(dir);
|
||||
const int ay = cy + rcGetDirOffsetY(dir);
|
||||
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
|
||||
unsigned char alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff;
|
||||
// Portal mask
|
||||
if (chf.areas[ai] != RC_NULL_AREA && lid != alid)
|
||||
{
|
||||
portal |= (unsigned char)(1<<dir);
|
||||
// Update height so that it matches on both sides of the portal.
|
||||
const rcCompactSpan& as = chf.spans[ai];
|
||||
if (as.y > hmin)
|
||||
layer->heights[idx] = rcMax(layer->heights[idx], (unsigned char)(as.y - hmin));
|
||||
}
|
||||
// Valid connection mask
|
||||
if (chf.areas[ai] != RC_NULL_AREA && lid == alid)
|
||||
{
|
||||
const int nx = ax - borderSize;
|
||||
const int ny = ay - borderSize;
|
||||
if (nx >= 0 && ny >= 0 && nx < lw && ny < lh)
|
||||
con |= (unsigned char)(1<<dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer->cons[idx] = (portal << 4) | con;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layer->minx > layer->maxx)
|
||||
layer->minx = layer->maxx = 0;
|
||||
if (layer->miny > layer->maxy)
|
||||
layer->miny = layer->maxy = 0;
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_BUILD_LAYERS);
|
||||
|
||||
return true;
|
||||
}
|
713
extern/recastnavigation/Recast/Source/RecastMesh.cpp
vendored
713
extern/recastnavigation/Recast/Source/RecastMesh.cpp
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -20,8 +20,8 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "Recast.h"
|
||||
#include "RecastTimer.h"
|
||||
#include "RecastLog.h"
|
||||
#include "RecastAlloc.h"
|
||||
#include "RecastAssert.h"
|
||||
|
||||
inline bool overlapBounds(const float* amin, const float* amax, const float* bmin, const float* bmax)
|
||||
{
|
||||
@ -48,8 +48,7 @@ static rcSpan* allocSpan(rcHeightfield& hf)
|
||||
{
|
||||
// Create new page.
|
||||
// Allocate memory for the new pool.
|
||||
const int size = (sizeof(rcSpanPool)-sizeof(rcSpan)) + sizeof(rcSpan)*RC_SPANS_PER_POOL;
|
||||
rcSpanPool* pool = reinterpret_cast<rcSpanPool*>(new unsigned char[size]);
|
||||
rcSpanPool* pool = (rcSpanPool*)rcAlloc(sizeof(rcSpanPool), RC_ALLOC_PERM);
|
||||
if (!pool) return 0;
|
||||
pool->next = 0;
|
||||
// Add the pool into the list of pools.
|
||||
@ -83,16 +82,17 @@ static void freeSpan(rcHeightfield& hf, rcSpan* ptr)
|
||||
hf.freelist = ptr;
|
||||
}
|
||||
|
||||
static void addSpan(rcHeightfield& hf, int x, int y,
|
||||
unsigned short smin, unsigned short smax,
|
||||
unsigned short flags)
|
||||
static void addSpan(rcHeightfield& hf, const int x, const int y,
|
||||
const unsigned short smin, const unsigned short smax,
|
||||
const unsigned char area, const int flagMergeThr)
|
||||
{
|
||||
|
||||
int idx = x + y*hf.width;
|
||||
|
||||
rcSpan* s = allocSpan(hf);
|
||||
s->smin = smin;
|
||||
s->smax = smax;
|
||||
s->flags = flags;
|
||||
s->area = area;
|
||||
s->next = 0;
|
||||
|
||||
// Empty cell, add he first span.
|
||||
@ -127,9 +127,8 @@ static void addSpan(rcHeightfield& hf, int x, int y,
|
||||
s->smax = cur->smax;
|
||||
|
||||
// Merge flags.
|
||||
// if (s->smax == cur->smax)
|
||||
if (rcAbs((int)s->smax - (int)cur->smax) <= 1)
|
||||
s->flags |= cur->flags;
|
||||
if (rcAbs((int)s->smax - (int)cur->smax) <= flagMergeThr)
|
||||
s->area = rcMax(s->area, cur->area);
|
||||
|
||||
// Remove current span.
|
||||
rcSpan* next = cur->next;
|
||||
@ -155,6 +154,21 @@ static void addSpan(rcHeightfield& hf, int x, int y,
|
||||
}
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// The span addition can be set to favor flags. If the span is merged to
|
||||
/// another span and the new @p smax is within @p flagMergeThr units
|
||||
/// from the existing span, the span flags are merged.
|
||||
///
|
||||
/// @see rcHeightfield, rcSpan.
|
||||
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)
|
||||
{
|
||||
// rcAssert(ctx);
|
||||
addSpan(hf, x,y, smin, smax, area, flagMergeThr);
|
||||
}
|
||||
|
||||
static int clipPoly(const float* in, int n, float* out, float pnx, float pnz, float pd)
|
||||
{
|
||||
float d[12];
|
||||
@ -186,9 +200,10 @@ static int clipPoly(const float* in, int n, float* out, float pnx, float pnz, fl
|
||||
}
|
||||
|
||||
static void rasterizeTri(const float* v0, const float* v1, const float* v2,
|
||||
unsigned char flags, rcHeightfield& hf,
|
||||
const unsigned char area, rcHeightfield& hf,
|
||||
const float* bmin, const float* bmax,
|
||||
const float cs, const float ics, const float ich)
|
||||
const float cs, const float ics, const float ich,
|
||||
const int flagMergeThr)
|
||||
{
|
||||
const int w = hf.width;
|
||||
const int h = hf.height;
|
||||
@ -196,12 +211,12 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2,
|
||||
const float by = bmax[1] - bmin[1];
|
||||
|
||||
// Calculate the bounding box of the triangle.
|
||||
vcopy(tmin, v0);
|
||||
vcopy(tmax, v0);
|
||||
vmin(tmin, v1);
|
||||
vmin(tmin, v2);
|
||||
vmax(tmax, v1);
|
||||
vmax(tmax, v2);
|
||||
rcVcopy(tmin, v0);
|
||||
rcVcopy(tmax, v0);
|
||||
rcVmin(tmin, v1);
|
||||
rcVmin(tmin, v2);
|
||||
rcVmax(tmax, v1);
|
||||
rcVmax(tmax, v2);
|
||||
|
||||
// If the triangle does not touch the bbox of the heightfield, skip the triagle.
|
||||
if (!overlapBounds(bmin, bmax, tmin, tmax))
|
||||
@ -223,9 +238,9 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2,
|
||||
for (int y = y0; y <= y1; ++y)
|
||||
{
|
||||
// Clip polygon to row.
|
||||
vcopy(&in[0], v0);
|
||||
vcopy(&in[1*3], v1);
|
||||
vcopy(&in[2*3], v2);
|
||||
rcVcopy(&in[0], v0);
|
||||
rcVcopy(&in[1*3], v1);
|
||||
rcVcopy(&in[2*3], v2);
|
||||
int nvrow = 3;
|
||||
const float cz = bmin[2] + y*cs;
|
||||
nvrow = clipPoly(in, nvrow, out, 0, 1, -cz);
|
||||
@ -256,38 +271,50 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2,
|
||||
if (smax < 0.0f) continue;
|
||||
if (smin > by) continue;
|
||||
// Clamp the span to the heightfield bbox.
|
||||
if (smin < 0.0f) smin = bmin[1];
|
||||
if (smax > by) smax = bmax[1];
|
||||
if (smin < 0.0f) smin = 0;
|
||||
if (smax > by) smax = by;
|
||||
|
||||
// Snap the span to the heightfield height grid.
|
||||
unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, 0x7fff);
|
||||
unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), 0, 0x7fff);
|
||||
unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, RC_SPAN_MAX_HEIGHT);
|
||||
unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, RC_SPAN_MAX_HEIGHT);
|
||||
|
||||
addSpan(hf, x, y, ismin, ismax, flags);
|
||||
addSpan(hf, x, y, ismin, ismax, area, flagMergeThr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
|
||||
unsigned char flags, rcHeightfield& solid)
|
||||
/// @par
|
||||
///
|
||||
/// No spans will be added if the triangle does not overlap the heightfield grid.
|
||||
///
|
||||
/// @see rcHeightfield
|
||||
void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2,
|
||||
const unsigned char area, rcHeightfield& solid,
|
||||
const int flagMergeThr)
|
||||
{
|
||||
rcTimeVal startTime = rcGetPerformanceTimer();
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
rasterizeTri(v0, v1, v2, flags, solid, solid.bmin, solid.bmax, solid.cs, ics, ich);
|
||||
rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
|
||||
if (rcGetBuildTimes())
|
||||
rcGetBuildTimes()->rasterizeTriangles += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
void rcRasterizeTriangles(const float* verts, int nv,
|
||||
const int* tris, const unsigned char* flags, int nt,
|
||||
rcHeightfield& solid)
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// Spans will only be added for triangles that overlap the heightfield grid.
|
||||
///
|
||||
/// @see rcHeightfield
|
||||
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)
|
||||
{
|
||||
rcTimeVal startTime = rcGetPerformanceTimer();
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
@ -298,11 +325,63 @@ void rcRasterizeTriangles(const float* verts, int nv,
|
||||
const float* v1 = &verts[tris[i*3+1]*3];
|
||||
const float* v2 = &verts[tris[i*3+2]*3];
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, flags[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich);
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
rcTimeVal endTime = rcGetPerformanceTimer();
|
||||
|
||||
if (rcGetBuildTimes())
|
||||
rcGetBuildTimes()->rasterizeTriangles += rcGetDeltaTimeUsec(startTime, endTime);
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// Spans will only be added for triangles that overlap the heightfield grid.
|
||||
///
|
||||
/// @see rcHeightfield
|
||||
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)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
// Rasterize triangles.
|
||||
for (int i = 0; i < nt; ++i)
|
||||
{
|
||||
const float* v0 = &verts[tris[i*3+0]*3];
|
||||
const float* v1 = &verts[tris[i*3+1]*3];
|
||||
const float* v2 = &verts[tris[i*3+2]*3];
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// Spans will only be added for triangles that overlap the heightfield grid.
|
||||
///
|
||||
/// @see rcHeightfield
|
||||
void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt,
|
||||
rcHeightfield& solid, const int flagMergeThr)
|
||||
{
|
||||
rcAssert(ctx);
|
||||
|
||||
ctx->startTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
|
||||
const float ics = 1.0f/solid.cs;
|
||||
const float ich = 1.0f/solid.ch;
|
||||
// Rasterize triangles.
|
||||
for (int i = 0; i < nt; ++i)
|
||||
{
|
||||
const float* v0 = &verts[(i*3+0)*3];
|
||||
const float* v1 = &verts[(i*3+1)*3];
|
||||
const float* v2 = &verts[(i*3+2)*3];
|
||||
// Rasterize.
|
||||
rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
|
||||
}
|
||||
|
||||
ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
362
extern/recastnavigation/recast-capi.cpp
vendored
362
extern/recastnavigation/recast-capi.cpp
vendored
@ -30,8 +30,370 @@
|
||||
#include <math.h>
|
||||
#include "Recast.h"
|
||||
|
||||
static rcContext *sctx;
|
||||
|
||||
#define INIT_SCTX() \
|
||||
if (sctx == NULL) sctx = new rcContext(false)
|
||||
|
||||
int recast_buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
const int nverts, const int vertsPerPoly)
|
||||
{
|
||||
return (int) buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly);
|
||||
}
|
||||
|
||||
void recast_calcBounds(const float *verts, int nv, float *bmin, float *bmax)
|
||||
{
|
||||
rcCalcBounds(verts, nv, bmin, bmax);
|
||||
}
|
||||
|
||||
void recast_calcGridSize(const float *bmin, const float *bmax, float cs, int *w, int *h)
|
||||
{
|
||||
rcCalcGridSize(bmin, bmax, cs, w, h);
|
||||
}
|
||||
|
||||
struct recast_heightfield *recast_newHeightfield(void)
|
||||
{
|
||||
return (struct recast_heightfield *) rcAllocHeightfield();
|
||||
}
|
||||
|
||||
void recast_destroyHeightfield(struct recast_heightfield *heightfield)
|
||||
{
|
||||
rcFreeHeightField((rcHeightfield *) heightfield);
|
||||
}
|
||||
|
||||
int recast_createHeightfield(struct recast_heightfield *hf, int width, int height,
|
||||
const float *bmin, const float* bmax, float cs, float ch)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcCreateHeightfield(sctx, *(rcHeightfield *)hf, width, height, bmin, bmax, cs, ch);
|
||||
}
|
||||
|
||||
void recast_markWalkableTriangles(const float walkableSlopeAngle,const float *verts, int nv,
|
||||
const int *tris, int nt, unsigned char *flags)
|
||||
{
|
||||
INIT_SCTX();
|
||||
rcMarkWalkableTriangles(sctx, walkableSlopeAngle, verts, nv, tris, nt, flags);
|
||||
}
|
||||
|
||||
void recast_rasterizeTriangles(const float *verts, int nv, const int *tris,
|
||||
const unsigned char *flags, int nt, struct recast_heightfield *solid)
|
||||
{
|
||||
INIT_SCTX();
|
||||
rcRasterizeTriangles(sctx, verts, nv, tris, flags, nt, *(rcHeightfield *) solid);
|
||||
}
|
||||
|
||||
void recast_filterLedgeSpans(const int walkableHeight, const int walkableClimb,
|
||||
struct recast_heightfield *solid)
|
||||
{
|
||||
INIT_SCTX();
|
||||
rcFilterLedgeSpans(sctx, walkableHeight, walkableClimb, *(rcHeightfield *) solid);
|
||||
}
|
||||
|
||||
void recast_filterWalkableLowHeightSpans(int walkableHeight, struct recast_heightfield *solid)
|
||||
{
|
||||
INIT_SCTX();
|
||||
rcFilterWalkableLowHeightSpans(sctx, walkableHeight, *(rcHeightfield *) solid);
|
||||
}
|
||||
|
||||
void recast_filterLowHangingWalkableObstacles(const int walkableClimb, struct recast_heightfield *solid)
|
||||
{
|
||||
INIT_SCTX();
|
||||
rcFilterLowHangingWalkableObstacles(sctx, walkableClimb, *(rcHeightfield *) solid);
|
||||
}
|
||||
|
||||
struct recast_compactHeightfield *recast_newCompactHeightfield(void)
|
||||
{
|
||||
return (struct recast_compactHeightfield *) rcAllocCompactHeightfield();
|
||||
}
|
||||
|
||||
void recast_destroyCompactHeightfield(struct recast_compactHeightfield *compactHeightfield)
|
||||
{
|
||||
rcFreeCompactHeightfield( (rcCompactHeightfield *) compactHeightfield);
|
||||
}
|
||||
|
||||
int recast_buildCompactHeightfield(const int walkableHeight, const int walkableClimb,
|
||||
struct recast_heightfield *hf, struct recast_compactHeightfield *chf)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildCompactHeightfield(sctx, walkableHeight, walkableClimb,
|
||||
*(rcHeightfield *) hf, *(rcCompactHeightfield *) chf);
|
||||
}
|
||||
|
||||
int recast_erodeWalkableArea(int radius, struct recast_compactHeightfield *chf)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcErodeWalkableArea(sctx, radius, *(rcCompactHeightfield *) chf);
|
||||
}
|
||||
|
||||
int recast_buildDistanceField(struct recast_compactHeightfield *chf)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildDistanceField(sctx, *(rcCompactHeightfield *) chf);
|
||||
}
|
||||
|
||||
int recast_buildRegions(struct recast_compactHeightfield *chf, int borderSize,
|
||||
int minRegionSize, int mergeRegionSize)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildRegions(sctx, *(rcCompactHeightfield *) chf, borderSize,
|
||||
minRegionSize, mergeRegionSize);
|
||||
}
|
||||
|
||||
struct recast_contourSet *recast_newContourSet(void)
|
||||
{
|
||||
return (struct recast_contourSet *) rcAllocContourSet();
|
||||
}
|
||||
|
||||
void recast_destroyContourSet(struct recast_contourSet *contourSet)
|
||||
{
|
||||
rcFreeContourSet((rcContourSet *) contourSet);
|
||||
}
|
||||
|
||||
int recast_buildContours(struct recast_compactHeightfield *chf,
|
||||
const float maxError, const int maxEdgeLen, struct recast_contourSet *cset)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildContours(sctx, *(rcCompactHeightfield *) chf, maxError, maxEdgeLen, *(rcContourSet *) cset);
|
||||
}
|
||||
|
||||
struct recast_polyMesh *recast_newPolyMesh(void)
|
||||
{
|
||||
return (recast_polyMesh *) rcAllocPolyMesh();
|
||||
}
|
||||
|
||||
void recast_destroyPolyMesh(struct recast_polyMesh *polyMesh)
|
||||
{
|
||||
rcFreePolyMesh((rcPolyMesh *) polyMesh);
|
||||
}
|
||||
|
||||
int recast_buildPolyMesh(struct recast_contourSet *cset, int nvp, struct recast_polyMesh *mesh)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildPolyMesh(sctx, *(rcContourSet *) cset, nvp, * (rcPolyMesh *) mesh);
|
||||
}
|
||||
|
||||
unsigned short *recast_polyMeshGetVerts(struct recast_polyMesh *mesh, int *nverts)
|
||||
{
|
||||
rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
|
||||
|
||||
if (nverts)
|
||||
*nverts = pmesh->nverts;
|
||||
|
||||
return pmesh->verts;
|
||||
}
|
||||
|
||||
void recast_polyMeshGetBoundbox(struct recast_polyMesh *mesh, float *bmin, float *bmax)
|
||||
{
|
||||
rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
|
||||
|
||||
if (bmin) {
|
||||
bmin[0] = pmesh->bmin[0];
|
||||
bmin[1] = pmesh->bmin[1];
|
||||
bmin[2] = pmesh->bmin[2];
|
||||
}
|
||||
|
||||
if (bmax) {
|
||||
bmax[0] = pmesh->bmax[0];
|
||||
bmax[1] = pmesh->bmax[1];
|
||||
bmax[2] = pmesh->bmax[2];
|
||||
}
|
||||
}
|
||||
|
||||
void recast_polyMeshGetCell(struct recast_polyMesh *mesh, float *cs, float *ch)
|
||||
{
|
||||
rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
|
||||
|
||||
if (cs)
|
||||
*cs = pmesh->cs;
|
||||
|
||||
if (ch)
|
||||
*ch = pmesh->ch;
|
||||
}
|
||||
|
||||
unsigned short *recast_polyMeshGetPolys(struct recast_polyMesh *mesh, int *npolys, int *nvp)
|
||||
{
|
||||
rcPolyMesh *pmesh = (rcPolyMesh *)mesh;
|
||||
|
||||
if (npolys)
|
||||
*npolys = pmesh->npolys;
|
||||
|
||||
if (nvp)
|
||||
*nvp = pmesh->nvp;
|
||||
|
||||
return pmesh->polys;
|
||||
}
|
||||
|
||||
struct recast_polyMeshDetail *recast_newPolyMeshDetail(void)
|
||||
{
|
||||
return (struct recast_polyMeshDetail *) rcAllocPolyMeshDetail();
|
||||
}
|
||||
|
||||
void recast_destroyPolyMeshDetail(struct recast_polyMeshDetail *polyMeshDetail)
|
||||
{
|
||||
rcFreePolyMeshDetail((rcPolyMeshDetail *) polyMeshDetail);
|
||||
}
|
||||
|
||||
int recast_buildPolyMeshDetail(const struct recast_polyMesh *mesh, const struct recast_compactHeightfield *chf,
|
||||
const float sampleDist, const float sampleMaxError, struct recast_polyMeshDetail *dmesh)
|
||||
{
|
||||
INIT_SCTX();
|
||||
return rcBuildPolyMeshDetail(sctx, *(rcPolyMesh *) mesh, *(rcCompactHeightfield *) chf,
|
||||
sampleDist, sampleMaxError, *(rcPolyMeshDetail *) dmesh);
|
||||
}
|
||||
|
||||
float *recast_polyMeshDetailGetVerts(struct recast_polyMeshDetail *mesh, int *nverts)
|
||||
{
|
||||
rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
|
||||
|
||||
if (nverts)
|
||||
*nverts = dmesh->nverts;
|
||||
|
||||
return dmesh->verts;
|
||||
}
|
||||
|
||||
unsigned char *recast_polyMeshDetailGetTris(struct recast_polyMeshDetail *mesh, int *ntris)
|
||||
{
|
||||
rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
|
||||
|
||||
if (ntris)
|
||||
*ntris = dmesh->ntris;
|
||||
|
||||
return dmesh->tris;
|
||||
}
|
||||
|
||||
unsigned int *recast_polyMeshDetailGetMeshes(struct recast_polyMeshDetail *mesh, int *nmeshes)
|
||||
{
|
||||
rcPolyMeshDetail *dmesh = (rcPolyMeshDetail *)mesh;
|
||||
|
||||
if (nmeshes)
|
||||
*nmeshes = dmesh->nmeshes;
|
||||
|
||||
return dmesh->meshes;
|
||||
}
|
||||
|
||||
// qsort based on FreeBSD source (libkern\qsort.c)
|
||||
typedef int cmp_t(void *, const void *, const void *);
|
||||
static inline char *med3(char *, char *, char *, cmp_t *, void *);
|
||||
static inline void swapfunc(char *, char *, int, int);
|
||||
|
||||
#define min(a, b) (a) < (b) ? a : b
|
||||
#define swapcode(TYPE, parmi, parmj, n) \
|
||||
{ \
|
||||
long i = (n) / sizeof (TYPE); \
|
||||
TYPE *pi = (TYPE *) (parmi); \
|
||||
TYPE *pj = (TYPE *) (parmj); \
|
||||
do { \
|
||||
TYPE t = *pi; \
|
||||
*pi++ = *pj; \
|
||||
*pj++ = t; \
|
||||
} while (--i > 0); \
|
||||
}
|
||||
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
|
||||
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
|
||||
|
||||
static inline void swapfunc(char* a, char* b, int n, int swaptype)
|
||||
{
|
||||
if(swaptype <= 1)
|
||||
swapcode(long, a, b, n)
|
||||
else
|
||||
swapcode(char, a, b, n)
|
||||
}
|
||||
|
||||
#define swap(a, b) \
|
||||
if (swaptype == 0) { \
|
||||
long t = *(long *)(a); \
|
||||
*(long *)(a) = *(long *)(b);\
|
||||
*(long *)(b) = t; \
|
||||
} else \
|
||||
swapfunc(a, b, es, swaptype)
|
||||
|
||||
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
|
||||
#define CMP(t, x, y) (cmp((t), (x), (y)))
|
||||
|
||||
static inline char * med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk)
|
||||
{
|
||||
return CMP(thunk, a, b) < 0 ?
|
||||
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
|
||||
:(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
|
||||
}
|
||||
|
||||
void recast_qsort(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
|
||||
{
|
||||
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
||||
int d, r, swaptype, swap_cnt;
|
||||
|
||||
loop:
|
||||
SWAPINIT(a, es);
|
||||
swap_cnt = 0;
|
||||
if (n < 7) {
|
||||
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
|
||||
for (pl = pm;
|
||||
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
|
||||
pl -= es)
|
||||
swap(pl, pl - es);
|
||||
return;
|
||||
}
|
||||
pm = (char *)a + (n / 2) * es;
|
||||
if (n > 7) {
|
||||
pl = (char *)a;
|
||||
pn = (char *)a + (n - 1) * es;
|
||||
if (n > 40) {
|
||||
d = (n / 8) * es;
|
||||
pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
|
||||
pm = med3(pm - d, pm, pm + d, cmp, thunk);
|
||||
pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
|
||||
}
|
||||
pm = med3(pl, pm, pn, cmp, thunk);
|
||||
}
|
||||
swap((char *)a, pm);
|
||||
pa = pb = (char *)a + es;
|
||||
|
||||
pc = pd = (char *)a + (n - 1) * es;
|
||||
for (;;) {
|
||||
while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) {
|
||||
if (r == 0) {
|
||||
swap_cnt = 1;
|
||||
swap(pa, pb);
|
||||
pa += es;
|
||||
}
|
||||
pb += es;
|
||||
}
|
||||
while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) {
|
||||
if (r == 0) {
|
||||
swap_cnt = 1;
|
||||
swap(pc, pd);
|
||||
pd -= es;
|
||||
}
|
||||
pc -= es;
|
||||
}
|
||||
if (pb > pc)
|
||||
break;
|
||||
swap(pb, pc);
|
||||
swap_cnt = 1;
|
||||
pb += es;
|
||||
pc -= es;
|
||||
}
|
||||
if (swap_cnt == 0) { /* Switch to insertion sort */
|
||||
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
|
||||
for (pl = pm;
|
||||
pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
|
||||
pl -= es)
|
||||
swap(pl, pl - es);
|
||||
return;
|
||||
}
|
||||
|
||||
pn = (char *)a + n * es;
|
||||
r = min(pa - (char *)a, pb - pa);
|
||||
vecswap((char *)a, pb - r, r);
|
||||
r = min(pd - pc, pn - pd - es);
|
||||
vecswap(pb, pn - r, r);
|
||||
if ((r = pb - pa) > es)
|
||||
recast_qsort(a, r / es, es, thunk, cmp);
|
||||
if ((r = pd - pc) > es) {
|
||||
/* Iterate rather than recurse to save stack space */
|
||||
a = pn - r;
|
||||
n = r / es;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
|
||||
|
98
extern/recastnavigation/recast-capi.h
vendored
98
extern/recastnavigation/recast-capi.h
vendored
@ -28,13 +28,111 @@
|
||||
#ifndef RECAST_C_API_H
|
||||
#define RECAST_C_API_H
|
||||
|
||||
// for size_t
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct recast_polyMesh;
|
||||
struct recast_polyMeshDetail;
|
||||
struct recast_heightfield;
|
||||
struct recast_compactHeightfield;
|
||||
struct recast_contourSet;
|
||||
|
||||
enum recast_SpanFlags
|
||||
{
|
||||
RECAST_WALKABLE = 0x01,
|
||||
RECAST_REACHABLE = 0x02
|
||||
};
|
||||
|
||||
int recast_buildMeshAdjacency(unsigned short* polys, const int npolys,
|
||||
const int nverts, const int vertsPerPoly);
|
||||
|
||||
void recast_calcBounds(const float *verts, int nv, float *bmin, float *bmax);
|
||||
|
||||
void recast_calcGridSize(const float *bmin, const float *bmax, float cs, int *w, int *h);
|
||||
|
||||
struct recast_heightfield *recast_newHeightfield(void);
|
||||
|
||||
void recast_destroyHeightfield(struct recast_heightfield *heightfield);
|
||||
|
||||
int recast_createHeightfield(struct recast_heightfield *hf, int width, int height,
|
||||
const float *bmin, const float* bmax, float cs, float ch);
|
||||
|
||||
void recast_markWalkableTriangles(const float walkableSlopeAngle,const float *verts, int nv,
|
||||
const int *tris, int nt, unsigned char *flags);
|
||||
|
||||
void recast_rasterizeTriangles(const float *verts, int nv, const int *tris,
|
||||
const unsigned char *flags, int nt, struct recast_heightfield *solid);
|
||||
|
||||
void recast_filterLedgeSpans(const int walkableHeight, const int walkableClimb,
|
||||
struct recast_heightfield *solid);
|
||||
|
||||
void recast_filterWalkableLowHeightSpans(int walkableHeight, struct recast_heightfield *solid);
|
||||
|
||||
void recast_filterLowHangingWalkableObstacles(const int walkableClimb, struct recast_heightfield *solid);
|
||||
|
||||
struct recast_compactHeightfield *recast_newCompactHeightfield(void);
|
||||
|
||||
void recast_destroyCompactHeightfield(struct recast_compactHeightfield *compactHeightfield);
|
||||
|
||||
int recast_buildCompactHeightfield(const int walkableHeight, const int walkableClimb,
|
||||
struct recast_heightfield *hf, struct recast_compactHeightfield *chf);
|
||||
|
||||
int recast_erodeWalkableArea(int radius, struct recast_compactHeightfield *chf);
|
||||
|
||||
int recast_buildDistanceField(struct recast_compactHeightfield *chf);
|
||||
|
||||
int recast_buildRegions(struct recast_compactHeightfield *chf, int borderSize,
|
||||
int minRegionSize, int mergeRegionSize);
|
||||
|
||||
/* Contour set */
|
||||
|
||||
struct recast_contourSet *recast_newContourSet(void);
|
||||
|
||||
void recast_destroyContourSet(struct recast_contourSet *contourSet);
|
||||
|
||||
int recast_buildContours(struct recast_compactHeightfield *chf,
|
||||
const float maxError, const int maxEdgeLen, struct recast_contourSet *cset);
|
||||
|
||||
/* Poly mesh */
|
||||
|
||||
struct recast_polyMesh *recast_newPolyMesh(void);
|
||||
|
||||
void recast_destroyPolyMesh(struct recast_polyMesh *polyMesh);
|
||||
|
||||
int recast_buildPolyMesh(struct recast_contourSet *cset, int nvp, struct recast_polyMesh *mesh);
|
||||
|
||||
unsigned short *recast_polyMeshGetVerts(struct recast_polyMesh *mesh, int *nverts);
|
||||
|
||||
void recast_polyMeshGetBoundbox(struct recast_polyMesh *mesh, float *bmin, float *bmax);
|
||||
|
||||
void recast_polyMeshGetCell(struct recast_polyMesh *mesh, float *cs, float *ch);
|
||||
|
||||
unsigned short *recast_polyMeshGetPolys(struct recast_polyMesh *mesh, int *npolys, int *nvp);
|
||||
|
||||
/* Poly mesh detail */
|
||||
|
||||
struct recast_polyMeshDetail *recast_newPolyMeshDetail(void);
|
||||
|
||||
void recast_destroyPolyMeshDetail(struct recast_polyMeshDetail *polyMeshDetail);
|
||||
|
||||
int recast_buildPolyMeshDetail(const struct recast_polyMesh *mesh, const struct recast_compactHeightfield *chf,
|
||||
const float sampleDist, const float sampleMaxError, struct recast_polyMeshDetail *dmesh);
|
||||
|
||||
float *recast_polyMeshDetailGetVerts(struct recast_polyMeshDetail *mesh, int *nverts);
|
||||
|
||||
unsigned char *recast_polyMeshDetailGetTris(struct recast_polyMeshDetail *mesh, int *ntris);
|
||||
|
||||
unsigned int *recast_polyMeshDetailGetMeshes(struct recast_polyMeshDetail *mesh, int *nmeshes);
|
||||
|
||||
/* utility function: quick sort reentrant */
|
||||
typedef int recast_cmp_t(void *ctx, const void *a, const void *b);
|
||||
|
||||
void recast_qsort(void *a, size_t n, size_t es, void *thunk, recast_cmp_t *cmp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -23,7 +23,6 @@
|
||||
set(INC
|
||||
.
|
||||
FX
|
||||
SRC
|
||||
intern
|
||||
../ffmpeg
|
||||
)
|
||||
@ -262,20 +261,6 @@ if(WITH_CODEC_SNDFILE)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_SAMPLERATE)
|
||||
add_definitions(-DWITH_SAMPLERATE)
|
||||
list(APPEND INC_SYS
|
||||
${SAMPLERATE_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND SRC
|
||||
SRC/AUD_SRCResampleFactory.cpp
|
||||
SRC/AUD_SRCResampleReader.cpp
|
||||
|
||||
SRC/AUD_SRCResampleFactory.h
|
||||
SRC/AUD_SRCResampleReader.h
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_FFTW3 AND FALSE)
|
||||
add_definitions(-DWITH_FFTW3)
|
||||
list(APPEND INC
|
||||
|
@ -848,6 +848,8 @@ Factory_filter(Factory* self, PyObject* args)
|
||||
{
|
||||
PyObject* py_b;
|
||||
PyObject* py_a = NULL;
|
||||
Py_ssize_t py_a_len;
|
||||
Py_ssize_t py_b_len;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
|
||||
return NULL;
|
||||
@ -858,7 +860,10 @@ Factory_filter(Factory* self, PyObject* args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!PySequence_Size(py_b) || (py_a != NULL && !PySequence_Size(py_a)))
|
||||
py_a_len= py_a ? PySequence_Size(py_a) : 0;
|
||||
py_b_len= PySequence_Size(py_b);
|
||||
|
||||
if(!py_b_len || ((py_a != NULL) && !py_b_len))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
|
||||
return NULL;
|
||||
@ -867,30 +872,31 @@ Factory_filter(Factory* self, PyObject* args)
|
||||
std::vector<float> a, b;
|
||||
PyObject* py_value;
|
||||
float value;
|
||||
int result;
|
||||
|
||||
for(int i = 0; i < PySequence_Size(py_b); i++)
|
||||
for(Py_ssize_t i = 0; i < py_b_len; i++)
|
||||
{
|
||||
py_value = PySequence_GetItem(py_b, i);
|
||||
result = PyArg_Parse(py_value, "f:filter", &value);
|
||||
value= (float)PyFloat_AsDouble(py_value);
|
||||
Py_DECREF(py_value);
|
||||
|
||||
if(!result)
|
||||
if (value==-1.0f && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b.push_back(value);
|
||||
}
|
||||
|
||||
if(py_a)
|
||||
{
|
||||
for(int i = 0; i < PySequence_Size(py_a); i++)
|
||||
for(Py_ssize_t i = 0; i < py_a_len; i++)
|
||||
{
|
||||
py_value = PySequence_GetItem(py_a, i);
|
||||
result = PyArg_Parse(py_value, "f:filter", &value);
|
||||
value= (float)PyFloat_AsDouble(py_value);
|
||||
Py_DECREF(py_value);
|
||||
|
||||
if(!result)
|
||||
if (value==-1.0f && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a.push_back(value);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
Import ('env')
|
||||
|
||||
sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp') + env.Glob('SRC/*.cpp')
|
||||
incs = '. intern FX SRC ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_LIBSAMPLERATE_INC']
|
||||
sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp')
|
||||
incs = '. intern FX ' + env['BF_PTHREADS_INC']
|
||||
defs = []
|
||||
|
||||
if env['WITH_BF_FFMPEG']:
|
||||
@ -44,7 +44,4 @@ if env['WITH_BF_PYTHON']:
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||
incs += ' ' + env['BF_PTHREADS_INC']
|
||||
|
||||
# not optional with scons yet
|
||||
defs.append('WITH_SAMPLERATE')
|
||||
|
||||
env.BlenderLib ('bf_intern_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
|
||||
|
@ -1094,9 +1094,11 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_pe
|
||||
specs.specs = reader->getSpecs();
|
||||
int len;
|
||||
float samplejump = specs.rate / samples_per_second;
|
||||
float min, max, power;
|
||||
float min, max, power, overallmax;
|
||||
bool eos;
|
||||
|
||||
overallmax = 0;
|
||||
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
len = floor(samplejump * (i+1)) - floor(samplejump * i);
|
||||
@ -1121,6 +1123,11 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_pe
|
||||
buffer[i * 3 + 1] = max;
|
||||
buffer[i * 3 + 2] = sqrt(power) / len;
|
||||
|
||||
if(overallmax < max)
|
||||
overallmax = max;
|
||||
if(overallmax < -min)
|
||||
overallmax = -min;
|
||||
|
||||
if(eos)
|
||||
{
|
||||
length = i;
|
||||
@ -1128,6 +1135,14 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_pe
|
||||
}
|
||||
}
|
||||
|
||||
if(overallmax > 1.0f)
|
||||
{
|
||||
for(int i = 0; i < length * 3; i++)
|
||||
{
|
||||
buffer[i] /= overallmax;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -132,8 +132,14 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
|
||||
while(eit != m_factory->m_entries.end())
|
||||
{
|
||||
handle = new AUD_SequencerHandle(*eit, m_device);
|
||||
handles.push_front(handle);
|
||||
try
|
||||
{
|
||||
handle = new AUD_SequencerHandle(*eit, m_device);
|
||||
handles.push_front(handle);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
}
|
||||
eit++;
|
||||
}
|
||||
|
||||
|
@ -37,18 +37,18 @@
|
||||
|
||||
class CTR_Link {
|
||||
public:
|
||||
CTR_Link(
|
||||
CTR_Link(
|
||||
) ;
|
||||
|
||||
CTR_Link(
|
||||
CTR_Link(
|
||||
CTR_Link *next,
|
||||
CTR_Link *prev
|
||||
) ;
|
||||
|
||||
|
||||
CTR_Link *
|
||||
getNext(
|
||||
) const ;
|
||||
|
||||
|
||||
CTR_Link *
|
||||
getPrev(
|
||||
) const ;
|
||||
@ -76,14 +76,14 @@ public:
|
||||
) ;
|
||||
|
||||
private:
|
||||
CTR_Link *m_next;
|
||||
CTR_Link *m_prev;
|
||||
CTR_Link *m_next;
|
||||
CTR_Link *m_prev;
|
||||
};
|
||||
|
||||
class CTR_List {
|
||||
public:
|
||||
|
||||
CTR_List(
|
||||
CTR_List(
|
||||
) ;
|
||||
|
||||
CTR_Link *
|
||||
@ -103,10 +103,10 @@ public:
|
||||
addTail(
|
||||
CTR_Link *link
|
||||
) ;
|
||||
|
||||
|
||||
private:
|
||||
CTR_Link m_head;
|
||||
CTR_Link m_tail;
|
||||
CTR_Link m_head;
|
||||
CTR_Link m_tail;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -37,24 +37,24 @@
|
||||
template <class Key, class Value>
|
||||
class CTR_Map {
|
||||
private:
|
||||
struct Entry {
|
||||
Entry (Entry *next, Key key, Value value) :
|
||||
m_next(next),
|
||||
m_key(key),
|
||||
m_value(value) {}
|
||||
struct Entry {
|
||||
Entry (Entry *next, Key key, Value value) :
|
||||
m_next(next),
|
||||
m_key(key),
|
||||
m_value(value) {}
|
||||
|
||||
Entry *m_next;
|
||||
Key m_key;
|
||||
Value m_value;
|
||||
};
|
||||
|
||||
Entry *m_next;
|
||||
Key m_key;
|
||||
Value m_value;
|
||||
};
|
||||
|
||||
public:
|
||||
CTR_Map(int num_buckets = 100) : m_num_buckets(num_buckets) {
|
||||
m_buckets = new Entry *[num_buckets];
|
||||
for (int i = 0; i < num_buckets; ++i) {
|
||||
m_buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
CTR_Map(int num_buckets = 100) : m_num_buckets(num_buckets) {
|
||||
m_buckets = new Entry *[num_buckets];
|
||||
for (int i = 0; i < num_buckets; ++i) {
|
||||
m_buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CTR_Map(const CTR_Map& map)
|
||||
{
|
||||
@ -68,114 +68,114 @@ public:
|
||||
insert(entry->m_key, entry->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
int size() {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Value* at(int index) {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
if (count==index)
|
||||
{
|
||||
return &bucket->m_value;
|
||||
}
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Key* getKey(int index) {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
if (count==index)
|
||||
{
|
||||
return &bucket->m_key;
|
||||
}
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (int i = 0; i < m_num_buckets; ++i) {
|
||||
Entry *entry_ptr = m_buckets[i];
|
||||
|
||||
while (entry_ptr != 0) {
|
||||
Entry *tmp_ptr = entry_ptr->m_next;
|
||||
delete entry_ptr;
|
||||
entry_ptr = tmp_ptr;
|
||||
}
|
||||
m_buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~CTR_Map() {
|
||||
clear();
|
||||
delete [] m_buckets;
|
||||
}
|
||||
|
||||
void insert(const Key& key, const Value& value) {
|
||||
Entry *entry_ptr = m_buckets[key.hash() % m_num_buckets];
|
||||
while ((entry_ptr != 0) && !(key == entry_ptr->m_key)) {
|
||||
entry_ptr = entry_ptr->m_next;
|
||||
}
|
||||
|
||||
if (entry_ptr != 0) {
|
||||
entry_ptr->m_value = value;
|
||||
}
|
||||
else {
|
||||
Entry **bucket = &m_buckets[key.hash() % m_num_buckets];
|
||||
*bucket = new Entry(*bucket, key, value);
|
||||
}
|
||||
}
|
||||
int size() {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void remove(const Key& key) {
|
||||
Entry **entry_ptr = &m_buckets[key.hash() % m_num_buckets];
|
||||
while ((*entry_ptr != 0) && !(key == (*entry_ptr)->m_key)) {
|
||||
entry_ptr = &(*entry_ptr)->m_next;
|
||||
}
|
||||
|
||||
if (*entry_ptr != 0) {
|
||||
Entry *tmp_ptr = (*entry_ptr)->m_next;
|
||||
delete *entry_ptr;
|
||||
*entry_ptr = tmp_ptr;
|
||||
}
|
||||
}
|
||||
Value* at(int index) {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
if (count==index)
|
||||
{
|
||||
return &bucket->m_value;
|
||||
}
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Key* getKey(int index) {
|
||||
int count=0;
|
||||
for (int i=0;i<m_num_buckets;i++)
|
||||
{
|
||||
Entry* bucket = m_buckets[i];
|
||||
while(bucket)
|
||||
{
|
||||
if (count==index)
|
||||
{
|
||||
return &bucket->m_key;
|
||||
}
|
||||
bucket = bucket->m_next;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
for (int i = 0; i < m_num_buckets; ++i) {
|
||||
Entry *entry_ptr = m_buckets[i];
|
||||
|
||||
while (entry_ptr != 0) {
|
||||
Entry *tmp_ptr = entry_ptr->m_next;
|
||||
delete entry_ptr;
|
||||
entry_ptr = tmp_ptr;
|
||||
}
|
||||
m_buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~CTR_Map() {
|
||||
clear();
|
||||
delete [] m_buckets;
|
||||
}
|
||||
|
||||
void insert(const Key& key, const Value& value) {
|
||||
Entry *entry_ptr = m_buckets[key.hash() % m_num_buckets];
|
||||
while ((entry_ptr != 0) && !(key == entry_ptr->m_key)) {
|
||||
entry_ptr = entry_ptr->m_next;
|
||||
}
|
||||
|
||||
if (entry_ptr != 0) {
|
||||
entry_ptr->m_value = value;
|
||||
}
|
||||
else {
|
||||
Entry **bucket = &m_buckets[key.hash() % m_num_buckets];
|
||||
*bucket = new Entry(*bucket, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void remove(const Key& key) {
|
||||
Entry **entry_ptr = &m_buckets[key.hash() % m_num_buckets];
|
||||
while ((*entry_ptr != 0) && !(key == (*entry_ptr)->m_key)) {
|
||||
entry_ptr = &(*entry_ptr)->m_next;
|
||||
}
|
||||
|
||||
if (*entry_ptr != 0) {
|
||||
Entry *tmp_ptr = (*entry_ptr)->m_next;
|
||||
delete *entry_ptr;
|
||||
*entry_ptr = tmp_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
Value *operator[](Key key) {
|
||||
Entry *bucket = m_buckets[key.hash() % m_num_buckets];
|
||||
while ((bucket != 0) && !(key == bucket->m_key)) {
|
||||
bucket = bucket->m_next;
|
||||
}
|
||||
return bucket != 0 ? &bucket->m_value : 0;
|
||||
}
|
||||
|
||||
Value *operator[](Key key) {
|
||||
Entry *bucket = m_buckets[key.hash() % m_num_buckets];
|
||||
while ((bucket != 0) && !(key == bucket->m_key)) {
|
||||
bucket = bucket->m_next;
|
||||
}
|
||||
return bucket != 0 ? &bucket->m_value : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_num_buckets;
|
||||
Entry **m_buckets;
|
||||
int m_num_buckets;
|
||||
Entry **m_buckets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -216,7 +216,6 @@ void ntlWorld::finishWorldInit()
|
||||
}
|
||||
long stopTime = getTime();
|
||||
|
||||
mSimulationTime += (*mpSims)[mFirstSim]->getStartTime();
|
||||
debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start-sims:"<< getTimeString(stopTime-startTime) , 1);
|
||||
#ifndef NOGUI
|
||||
guiResetSimulationTimeRange( mSimulationTime );
|
||||
|
@ -25,6 +25,15 @@
|
||||
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
|
||||
/* check our ffmpeg is new enough, avoids user complaints */
|
||||
#if (LIBAVFORMAT_VERSION_MAJOR < 52) || ((LIBAVFORMAT_VERSION_MAJOR == 52) && (LIBAVFORMAT_VERSION_MINOR <= 64))
|
||||
# error "FFmpeg 0.7 or newer is needed, Upgrade you're FFmpeg or disable it"
|
||||
#endif
|
||||
/* end sanity check */
|
||||
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/rational.h>
|
||||
|
||||
|
@ -248,9 +248,10 @@ elseif(UNIX)
|
||||
endif()
|
||||
|
||||
elseif(WIN32)
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
|
||||
endif()
|
||||
## Warnings as errors, this is too strict!
|
||||
#if(MSVC)
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
|
||||
#endif()
|
||||
|
||||
list(APPEND INC_SYS
|
||||
${WINTAB_INC}
|
||||
|
@ -96,14 +96,14 @@ typedef enum {
|
||||
} GHOST_TFireTimeConstant;
|
||||
|
||||
typedef enum {
|
||||
GHOST_kModifierKeyLeftShift = 0,
|
||||
GHOST_kModifierKeyRightShift,
|
||||
GHOST_kModifierKeyLeftAlt,
|
||||
GHOST_kModifierKeyRightAlt,
|
||||
GHOST_kModifierKeyLeftControl,
|
||||
GHOST_kModifierKeyRightControl,
|
||||
GHOST_kModifierKeyOS,
|
||||
GHOST_kModifierKeyNumMasks
|
||||
GHOST_kModifierKeyLeftShift = 0,
|
||||
GHOST_kModifierKeyRightShift,
|
||||
GHOST_kModifierKeyLeftAlt,
|
||||
GHOST_kModifierKeyRightAlt,
|
||||
GHOST_kModifierKeyLeftControl,
|
||||
GHOST_kModifierKeyRightControl,
|
||||
GHOST_kModifierKeyOS,
|
||||
GHOST_kModifierKeyNumMasks
|
||||
} GHOST_TModifierKeyMask;
|
||||
|
||||
|
||||
|
@ -34,7 +34,12 @@ elif window_system in ('linux', 'openbsd3', 'sunos5', 'freebsd7', 'freebsd8', 'f
|
||||
sources.remove('intern' + os.sep + f + 'SDL.cpp')
|
||||
except ValueError:
|
||||
pass
|
||||
defs += ['PREFIX=\\"/usr/local/\\"'] # XXX, make an option
|
||||
## removing because scons does not support system installation
|
||||
## if this is used for blender.org builds it means our distrobution
|
||||
## will find any locally installed blender and double up its script path.
|
||||
## So until this is supported properly as with CMake,
|
||||
## just dont use the PREFIX.
|
||||
# defs += ['PREFIX=\\"/usr/local/\\"'] # XXX, make an option
|
||||
defs += ['WITH_X11_XINPUT'] # XXX, make an option
|
||||
|
||||
elif window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||
@ -100,6 +105,11 @@ if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-v
|
||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||
|
||||
if window_system in ('win32-vc', 'win64-vc'):
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15]) #, cc_compileflags=env['CCFLAGS'].append('/WX') )
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15]) #, cc_compileflags=env['CCFLAGS'].append('/WX') )
|
||||
|
||||
elif env['WITH_GHOST_COCOA']: # always use Apple-gcc-4.2 for objC language, for gnu-compilers do not support it fully yet
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15], cc_compilerchange='/usr/bin/gcc-4.2', cxx_compilerchange='/usr/bin/g++-4.2' )
|
||||
print "GHOST COCOA WILL BE COMPILED WITH APPLE GCC"
|
||||
|
||||
else:
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||
|
@ -44,35 +44,35 @@
|
||||
* @date May 15, 2001
|
||||
*/
|
||||
struct GHOST_Buttons {
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_Buttons();
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_Buttons();
|
||||
|
||||
virtual ~GHOST_Buttons();
|
||||
|
||||
/**
|
||||
* Returns the state of a single button.
|
||||
* @param mask. Key button to return.
|
||||
* @return The state of the button (pressed == true).
|
||||
*/
|
||||
virtual bool get(GHOST_TButtonMask mask) const;
|
||||
|
||||
/**
|
||||
* Updates the state of a single button.
|
||||
* @param mask. Button state to update.
|
||||
* @param down. The new state of the button.
|
||||
*/
|
||||
virtual void set(GHOST_TButtonMask mask, bool down);
|
||||
|
||||
/**
|
||||
* Sets the state of all buttons to up.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
GHOST_TUns8 m_ButtonLeft : 1;
|
||||
GHOST_TUns8 m_ButtonMiddle : 1;
|
||||
GHOST_TUns8 m_ButtonRight : 1;
|
||||
|
||||
/**
|
||||
* Returns the state of a single button.
|
||||
* @param mask. Key button to return.
|
||||
* @return The state of the button (pressed == true).
|
||||
*/
|
||||
virtual bool get(GHOST_TButtonMask mask) const;
|
||||
|
||||
/**
|
||||
* Updates the state of a single button.
|
||||
* @param mask. Button state to update.
|
||||
* @param down. The new state of the button.
|
||||
*/
|
||||
virtual void set(GHOST_TButtonMask mask, bool down);
|
||||
|
||||
/**
|
||||
* Sets the state of all buttons to up.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
GHOST_TUns8 m_ButtonLeft : 1;
|
||||
GHOST_TUns8 m_ButtonMiddle : 1;
|
||||
GHOST_TUns8 m_ButtonRight : 1;
|
||||
};
|
||||
|
||||
#endif // _GHOST_BUTTONS_H_
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
ULONG __stdcall Release (void);
|
||||
|
||||
/* IDropTarget implementation
|
||||
+ The IDropTarget interface is one of the interfaces you implement to
|
||||
+ The IDropTarget interface is one of the interfaces you implement to
|
||||
provide drag-and-drop operations in your application. It contains methods
|
||||
used in any application that can be a target for data during a
|
||||
drag-and-drop operation. A drop-target application is responsible for:
|
||||
|
@ -127,9 +127,9 @@ public:
|
||||
* Removes all events for a window from the stack.
|
||||
* @param window The window to remove events for.
|
||||
*/
|
||||
virtual void
|
||||
removeWindowEvents(
|
||||
GHOST_IWindow* window
|
||||
virtual void
|
||||
removeWindowEvents(
|
||||
GHOST_IWindow* window
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -44,10 +44,10 @@
|
||||
*/
|
||||
struct GHOST_ModifierKeys
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ModifierKeys();
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_ModifierKeys();
|
||||
|
||||
virtual ~GHOST_ModifierKeys();
|
||||
|
||||
@ -58,25 +58,25 @@ struct GHOST_ModifierKeys
|
||||
*/
|
||||
static GHOST_TKey getModifierKeyCode(GHOST_TModifierKeyMask mask);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the state of a single modifier key.
|
||||
* @param mask. Key state to return.
|
||||
* @return The state of the key (pressed == true).
|
||||
*/
|
||||
virtual bool get(GHOST_TModifierKeyMask mask) const;
|
||||
|
||||
/**
|
||||
* Updates the state of a single modifier key.
|
||||
* @param mask. Key state to update.
|
||||
* @param down. The new state of the key.
|
||||
*/
|
||||
virtual void set(GHOST_TModifierKeyMask mask, bool down);
|
||||
|
||||
/**
|
||||
* Sets the state of all modifier keys to up.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
/**
|
||||
* Returns the state of a single modifier key.
|
||||
* @param mask. Key state to return.
|
||||
* @return The state of the key (pressed == true).
|
||||
*/
|
||||
virtual bool get(GHOST_TModifierKeyMask mask) const;
|
||||
|
||||
/**
|
||||
* Updates the state of a single modifier key.
|
||||
* @param mask. Key state to update.
|
||||
* @param down. The new state of the key.
|
||||
*/
|
||||
virtual void set(GHOST_TModifierKeyMask mask, bool down);
|
||||
|
||||
/**
|
||||
* Sets the state of all modifier keys to up.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
/**
|
||||
* Determines whether to modifier key states are equal.
|
||||
@ -84,21 +84,21 @@ struct GHOST_ModifierKeys
|
||||
* @return Indication of equality.
|
||||
*/
|
||||
virtual bool equals(const GHOST_ModifierKeys& keys) const;
|
||||
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_OS : 1;
|
||||
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_LeftControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_RightControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
GHOST_TUns8 m_OS : 1;
|
||||
};
|
||||
|
||||
#endif // _GHOST_MODIFIER_KEYS_H_
|
||||
|
@ -250,7 +250,7 @@ public:
|
||||
virtual inline GHOST_WindowManager* getWindowManager() const;
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
/**
|
||||
/**
|
||||
* Returns a pointer to our n-degree of freedeom manager.
|
||||
* @return A pointer to our n-degree of freedeom manager.
|
||||
*/
|
||||
|
@ -394,7 +394,7 @@ GHOST_TUns8 GHOST_SystemCarbon::getNumDisplays() const
|
||||
void GHOST_SystemCarbon::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
|
||||
{
|
||||
BitMap screenBits;
|
||||
Rect bnds = GetQDGlobalsScreenBits(&screenBits)->bounds;
|
||||
Rect bnds = GetQDGlobalsScreenBits(&screenBits)->bounds;
|
||||
width = bnds.right - bnds.left;
|
||||
height = bnds.bottom - bnds.top;
|
||||
}
|
||||
@ -413,28 +413,28 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow(
|
||||
const GHOST_TEmbedderWindowID parentWindow
|
||||
)
|
||||
{
|
||||
GHOST_IWindow* window = 0;
|
||||
GHOST_IWindow* window = 0;
|
||||
|
||||
window = new GHOST_WindowCarbon (title, left, top, width, height, state, type);
|
||||
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
|
||||
}
|
||||
else {
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
// Store the pointer to the window
|
||||
GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
|
||||
m_windowManager->addWindow(window);
|
||||
m_windowManager->setActiveWindow(window);
|
||||
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemCarbon::createWindow(): window invalid\n");
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
}
|
||||
delete window;
|
||||
window = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
GHOST_PRINT("GHOST_SystemCarbon::createWindow(): could not create window\n");
|
||||
}
|
||||
return window;
|
||||
return window;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCarbon::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)
|
||||
@ -522,19 +522,19 @@ bool GHOST_SystemCarbon::processEvents(bool waitForEvent)
|
||||
}
|
||||
} while (waitForEvent && !anyProcessed);
|
||||
|
||||
return anyProcessed;
|
||||
return anyProcessed;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCarbon::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
|
||||
{
|
||||
Point mouseLoc;
|
||||
// Get the position of the mouse in the active port
|
||||
::GetGlobalMouse(&mouseLoc);
|
||||
// Convert the coordinates to screen coordinates
|
||||
x = (GHOST_TInt32)mouseLoc.h;
|
||||
y = (GHOST_TInt32)mouseLoc.v;
|
||||
return GHOST_kSuccess;
|
||||
Point mouseLoc;
|
||||
// Get the position of the mouse in the active port
|
||||
::GetGlobalMouse(&mouseLoc);
|
||||
// Convert the coordinates to screen coordinates
|
||||
x = (GHOST_TInt32)mouseLoc.h;
|
||||
y = (GHOST_TInt32)mouseLoc.v;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
@ -552,29 +552,29 @@ GHOST_TSuccess GHOST_SystemCarbon::setCursorPosition(GHOST_TInt32 x, GHOST_TInt3
|
||||
// this call below sends event, but empties other events (like shift)
|
||||
// CGPostMouseEvent(CGPointMake(xf, yf), TRUE, 1, FALSE, 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCarbon::getModifierKeys(GHOST_ModifierKeys& keys) const
|
||||
{
|
||||
UInt32 modifiers = ::GetCurrentKeyModifiers();
|
||||
UInt32 modifiers = ::GetCurrentKeyModifiers();
|
||||
|
||||
keys.set(GHOST_kModifierKeyOS, (modifiers & cmdKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & optionKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftShift, (modifiers & shiftKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftControl, (modifiers & controlKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyOS, (modifiers & cmdKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & optionKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftShift, (modifiers & shiftKey) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftControl, (modifiers & controlKey) ? true : false);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
/* XXX, incorrect for multibutton mice */
|
||||
/* XXX, incorrect for multibutton mice */
|
||||
GHOST_TSuccess GHOST_SystemCarbon::getButtons(GHOST_Buttons& buttons) const
|
||||
{
|
||||
Boolean theOnlyButtonIsDown = ::Button();
|
||||
buttons.clear();
|
||||
buttons.set(GHOST_kButtonMaskLeft, theOnlyButtonIsDown);
|
||||
return GHOST_kSuccess;
|
||||
Boolean theOnlyButtonIsDown = ::Button();
|
||||
buttons.clear();
|
||||
buttons.set(GHOST_kButtonMaskLeft, theOnlyButtonIsDown);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#define FIRSTFILEBUFLG 512
|
||||
@ -659,35 +659,35 @@ OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *re
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCarbon::init()
|
||||
{
|
||||
|
||||
GHOST_TSuccess success = GHOST_System::init();
|
||||
if (success) {
|
||||
|
||||
GHOST_TSuccess success = GHOST_System::init();
|
||||
if (success) {
|
||||
/*
|
||||
* Initialize the cursor to the standard arrow shape (so that we can change it later on).
|
||||
* This initializes the cursor's visibility counter to 0.
|
||||
*/
|
||||
::InitCursor();
|
||||
* Initialize the cursor to the standard arrow shape (so that we can change it later on).
|
||||
* This initializes the cursor's visibility counter to 0.
|
||||
*/
|
||||
::InitCursor();
|
||||
|
||||
MenuRef windMenu;
|
||||
::CreateStandardWindowMenu(0, &windMenu);
|
||||
::InsertMenu(windMenu, 0);
|
||||
::DrawMenuBar();
|
||||
|
||||
::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
|
||||
::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
|
||||
|
||||
::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false);
|
||||
::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false);
|
||||
::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false);
|
||||
::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false);
|
||||
|
||||
}
|
||||
return success;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCarbon::exit()
|
||||
{
|
||||
return GHOST_System::exit();
|
||||
return GHOST_System::exit();
|
||||
}
|
||||
|
||||
|
||||
@ -847,11 +847,11 @@ OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
|
||||
err = noErr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case kEventMouseMoved:
|
||||
case kEventMouseDragged: {
|
||||
Point mousePos;
|
||||
Point mousePos;
|
||||
|
||||
if (window) {
|
||||
//handle any tablet events that may have come with the mouse event (optional)
|
||||
@ -860,7 +860,7 @@ OSStatus GHOST_SystemCarbon::handleMouseEvent(EventRef event)
|
||||
::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
|
||||
pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, mousePos.h, mousePos.v));
|
||||
err = noErr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kEventMouseWheelMoved:
|
||||
@ -1094,38 +1094,38 @@ bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult)
|
||||
}
|
||||
|
||||
::HiliteMenu(0);
|
||||
return handled;
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData)
|
||||
{
|
||||
GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) userData;
|
||||
OSStatus err = eventNotHandledErr;
|
||||
OSStatus err = eventNotHandledErr;
|
||||
GHOST_IWindow* window;
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
GHOST_TEventNDOFData data;
|
||||
#endif
|
||||
UInt32 kind;
|
||||
|
||||
switch (::GetEventClass(event))
|
||||
{
|
||||
switch (::GetEventClass(event))
|
||||
{
|
||||
case kEventClassAppleEvent:
|
||||
EventRecord eventrec;
|
||||
if (ConvertEventRefToEventRecord(event, &eventrec)) {
|
||||
err = AEProcessAppleEvent(&eventrec);
|
||||
}
|
||||
break;
|
||||
case kEventClassMouse:
|
||||
err = sys->handleMouseEvent(event);
|
||||
break;
|
||||
case kEventClassMouse:
|
||||
err = sys->handleMouseEvent(event);
|
||||
break;
|
||||
case kEventClassWindow:
|
||||
err = sys->handleWindowEvent(event);
|
||||
break;
|
||||
case kEventClassKeyboard:
|
||||
err = sys->handleKeyEvent(event);
|
||||
break;
|
||||
case kEventClassBlender :
|
||||
case kEventClassBlender :
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
window = sys->m_windowManager->getActiveWindow();
|
||||
sys->m_ndofManager->GHOST_NDOFGetDatas(data);
|
||||
@ -1146,11 +1146,11 @@ OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, Even
|
||||
err = noErr;
|
||||
break;
|
||||
default :
|
||||
;
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
|
||||
GHOST_TUns8* GHOST_SystemCarbon::getClipboard(bool selection) const
|
||||
|
@ -55,16 +55,16 @@ class GHOST_EventWindow;
|
||||
*/
|
||||
class GHOST_SystemCarbon : public GHOST_System {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemCarbon();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemCarbon();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemCarbon();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemCarbon();
|
||||
|
||||
/***************************************************************************************
|
||||
** Time(r) functionality
|
||||
***************************************************************************************/
|
||||
@ -211,54 +211,54 @@ protected:
|
||||
virtual GHOST_TSuccess exit();
|
||||
|
||||
|
||||
/**
|
||||
* Handles a tablet event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleTabletEvent(EventRef event);
|
||||
/**
|
||||
* Handles a mouse event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleMouseEvent(EventRef event);
|
||||
/**
|
||||
* Handles a tablet event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleTabletEvent(EventRef event);
|
||||
/**
|
||||
* Handles a mouse event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleMouseEvent(EventRef event);
|
||||
|
||||
/**
|
||||
* Handles a key event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleKeyEvent(EventRef event);
|
||||
/**
|
||||
* Handles a key event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleKeyEvent(EventRef event);
|
||||
|
||||
/**
|
||||
* Handles a window event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleWindowEvent(EventRef event);
|
||||
/**
|
||||
* Handles a window event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
OSStatus handleWindowEvent(EventRef event);
|
||||
|
||||
/**
|
||||
* Handles all basic Mac application stuff for a mouse down event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
bool handleMouseDown(EventRef event);
|
||||
/**
|
||||
* Handles all basic Mac application stuff for a mouse down event.
|
||||
* @param event A Mac event.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
bool handleMouseDown(EventRef event);
|
||||
|
||||
/**
|
||||
* Handles a Mac menu command.
|
||||
* @param menuResult A Mac menu/item identifier.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
bool handleMenuCommand(GHOST_TInt32 menuResult);
|
||||
|
||||
/* callback for blender generated events */
|
||||
// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
|
||||
/**
|
||||
* Handles a Mac menu command.
|
||||
* @param menuResult A Mac menu/item identifier.
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
bool handleMenuCommand(GHOST_TInt32 menuResult);
|
||||
|
||||
/* callback for blender generated events */
|
||||
// static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
|
||||
|
||||
|
||||
/**
|
||||
* Callback for Carbon when it has events.
|
||||
*/
|
||||
/**
|
||||
* Callback for Carbon when it has events.
|
||||
*/
|
||||
static OSStatus sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
|
||||
|
||||
/** Apple Event Handlers */
|
||||
@ -267,23 +267,23 @@ protected:
|
||||
static OSErr sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
|
||||
static OSErr sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon);
|
||||
|
||||
/**
|
||||
* Callback for Mac Timer tasks that expire.
|
||||
* @param tmTask Pointer to the timer task that expired.
|
||||
*/
|
||||
//static void s_timerCallback(TMTaskPtr tmTask);
|
||||
|
||||
/** Event handler reference. */
|
||||
EventHandlerRef m_handler;
|
||||
/**
|
||||
* Callback for Mac Timer tasks that expire.
|
||||
* @param tmTask Pointer to the timer task that expired.
|
||||
*/
|
||||
//static void s_timerCallback(TMTaskPtr tmTask);
|
||||
|
||||
/** Event handler reference. */
|
||||
EventHandlerRef m_handler;
|
||||
|
||||
/** Start time at initialization. */
|
||||
GHOST_TUns64 m_start_time;
|
||||
|
||||
/** State of the modifiers. */
|
||||
UInt32 m_modifierMask;
|
||||
/** State of the modifiers. */
|
||||
UInt32 m_modifierMask;
|
||||
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
};
|
||||
|
||||
#endif // _GHOST_SYSTEM_CARBON_H_
|
||||
|
@ -52,16 +52,16 @@ class GHOST_WindowCocoa;
|
||||
|
||||
class GHOST_SystemCocoa : public GHOST_System {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemCocoa();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemCocoa();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemCocoa();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemCocoa();
|
||||
|
||||
/***************************************************************************************
|
||||
** Time(r) functionality
|
||||
***************************************************************************************/
|
||||
@ -92,7 +92,7 @@ public:
|
||||
|
||||
/**
|
||||
* Create a new window.
|
||||
* The new window is added to the list of windows managed.
|
||||
* The new window is added to the list of windows managed.
|
||||
* Never explicitly delete the window, use disposeWindow() instead.
|
||||
* @param title The name of the window (displayed in the title bar of the window if the OS supports it).
|
||||
* @param left The coordinate of the left edge of the window.
|
||||
@ -107,17 +107,17 @@ public:
|
||||
* @return The new window (or 0 if creation failed).
|
||||
*/
|
||||
virtual GHOST_IWindow* createWindow(
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0
|
||||
);
|
||||
const STR_String& title,
|
||||
GHOST_TInt32 left,
|
||||
GHOST_TInt32 top,
|
||||
GHOST_TUns32 width,
|
||||
GHOST_TUns32 height,
|
||||
GHOST_TWindowState state,
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool stereoVisual = false,
|
||||
const GHOST_TUns16 numOfAASamples = 0,
|
||||
const GHOST_TEmbedderWindowID parentWindow = 0
|
||||
);
|
||||
|
||||
/***************************************************************************************
|
||||
** Event management functionality
|
||||
@ -140,19 +140,19 @@ public:
|
||||
* Handle Cocoa openFile event
|
||||
* Display confirmation request panel if changes performed since last save
|
||||
*/
|
||||
bool handleOpenDocumentRequest(void *filepathStr);
|
||||
bool handleOpenDocumentRequest(void *filepathStr);
|
||||
|
||||
/**
|
||||
* Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass
|
||||
* @param eventType The type of drag'n'drop event
|
||||
* Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass
|
||||
* @param eventType The type of drag'n'drop event
|
||||
* @param draggedObjectType The type object concerned (currently array of file names, string, TIFF image)
|
||||
* @param mouseX x mouse coordinate (in cocoa base window coordinates)
|
||||
* @param mouseY y mouse coordinate
|
||||
* @param window The window on which the event occurred
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, GHOST_TDragnDropTypes draggedObjectType,
|
||||
GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data);
|
||||
GHOST_WindowCocoa* window, int mouseX, int mouseY, void* data);
|
||||
|
||||
/***************************************************************************************
|
||||
** Cursor management functionality
|
||||
@ -207,18 +207,18 @@ public:
|
||||
virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
|
||||
|
||||
/**
|
||||
* Handles a window event. Called by GHOST_WindowCocoa window delegate
|
||||
* @param eventType The type of window event
|
||||
* Handles a window event. Called by GHOST_WindowCocoa window delegate
|
||||
* @param eventType The type of window event
|
||||
* @param window The window on which the event occurred
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window);
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window);
|
||||
|
||||
/**
|
||||
* Handles the Cocoa event telling the application has become active (again)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleApplicationBecomeActiveEvent();
|
||||
* Handles the Cocoa event telling the application has become active (again)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleApplicationBecomeActiveEvent();
|
||||
|
||||
/**
|
||||
* External objects should call this when they send an event outside processEvents.
|
||||
@ -239,28 +239,28 @@ protected:
|
||||
*/
|
||||
virtual GHOST_TSuccess init();
|
||||
|
||||
/**
|
||||
* Handles a tablet event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
|
||||
|
||||
/**
|
||||
* Handles a mouse event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleMouseEvent(void *eventPtr);
|
||||
* Handles a tablet event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
|
||||
|
||||
/**
|
||||
* Handles a mouse event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleMouseEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a key event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleKeyEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Handles a key event.
|
||||
* @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
|
||||
* @return Indication whether the event was handled.
|
||||
*/
|
||||
GHOST_TSuccess handleKeyEvent(void *eventPtr);
|
||||
|
||||
/**
|
||||
* Performs the actual cursor position update (location in screen coordinates).
|
||||
* @param x The x-coordinate of the cursor.
|
||||
@ -281,11 +281,11 @@ protected:
|
||||
/** Mouse buttons state */
|
||||
GHOST_TUns32 m_pressedMouseButtons;
|
||||
|
||||
/** State of the modifiers. */
|
||||
GHOST_TUns32 m_modifierMask;
|
||||
/** State of the modifiers. */
|
||||
GHOST_TUns32 m_modifierMask;
|
||||
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
/** Ignores window size messages (when window is dragged). */
|
||||
bool m_ignoreWindowSizedMessages;
|
||||
|
||||
/** Stores the mouse cursor delta due to setting a new cursor position
|
||||
* Needed because cocoa event delta cursor move takes setCursorPosition changes too.
|
||||
|
@ -50,16 +50,16 @@
|
||||
*/
|
||||
class GHOST_SystemPathsCarbon : public GHOST_SystemPaths {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemPathsCarbon();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemPathsCarbon();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemPathsCarbon();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemPathsCarbon();
|
||||
|
||||
/**
|
||||
* Determine the base dir in which shared resources are located. It will first try to use
|
||||
* "unpack and run" path, then look for properly installed path, not including versioning.
|
||||
@ -78,12 +78,12 @@ public:
|
||||
* Determine the directory of the current binary
|
||||
* @return Unsigned char string pointing to the binary dir
|
||||
*/
|
||||
virtual const GHOST_TUns8* getBinaryDir() const;
|
||||
virtual const GHOST_TUns8* getBinaryDir() const;
|
||||
|
||||
/**
|
||||
* Add the file to the operating system most recently used files
|
||||
*/
|
||||
void addToSystemRecentFiles(const char* filename) const;
|
||||
void addToSystemRecentFiles(const char* filename) const;
|
||||
};
|
||||
|
||||
#endif // _GHOST_SYSTEM_CARBON_H_
|
||||
|
@ -44,15 +44,15 @@
|
||||
|
||||
class GHOST_SystemPathsCocoa : public GHOST_SystemPaths {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemPathsCocoa();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemPathsCocoa();
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
GHOST_SystemPathsCocoa();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~GHOST_SystemPathsCocoa();
|
||||
|
||||
/**
|
||||
* Determine the base dir in which shared resources are located. It will first try to use
|
||||
|
@ -1018,18 +1018,18 @@ convertXKey(KeySym key)
|
||||
GXMAP(type,XK_bracketright, GHOST_kKeyRightBracket);
|
||||
GXMAP(type,XK_Pause, GHOST_kKeyPause);
|
||||
|
||||
GXMAP(type,XK_Shift_L, GHOST_kKeyLeftShift);
|
||||
GXMAP(type,XK_Shift_R, GHOST_kKeyRightShift);
|
||||
GXMAP(type,XK_Shift_L, GHOST_kKeyLeftShift);
|
||||
GXMAP(type,XK_Shift_R, GHOST_kKeyRightShift);
|
||||
GXMAP(type,XK_Control_L, GHOST_kKeyLeftControl);
|
||||
GXMAP(type,XK_Control_R, GHOST_kKeyRightControl);
|
||||
GXMAP(type,XK_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type,XK_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(type,XK_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type,XK_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(type,XK_Super_L, GHOST_kKeyOS);
|
||||
GXMAP(type,XK_Super_R, GHOST_kKeyOS);
|
||||
|
||||
GXMAP(type,XK_Insert, GHOST_kKeyInsert);
|
||||
GXMAP(type,XK_Delete, GHOST_kKeyDelete);
|
||||
GXMAP(type,XK_Home, GHOST_kKeyHome);
|
||||
GXMAP(type,XK_Insert, GHOST_kKeyInsert);
|
||||
GXMAP(type,XK_Delete, GHOST_kKeyDelete);
|
||||
GXMAP(type,XK_Home, GHOST_kKeyHome);
|
||||
GXMAP(type,XK_End, GHOST_kKeyEnd);
|
||||
GXMAP(type,XK_Page_Up, GHOST_kKeyUpPage);
|
||||
GXMAP(type,XK_Page_Down, GHOST_kKeyDownPage);
|
||||
@ -1045,27 +1045,27 @@ convertXKey(KeySym key)
|
||||
|
||||
/* keypad events */
|
||||
|
||||
GXMAP(type,XK_KP_0, GHOST_kKeyNumpad0);
|
||||
GXMAP(type,XK_KP_1, GHOST_kKeyNumpad1);
|
||||
GXMAP(type,XK_KP_2, GHOST_kKeyNumpad2);
|
||||
GXMAP(type,XK_KP_3, GHOST_kKeyNumpad3);
|
||||
GXMAP(type,XK_KP_4, GHOST_kKeyNumpad4);
|
||||
GXMAP(type,XK_KP_5, GHOST_kKeyNumpad5);
|
||||
GXMAP(type,XK_KP_6, GHOST_kKeyNumpad6);
|
||||
GXMAP(type,XK_KP_7, GHOST_kKeyNumpad7);
|
||||
GXMAP(type,XK_KP_8, GHOST_kKeyNumpad8);
|
||||
GXMAP(type,XK_KP_9, GHOST_kKeyNumpad9);
|
||||
GXMAP(type,XK_KP_0, GHOST_kKeyNumpad0);
|
||||
GXMAP(type,XK_KP_1, GHOST_kKeyNumpad1);
|
||||
GXMAP(type,XK_KP_2, GHOST_kKeyNumpad2);
|
||||
GXMAP(type,XK_KP_3, GHOST_kKeyNumpad3);
|
||||
GXMAP(type,XK_KP_4, GHOST_kKeyNumpad4);
|
||||
GXMAP(type,XK_KP_5, GHOST_kKeyNumpad5);
|
||||
GXMAP(type,XK_KP_6, GHOST_kKeyNumpad6);
|
||||
GXMAP(type,XK_KP_7, GHOST_kKeyNumpad7);
|
||||
GXMAP(type,XK_KP_8, GHOST_kKeyNumpad8);
|
||||
GXMAP(type,XK_KP_9, GHOST_kKeyNumpad9);
|
||||
GXMAP(type,XK_KP_Decimal, GHOST_kKeyNumpadPeriod);
|
||||
|
||||
GXMAP(type,XK_KP_Insert, GHOST_kKeyNumpad0);
|
||||
GXMAP(type,XK_KP_End, GHOST_kKeyNumpad1);
|
||||
GXMAP(type,XK_KP_Down, GHOST_kKeyNumpad2);
|
||||
GXMAP(type,XK_KP_End, GHOST_kKeyNumpad1);
|
||||
GXMAP(type,XK_KP_Down, GHOST_kKeyNumpad2);
|
||||
GXMAP(type,XK_KP_Page_Down, GHOST_kKeyNumpad3);
|
||||
GXMAP(type,XK_KP_Left, GHOST_kKeyNumpad4);
|
||||
GXMAP(type,XK_KP_Begin, GHOST_kKeyNumpad5);
|
||||
GXMAP(type,XK_KP_Left, GHOST_kKeyNumpad4);
|
||||
GXMAP(type,XK_KP_Begin, GHOST_kKeyNumpad5);
|
||||
GXMAP(type,XK_KP_Right, GHOST_kKeyNumpad6);
|
||||
GXMAP(type,XK_KP_Home, GHOST_kKeyNumpad7);
|
||||
GXMAP(type,XK_KP_Up, GHOST_kKeyNumpad8);
|
||||
GXMAP(type,XK_KP_Home, GHOST_kKeyNumpad7);
|
||||
GXMAP(type,XK_KP_Up, GHOST_kKeyNumpad8);
|
||||
GXMAP(type,XK_KP_Page_Up, GHOST_kKeyNumpad9);
|
||||
GXMAP(type,XK_KP_Delete, GHOST_kKeyNumpadPeriod);
|
||||
|
||||
|
@ -285,7 +285,7 @@ private :
|
||||
void
|
||||
processEvent(
|
||||
XEvent *xe
|
||||
);
|
||||
);
|
||||
|
||||
Time
|
||||
lastEventTime(
|
||||
@ -294,7 +294,7 @@ private :
|
||||
|
||||
bool
|
||||
generateWindowExposeEvents(
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,25 +21,25 @@
|
||||
#define __ITaskbarList_INTERFACE_DEFINED__
|
||||
extern "C" {const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90} };
|
||||
const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90} }; }
|
||||
class ITaskbarList : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE HrInit (void) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE AddTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE DeleteTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ActivateTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetActiveAlt (HWND hwnd) = 0;
|
||||
};
|
||||
class ITaskbarList : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE HrInit (void) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE AddTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE DeleteTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ActivateTab (HWND hwnd) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetActiveAlt (HWND hwnd) = 0;
|
||||
};
|
||||
#endif /* ITaskbarList */
|
||||
|
||||
#ifndef __ITaskbarList2_INTERFACE_DEFINED__
|
||||
#define __ITaskbarList2_INTERFACE_DEFINED__
|
||||
extern "C" {const GUID IID_ITaskbarList2 = {0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17} }; }
|
||||
class ITaskbarList2 : public ITaskbarList
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0;
|
||||
};
|
||||
class ITaskbarList2 : public ITaskbarList
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0;
|
||||
};
|
||||
#endif /* ITaskbarList2 */
|
||||
|
||||
#ifndef __ITaskbarList3_INTERFACE_DEFINED__
|
||||
@ -51,9 +51,9 @@ typedef enum TBPFLAG {TBPF_NOPROGRESS = 0, TBPF_INDETERMINATE = 0x1, TBPF_NORMA
|
||||
#define THBN_CLICKED 0x1800
|
||||
extern "C" {const GUID IID_ITaskList3 = { 0xEA1AFB91, 0x9E28, 0x4B86, {0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF} };}
|
||||
|
||||
class ITaskbarList3 : public ITaskbarList2
|
||||
{
|
||||
public:
|
||||
class ITaskbarList3 : public ITaskbarList2
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetProgressValue (HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetProgressState (HWND hwnd, TBPFLAG tbpFlags) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE RegisterTab (HWND hwndTab, HWND hwndMDI) = 0;
|
||||
@ -62,11 +62,11 @@ typedef enum TBPFLAG {TBPF_NOPROGRESS = 0, TBPF_INDETERMINATE = 0x1, TBPF_NORMA
|
||||
virtual HRESULT STDMETHODCALLTYPE SetTabActive (HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons (HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons (HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList (HWND hwnd, HIMAGELIST himl) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList (HWND hwnd, HIMAGELIST himl) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon (HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip (HWND hwnd, LPCWSTR pszTip) = 0;
|
||||
virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip (HWND hwnd, RECT *prcClip) = 0;
|
||||
};
|
||||
};
|
||||
#endif /* ITaskbarList3 */
|
||||
|
||||
#endif /*GHOST_TASKBARWIN32_H_*/
|
||||
|
@ -339,11 +339,11 @@ protected:
|
||||
|
||||
/** Number of samples used in anti-aliasing, set to 0 if no AA **/
|
||||
GHOST_TUns16 m_numOfAASamples;
|
||||
|
||||
/** Full-screen width */
|
||||
GHOST_TUns32 m_fullScreenWidth;
|
||||
/** Full-screen height */
|
||||
GHOST_TUns32 m_fullScreenHeight;
|
||||
|
||||
/** Full-screen width */
|
||||
GHOST_TUns32 m_fullScreenWidth;
|
||||
/** Full-screen height */
|
||||
GHOST_TUns32 m_fullScreenHeight;
|
||||
};
|
||||
|
||||
|
||||
|
@ -200,12 +200,12 @@ public:
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
|
||||
virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
|
||||
|
||||
/**
|
||||
* Returns the dirty state of the window when in full-screen mode.
|
||||
* @return Whether it is dirty.
|
||||
*/
|
||||
virtual bool getFullScreenDirty();
|
||||
|
||||
/**
|
||||
* Returns the dirty state of the window when in full-screen mode.
|
||||
* @return Whether it is dirty.
|
||||
*/
|
||||
virtual bool getFullScreenDirty();
|
||||
|
||||
/* accessor for fullscreen window */
|
||||
virtual void setMac_windowState(short value);
|
||||
@ -257,24 +257,24 @@ protected:
|
||||
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
|
||||
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
|
||||
|
||||
/**
|
||||
* Converts a string object to a Mac Pascal string.
|
||||
* @param in The string object to be converted.
|
||||
* @param out The converted string.
|
||||
*/
|
||||
virtual void gen2mac(const STR_String& in, Str255 out) const;
|
||||
|
||||
/**
|
||||
* Converts a Mac Pascal string to a string object.
|
||||
* @param in The string to be converted.
|
||||
* @param out The converted string object.
|
||||
*/
|
||||
virtual void mac2gen(const Str255 in, STR_String& out) const;
|
||||
/**
|
||||
* Converts a string object to a Mac Pascal string.
|
||||
* @param in The string object to be converted.
|
||||
* @param out The converted string.
|
||||
*/
|
||||
virtual void gen2mac(const STR_String& in, Str255 out) const;
|
||||
|
||||
/**
|
||||
* Converts a Mac Pascal string to a string object.
|
||||
* @param in The string to be converted.
|
||||
* @param out The converted string object.
|
||||
*/
|
||||
virtual void mac2gen(const Str255 in, STR_String& out) const;
|
||||
|
||||
WindowRef m_windowRef;
|
||||
CGrafPtr m_grafPtr;
|
||||
AGLContext m_aglCtx;
|
||||
WindowRef m_windowRef;
|
||||
CGrafPtr m_grafPtr;
|
||||
AGLContext m_aglCtx;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static AGLContext s_firstaglCtx;
|
||||
@ -282,9 +282,9 @@ protected:
|
||||
Cursor* m_customCursor;
|
||||
|
||||
GHOST_TabletData m_tablet;
|
||||
|
||||
/** When running in full-screen this tells whether to refresh the window. */
|
||||
bool m_fullScreenDirty;
|
||||
|
||||
/** When running in full-screen this tells whether to refresh the window. */
|
||||
bool m_fullScreenDirty;
|
||||
|
||||
/** specific MacOs X full screen window setting as we use partially system mechanism
|
||||
values : 0 not maximizable default
|
||||
@ -295,17 +295,17 @@ protected:
|
||||
in order to be unified with GHOST fullscreen/maximised settings
|
||||
|
||||
(lukep)
|
||||
**/
|
||||
|
||||
**/
|
||||
|
||||
short mac_windowState;
|
||||
|
||||
|
||||
/**
|
||||
* The width/height of the size rectangle in the lower right corner of a
|
||||
* Mac/Carbon window. This is also the height of the gutter area.
|
||||
*/
|
||||
/**
|
||||
* The width/height of the size rectangle in the lower right corner of a
|
||||
* Mac/Carbon window. This is also the height of the gutter area.
|
||||
*/
|
||||
#ifdef GHOST_DRAW_CARBON_GUTTER
|
||||
static const GHOST_TInt32 s_sizeRectSize;
|
||||
static const GHOST_TInt32 s_sizeRectSize;
|
||||
#endif // GHOST_DRAW_CARBON_GUTTER
|
||||
};
|
||||
|
||||
|
@ -305,13 +305,13 @@ protected:
|
||||
int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
|
||||
|
||||
virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
|
||||
|
||||
/** The window containing the OpenGL view */
|
||||
CocoaWindow *m_window;
|
||||
|
||||
/** The window containing the OpenGL view */
|
||||
CocoaWindow *m_window;
|
||||
|
||||
/** The openGL view */
|
||||
CocoaOpenGLView *m_openGLView;
|
||||
|
||||
|
||||
/** The opgnGL drawing context */
|
||||
NSOpenGLContext *m_openGLContext;
|
||||
|
||||
|
@ -1009,7 +1009,7 @@ GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextTyp
|
||||
switch (type) {
|
||||
case GHOST_kDrawingContextTypeOpenGL:
|
||||
if (!getValid()) break;
|
||||
|
||||
|
||||
pixelFormat = [m_openGLView pixelFormat];
|
||||
tmpOpenGLContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
|
||||
shareContext:s_firstOpenGLcontext];
|
||||
@ -1332,7 +1332,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap
|
||||
|
||||
|
||||
cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
|
||||
pixelsWide:sizex
|
||||
pixelsWide:sizex
|
||||
pixelsHigh:sizey
|
||||
bitsPerSample:1
|
||||
samplesPerPixel:2
|
||||
|
@ -255,7 +255,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
|
||||
title, // pointer to window name
|
||||
WS_POPUP | WS_MAXIMIZE, // window style
|
||||
left, // horizontal position of window
|
||||
top, // vertical position of window
|
||||
top, // vertical position of window
|
||||
width, // window width
|
||||
height, // window height
|
||||
HWND_DESKTOP, // handle to parent or owner window
|
||||
@ -633,7 +633,7 @@ GHOST_TSuccess GHOST_WindowWin32::setState(GHOST_TWindowState state)
|
||||
break;
|
||||
}
|
||||
SetWindowPos(m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); /*Clears window cache for SetWindowLongPtr */
|
||||
return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
return ::SetWindowPlacement(m_hWnd, &wp) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
|
||||
|
@ -614,7 +614,7 @@ void GHOST_WindowX11::initXInputDevices()
|
||||
ici = (XAnyClassPtr)(((char *)ici) + ici->length);
|
||||
}
|
||||
} else {
|
||||
m_xtablet.StylusID= 0;
|
||||
m_xtablet.StylusID= 0;
|
||||
}
|
||||
}
|
||||
else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) {
|
||||
@ -1216,11 +1216,11 @@ activateDrawingContext(
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
invalidate(
|
||||
){
|
||||
|
||||
|
||||
// So the idea of this function is to generate an expose event
|
||||
// for the window.
|
||||
// Unfortunately X does not handle expose events for you and
|
||||
|
@ -190,16 +190,16 @@ static void gearGL(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GL
|
||||
|
||||
static void drawGearGL(int id)
|
||||
{
|
||||
static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
|
||||
static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
|
||||
static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
|
||||
static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
|
||||
static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f };
|
||||
static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f };
|
||||
static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f };
|
||||
static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f };
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
@ -218,40 +218,40 @@ static void drawGearGL(int id)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
glEnable(GL_NORMALIZE);
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
|
||||
static void drawGL(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glPushMatrix();
|
||||
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(fAngle, 0.0, 0.0, 1.0);
|
||||
drawGearGL(1);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(fAngle, 0.0, 0.0, 1.0);
|
||||
drawGearGL(1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1f, -2.0f, 0.0f);
|
||||
glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(2);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1f, -2.0f, 0.0f);
|
||||
glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1f, 2.2f, -1.8f);
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(3);
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1f, 2.2f, -1.8f);
|
||||
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0);
|
||||
drawGearGL(3);
|
||||
glPopMatrix();
|
||||
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
@ -260,21 +260,21 @@ static void setViewPortGL(GHOST_WindowHandle hWindow)
|
||||
GHOST_RectangleHandle hRect = NULL;
|
||||
GLfloat w, h;
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(hWindow);
|
||||
hRect = GHOST_GetClientBounds(hWindow);
|
||||
GHOST_ActivateWindowDrawingContext(hWindow);
|
||||
hRect = GHOST_GetClientBounds(hWindow);
|
||||
|
||||
w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
|
||||
h = 1.0;
|
||||
w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect);
|
||||
h = 1.0;
|
||||
|
||||
glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect));
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-w, w, -h, h, 5.0, 60.0);
|
||||
glFrustum(-w, w, -h, h, 5.0, 60.0);
|
||||
/* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
|
||||
glClearColor(.2f,0.0f,0.0f,0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
@ -541,8 +541,8 @@ int main(int argc, char** argv)
|
||||
static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time)
|
||||
{
|
||||
GHOST_WindowHandle hWindow = NULL;
|
||||
fAngle += 2.0;
|
||||
view_roty += 1.0;
|
||||
fAngle += 2.0;
|
||||
view_roty += 1.0;
|
||||
hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask);
|
||||
if (GHOST_GetFullScreen(shSystem))
|
||||
{
|
||||
|
@ -711,6 +711,10 @@ static void rem_memblock(MemHead *memh)
|
||||
static void MemorY_ErroR(const char *block, const char *error)
|
||||
{
|
||||
print_error("Memoryblock %s: %s\n",block, error);
|
||||
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *check_memlist(MemHead *memh)
|
||||
|
@ -166,13 +166,13 @@ typedef struct
|
||||
tbool bOrient;
|
||||
} STSpace;
|
||||
|
||||
int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn);
|
||||
tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
|
||||
const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
|
||||
const SMikkTSpaceContext * pContext);
|
||||
static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn);
|
||||
static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
|
||||
const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
|
||||
const SMikkTSpaceContext * pContext);
|
||||
|
||||
static int MakeIndex(const int iFace, const int iVert)
|
||||
{
|
||||
@ -216,14 +216,14 @@ static STSpace AvgTSpace(const STSpace * pTS0, const STSpace * pTS1)
|
||||
|
||||
|
||||
|
||||
SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index);
|
||||
SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index);
|
||||
SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index);
|
||||
static SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index);
|
||||
static SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index);
|
||||
static SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index);
|
||||
|
||||
|
||||
// degen triangles
|
||||
void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris);
|
||||
void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris);
|
||||
static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris);
|
||||
static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris);
|
||||
|
||||
|
||||
tbool genTangSpaceDefault(const SMikkTSpaceContext * pContext)
|
||||
@ -450,11 +450,11 @@ NOINLINE int FindGridCell(const float fMin, const float fMax, const float fVal)
|
||||
return iIndex<g_iCells?iIndex:(g_iCells-1);
|
||||
}
|
||||
|
||||
void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in);
|
||||
void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries);
|
||||
void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in);
|
||||
static void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries);
|
||||
static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn);
|
||||
|
||||
void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
{
|
||||
|
||||
// Generate bounding box
|
||||
@ -579,7 +579,7 @@ void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], const SMikkTSpa
|
||||
free(piHashOffsets);
|
||||
}
|
||||
|
||||
void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in)
|
||||
static void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikkTSpaceContext * pContext, const int iL_in, const int iR_in)
|
||||
{
|
||||
// make bbox
|
||||
int c=0, l=0, channel=0;
|
||||
@ -689,7 +689,7 @@ void MergeVertsFast(int piTriList_in_and_out[], STmpVert pTmpVert[], const SMikk
|
||||
}
|
||||
}
|
||||
|
||||
void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries)
|
||||
static void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int pTable[], const int iEntries)
|
||||
{
|
||||
// this can be optimized further using a tree structure or more hashing.
|
||||
int e=0;
|
||||
@ -724,7 +724,7 @@ void MergeVertsSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pCont
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
static void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
{
|
||||
int iNumUniqueVerts = 0, t=0, i=0;
|
||||
for(t=0; t<iNrTrianglesIn; t++)
|
||||
@ -767,7 +767,7 @@ void GenerateSharedVerticesIndexListSlow(int piTriList_in_and_out[], const SMikk
|
||||
}
|
||||
}
|
||||
|
||||
int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
{
|
||||
int iTSpacesOffs = 0, f=0, t=0;
|
||||
int iDstTriIndex = 0;
|
||||
@ -878,7 +878,7 @@ int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], int piTriList_out[],
|
||||
return iTSpacesOffs;
|
||||
}
|
||||
|
||||
SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index)
|
||||
static SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index)
|
||||
{
|
||||
int iF, iI;
|
||||
SVec3 res; float pos[3];
|
||||
@ -888,7 +888,7 @@ SVec3 GetPosition(const SMikkTSpaceContext * pContext, const int index)
|
||||
return res;
|
||||
}
|
||||
|
||||
SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index)
|
||||
static SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index)
|
||||
{
|
||||
int iF, iI;
|
||||
SVec3 res; float norm[3];
|
||||
@ -898,7 +898,7 @@ SVec3 GetNormal(const SMikkTSpaceContext * pContext, const int index)
|
||||
return res;
|
||||
}
|
||||
|
||||
SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index)
|
||||
static SVec3 GetTexCoord(const SMikkTSpaceContext * pContext, const int index)
|
||||
{
|
||||
int iF, iI;
|
||||
SVec3 res; float texc[2];
|
||||
@ -920,8 +920,8 @@ typedef union
|
||||
int array[3];
|
||||
} SEdge;
|
||||
|
||||
void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn);
|
||||
void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn);
|
||||
static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn);
|
||||
static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn);
|
||||
|
||||
// returns the texture area times 2
|
||||
static float CalcTexArea(const SMikkTSpaceContext * pContext, const int indices[])
|
||||
@ -940,7 +940,7 @@ static float CalcTexArea(const SMikkTSpaceContext * pContext, const int indices[
|
||||
return fSignedAreaSTx2<0 ? (-fSignedAreaSTx2) : fSignedAreaSTx2;
|
||||
}
|
||||
|
||||
void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
static void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn)
|
||||
{
|
||||
int f=0, i=0, t=0;
|
||||
// pTriInfos[f].iFlag is cleared in GenerateInitialVerticesIndexList() which is called before this function.
|
||||
@ -1062,10 +1062,10 @@ void InitTriInfo(STriInfo pTriInfos[], const int piTriListIn[], const SMikkTSpac
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int iMyTriIndex, SGroup * pGroup);
|
||||
void AddTriToGroup(SGroup * pGroup, const int iTriIndex);
|
||||
static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[], const int iMyTriIndex, SGroup * pGroup);
|
||||
static void AddTriToGroup(SGroup * pGroup, const int iTriIndex);
|
||||
|
||||
int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn)
|
||||
static int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTrianglesBuffer[], const int piTriListIn[], const int iNrTrianglesIn)
|
||||
{
|
||||
const int iNrMaxGroups = iNrTrianglesIn*3;
|
||||
int iNrActiveGroups = 0;
|
||||
@ -1126,13 +1126,13 @@ int Build4RuleGroups(STriInfo pTriInfos[], SGroup pGroups[], int piGroupTriangle
|
||||
return iNrActiveGroups;
|
||||
}
|
||||
|
||||
void AddTriToGroup(SGroup * pGroup, const int iTriIndex)
|
||||
static void AddTriToGroup(SGroup * pGroup, const int iTriIndex)
|
||||
{
|
||||
pGroup->pFaceIndices[pGroup->iNrFaces] = iTriIndex;
|
||||
++pGroup->iNrFaces;
|
||||
}
|
||||
|
||||
tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[],
|
||||
static tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[],
|
||||
const int iMyTriIndex, SGroup * pGroup)
|
||||
{
|
||||
STriInfo * pMyTriInfo = &psTriInfos[iMyTriIndex];
|
||||
@ -1187,13 +1187,13 @@ tbool AssignRecur(const int piTriListIn[], STriInfo psTriInfos[],
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2);
|
||||
void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed);
|
||||
STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[], const SMikkTSpaceContext * pContext, const int iVertexRepresentitive);
|
||||
static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2);
|
||||
static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed);
|
||||
static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[], const SMikkTSpaceContext * pContext, const int iVertexRepresentitive);
|
||||
|
||||
tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
|
||||
const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
|
||||
const SMikkTSpaceContext * pContext)
|
||||
static tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGroup pGroups[],
|
||||
const int iNrActiveGroups, const int piTriListIn[], const float fThresCos,
|
||||
const SMikkTSpaceContext * pContext)
|
||||
{
|
||||
STSpace * pSubGroupTspace = NULL;
|
||||
SSubGroup * pUniSubGroups = NULL;
|
||||
@ -1361,8 +1361,8 @@ tbool GenerateTSpaces(STSpace psTspace[], const STriInfo pTriInfos[], const SGro
|
||||
return TTRUE;
|
||||
}
|
||||
|
||||
STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[],
|
||||
const SMikkTSpaceContext * pContext, const int iVertexRepresentitive)
|
||||
static STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[], const STriInfo pTriInfos[],
|
||||
const SMikkTSpaceContext * pContext, const int iVertexRepresentitive)
|
||||
{
|
||||
STSpace res;
|
||||
float fAngleSum = 0;
|
||||
@ -1435,7 +1435,7 @@ STSpace EvalTspace(int face_indices[], const int iFaces, const int piTriListIn[]
|
||||
return res;
|
||||
}
|
||||
|
||||
tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2)
|
||||
static tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2)
|
||||
{
|
||||
tbool bStillSame=TTRUE;
|
||||
int i=0;
|
||||
@ -1448,7 +1448,7 @@ tbool CompareSubGroups(const SSubGroup * pg1, const SSubGroup * pg2)
|
||||
return bStillSame;
|
||||
}
|
||||
|
||||
void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
|
||||
static void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
|
||||
{
|
||||
int iL, iR, n, index, iMid, iTmp;
|
||||
|
||||
@ -1492,10 +1492,10 @@ void QuickSort(int* pSortBuffer, int iLeft, int iRight, unsigned int uSeed)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed);
|
||||
void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in);
|
||||
static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed);
|
||||
static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in);
|
||||
|
||||
void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn)
|
||||
static void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriListIn[], const int iNrTrianglesIn)
|
||||
{
|
||||
// build array of edges
|
||||
unsigned int uSeed = INTERNAL_RND_SORT_SEED; // could replace with a random seed?
|
||||
@ -1590,7 +1590,7 @@ void BuildNeighborsFast(STriInfo pTriInfos[], SEdge * pEdges, const int piTriLis
|
||||
}
|
||||
}
|
||||
|
||||
void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn)
|
||||
static void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int iNrTrianglesIn)
|
||||
{
|
||||
int f=0, i=0;
|
||||
for(f=0; f<iNrTrianglesIn; f++)
|
||||
@ -1639,7 +1639,7 @@ void BuildNeighborsSlow(STriInfo pTriInfos[], const int piTriListIn[], const int
|
||||
}
|
||||
}
|
||||
|
||||
void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
|
||||
static void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channel, unsigned int uSeed)
|
||||
{
|
||||
unsigned int t;
|
||||
int iL, iR, n, index, iMid;
|
||||
@ -1696,7 +1696,7 @@ void QuickSortEdges(SEdge * pSortBuffer, int iLeft, int iRight, const int channe
|
||||
}
|
||||
|
||||
// resolve ordering and edge number
|
||||
void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in)
|
||||
static void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[], const int i0_in, const int i1_in)
|
||||
{
|
||||
*edgenum_out = -1;
|
||||
|
||||
@ -1730,7 +1730,7 @@ void GetEdge(int * i0_out, int * i1_out, int * edgenum_out, const int indices[],
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////// Degenerate triangles ////////////////////////////////////
|
||||
|
||||
void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris)
|
||||
static void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrianglesIn, const int iTotTris)
|
||||
{
|
||||
int iNextGoodTriangleSearchIndex=-1;
|
||||
tbool bStillFindingGoodOnes;
|
||||
@ -1813,7 +1813,7 @@ void DegenPrologue(STriInfo pTriInfos[], int piTriList_out[], const int iNrTrian
|
||||
assert(iNrTrianglesIn == t);
|
||||
}
|
||||
|
||||
void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris)
|
||||
static void DegenEpilogue(STSpace psTspace[], STriInfo pTriInfos[], int piTriListIn[], const SMikkTSpaceContext * pContext, const int iNrTrianglesIn, const int iTotTris)
|
||||
{
|
||||
int t=0, i=0;
|
||||
// deal with degenerate triangles
|
||||
|
@ -132,7 +132,7 @@ protected:
|
||||
uint32 mixBits( const uint32& u, const uint32& v ) const
|
||||
{ return hiBit(u) | loBits(v); }
|
||||
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
|
||||
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
|
||||
{ return m ^ (mixBits(s0,s1)>>1) ^ ((~loBit(s1) + 1) & 0x9908b0dfUL); }
|
||||
static uint32 hash( time_t t, clock_t c );
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ static inline dword STR_gHash(dword inDWord)
|
||||
key ^= (key >> 13);
|
||||
key += ~(key << 9);
|
||||
key ^= (key >> 17);
|
||||
return key;
|
||||
return key;
|
||||
}
|
||||
|
||||
enum { GOLDEN_RATIO = 0x9e3779b9 }; // arbitrary value to initialize hash funtion, well not so arbitrary
|
||||
|
@ -95,11 +95,11 @@ public:
|
||||
STR_String& Format(const char *fmt, ...); // Set formatted text to string
|
||||
STR_String& FormatAdd(const char *fmt, ...); // Add formatted text to string
|
||||
inline void Clear() { Len = pData[0] = 0; }
|
||||
inline const STR_String & Reverse()
|
||||
{
|
||||
for (int i1=0, i2=Len-1; i1<i2; i1++, i2--)
|
||||
swap(pData[i1], pData[i2]); return *this;
|
||||
}
|
||||
inline const STR_String & Reverse()
|
||||
{
|
||||
for (int i1=0, i2=Len-1; i1<i2; i1++, i2--)
|
||||
swap(pData[i1], pData[i2]); return *this;
|
||||
}
|
||||
|
||||
// Properties
|
||||
bool IsUpper() const;
|
||||
|
@ -1,6 +1,5 @@
|
||||
release/scripts/modules/rna_prop_ui.py
|
||||
|
||||
release/scripts/startup/bl_operators/animsys_update.py
|
||||
release/scripts/startup/bl_operators/object.py
|
||||
release/scripts/startup/bl_operators/object_align.py
|
||||
release/scripts/startup/bl_operators/object_quick_effects.py
|
||||
|
81
po/README.txt
Normal file
81
po/README.txt
Normal file
@ -0,0 +1,81 @@
|
||||
Blender translation HOWTO
|
||||
=========================
|
||||
|
||||
I'll try briefly explain how translation works and how to update translation files.
|
||||
|
||||
1. How it works
|
||||
---------------
|
||||
|
||||
This folder contains source files for translation system. This source files have
|
||||
got .po extension and they've got pretty simple syntax:
|
||||
|
||||
msgid "some message id"
|
||||
msgstr "translation for this message"
|
||||
|
||||
This means when string "some message id" is used as operator name, tooltip, menu
|
||||
and so it'll be displayed on the screen as "translation for this message".
|
||||
Pretty simple.
|
||||
|
||||
This source files are pre-compiled into ../relese/bin/.blender/locale/<language>/LC_MESSAGES/blender.mo,
|
||||
so they aren't getting compiled every time Blender is compiling to same some time and prevent
|
||||
failure on systems which doesn't have needed tools for compiling .po files.
|
||||
|
||||
2. How to update translations
|
||||
-----------------------------
|
||||
|
||||
It's also pretty simple. If you can find string you want to translate in <language>.po
|
||||
file as msgid, just write correct msgstr string for it. If msgid is marked as fuzzy,
|
||||
i.e.
|
||||
|
||||
#, fuzzy
|
||||
msgid "some message id"
|
||||
msgstr "translation for this message"
|
||||
|
||||
it means translation used to exist for this message, but message was changed, so translation
|
||||
also have to be updated (it's easier to make new translation based on previos translation).
|
||||
When translation was updated, remove line with '#, fuzzy' and it'll work.
|
||||
|
||||
If there's no message in .po file you want to translate, probably .po file should be updated.
|
||||
Use the following steps for this:
|
||||
- With newly compiled blender run:
|
||||
`blender --background --factory-startup --python update_msg.py`
|
||||
to update messages.txt file (this file contains strings collected
|
||||
automatically from RNA system and python UI scripts)
|
||||
- Run update_pot.py script which will update blender.pot file. This file contains all
|
||||
strings which should be transated.
|
||||
- Run update_po.py script to merge all .po files with blender.pot (so all .po files
|
||||
will contain all msgid-s declared in blender.pot) or update_po.py <language> to
|
||||
update only needed .po file(s) to save time when you're busy with translation.
|
||||
But before ocmmit all .po files better be updated.
|
||||
|
||||
When you've finished with translation, you should re-compile .po file into .mo file.
|
||||
It's also pretty simple: just run update_mo.py script to recompile all languages or
|
||||
just update_mo.py <language> to re-compile only needed language(s).
|
||||
|
||||
NOTE: msgfmt, msgmerge and xgettext tools should be available in your PATH.
|
||||
|
||||
This steps to update template, translation files and compile them can be made in "batch" mode
|
||||
using GNUMakefile:
|
||||
|
||||
make -f GNUMakefile translations
|
||||
|
||||
NOTE: Blender has to be compiled using GNUMakefile first.
|
||||
|
||||
|
||||
3. Note for Windows users
|
||||
-------------------------
|
||||
You can find compiled builds of gettext in the lib folder under "binaries\gettext\" for both windows and win64.
|
||||
In order to run the scripts you will need to replace the location of the GETTEXT_..._EXeCUTABLE.
|
||||
|
||||
For example in update_pot.py:
|
||||
-GETTEXT_XGETTEXT_EXECUTABLE = "xgettext"
|
||||
+GETTEXT_XGETTEXT_EXECUTABLE = "C:\\Blender\\lib\\\windows\\\binaries\\\gettext\\xgettext.exe"
|
||||
|
||||
4. Other scripts
|
||||
----------------
|
||||
|
||||
- check_po.py: this script checks if all messages declared in blender.pot exists in.po files
|
||||
and that no extra messages are declared in .po files
|
||||
- clean_po.py: this script removes all commented messages which aren't required by .pot file anymore.
|
||||
- merge_po.py: this scripts accepts two files as arguments and copies translations from second file
|
||||
into first file.
|
93
po/check_po.py
Executable file
93
po/check_po.py
Executable file
@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# update the pot file according the POTFILES.in
|
||||
|
||||
import os
|
||||
import sys
|
||||
from codecs import open
|
||||
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
|
||||
|
||||
|
||||
def read_messages(fname):
|
||||
def stripeol(s):
|
||||
return s.rstrip("\n\r")
|
||||
|
||||
messages = {}
|
||||
reading_message = False
|
||||
message = ""
|
||||
with open(fname, 'r', "utf-8") as handle:
|
||||
while True:
|
||||
line = handle.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
|
||||
line = stripeol(line)
|
||||
if line.startswith("msgid"):
|
||||
reading_message = True
|
||||
message = line[7:-1]
|
||||
elif line.startswith("msgstr"):
|
||||
reading_message = False
|
||||
messages[message] = True
|
||||
elif reading_message:
|
||||
message += line[1:-1]
|
||||
return messages
|
||||
|
||||
|
||||
def main():
|
||||
pot_messages = read_messages(FILE_NAME_POT)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for lang in sys.argv[1:]:
|
||||
po = os.path.join(CURRENT_DIR, lang + '.po')
|
||||
|
||||
if os.path.exists(po):
|
||||
po_messages = read_messages(po)
|
||||
for msgid in po_messages:
|
||||
if not pot_messages.get(msgid):
|
||||
print('Unneeded message id \'%s\'' % (msgid))
|
||||
|
||||
for msgid in pot_messages:
|
||||
if not po_messages.get(msgid):
|
||||
print('Missed message id \'%s\'' % (msgid))
|
||||
else:
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith('.po'):
|
||||
print('Processing %s...' % (po))
|
||||
po_messages = read_messages(po)
|
||||
for msgid in po_messages:
|
||||
if not pot_messages.get(msgid):
|
||||
print(' Unneeded message id \'%s\'' % (msgid))
|
||||
|
||||
for msgid in pot_messages:
|
||||
if not po_messages.get(msgid):
|
||||
print(' Missed message id \'%s\'' % (msgid))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n\n *** Running %r *** \n" % __file__)
|
||||
main()
|
190
po/clean_po.py
Executable file
190
po/clean_po.py
Executable file
@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# update the pot file according the POTFILES.in
|
||||
|
||||
import os
|
||||
import sys
|
||||
import collections
|
||||
|
||||
from codecs import open
|
||||
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
|
||||
|
||||
|
||||
def read_messages(fname):
|
||||
def stripeol(s):
|
||||
return s.rstrip("\n\r")
|
||||
|
||||
last_message = None
|
||||
|
||||
if hasattr(collections, 'OrderedDict'):
|
||||
messages = collections.OrderedDict()
|
||||
commented_messages = collections.OrderedDict()
|
||||
else:
|
||||
messages = {}
|
||||
commented_messages = {}
|
||||
|
||||
reading_message = False
|
||||
reading_translation = False
|
||||
commented = False
|
||||
message = ""
|
||||
translation = ""
|
||||
message_lines = []
|
||||
translation_lines = []
|
||||
comment_lines = []
|
||||
with open(fname, 'r', "utf-8") as handle:
|
||||
while True:
|
||||
line = handle.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
|
||||
line = stripeol(line)
|
||||
if line.startswith("msgid") or line.startswith("#~ msgid"):
|
||||
if reading_translation:
|
||||
last_message['translation'] = translation
|
||||
translation_lines = []
|
||||
|
||||
reading_message = True
|
||||
reading_translation = False
|
||||
|
||||
if line.startswith('#~'):
|
||||
message = line[10:-1]
|
||||
commented = True
|
||||
else:
|
||||
message = line[7:-1]
|
||||
commented = False
|
||||
|
||||
message_lines.append(message)
|
||||
elif line.startswith("msgstr") or line.startswith("#~ msgstr"):
|
||||
reading_message = False
|
||||
reading_translation = True
|
||||
last_message = {'comment_lines': comment_lines,
|
||||
'message_lines': message_lines,
|
||||
'translation_lines': translation_lines}
|
||||
|
||||
if commented:
|
||||
translation = line[11:-1]
|
||||
commented_messages[message] = last_message
|
||||
else:
|
||||
translation = line[8:-1]
|
||||
messages[message] = last_message
|
||||
|
||||
message_lines = []
|
||||
comment_lines = []
|
||||
translation_lines.append(translation)
|
||||
elif not line.startswith('"') and not line.startswith('#~ "'):
|
||||
if reading_translation:
|
||||
last_message['translation'] = translation
|
||||
else:
|
||||
comment_lines.append(line)
|
||||
|
||||
reading_message = False
|
||||
reading_translation = False
|
||||
message_lines = []
|
||||
translation_lines = []
|
||||
elif reading_message:
|
||||
if line.startswith('#~ "'):
|
||||
m = line[4:-1]
|
||||
else:
|
||||
m = line[1:-1]
|
||||
|
||||
message += m
|
||||
message_lines.append(m)
|
||||
elif reading_translation:
|
||||
if line.startswith('#~ "'):
|
||||
t = line[4:-1]
|
||||
else:
|
||||
t = line[1:-1]
|
||||
|
||||
translation += t
|
||||
translation_lines.append(t)
|
||||
|
||||
return (messages, commented_messages)
|
||||
|
||||
|
||||
def do_clean(po, pot_messages):
|
||||
po_messages, commented_messages = read_messages(po)
|
||||
|
||||
for msgid in commented_messages:
|
||||
if pot_messages.get(msgid):
|
||||
t = po_messages.get(msgid)
|
||||
if not t:
|
||||
print("Reusing full item from commented "
|
||||
"lines for msgid '%s'" % msgid)
|
||||
po_messages[msgid] = commented_messages[msgid]
|
||||
elif not t['translation']:
|
||||
print("Reusing translation from commented "
|
||||
"lines for msgid '%s'" % msgid)
|
||||
m = commented_messages[msgid]
|
||||
t['translation'] = m['translation']
|
||||
t['translation_lines'] = m['translation_lines']
|
||||
|
||||
with open(po, 'w', 'utf-8') as handle:
|
||||
for msgid in po_messages:
|
||||
item = po_messages[msgid]
|
||||
|
||||
for x in item['comment_lines']:
|
||||
handle.write(x + "\n")
|
||||
|
||||
first = True
|
||||
for x in item['message_lines']:
|
||||
if first:
|
||||
handle.write("msgid \"%s\"\n" % x)
|
||||
else:
|
||||
handle.write("\"%s\"\n" % x)
|
||||
first = False
|
||||
|
||||
first = True
|
||||
for x in item['translation_lines']:
|
||||
if first:
|
||||
handle.write("msgstr \"%s\"\n" % x)
|
||||
else:
|
||||
handle.write("\"%s\"\n" % x)
|
||||
first = False
|
||||
|
||||
handle.write("\n")
|
||||
|
||||
|
||||
def main():
|
||||
pot_messages, commented_messages = read_messages(FILE_NAME_POT)
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
for lang in sys.argv[1:]:
|
||||
po = os.path.join(CURRENT_DIR, lang + '.po')
|
||||
|
||||
if os.path.exists(po):
|
||||
do_clean(po, pot_messages)
|
||||
else:
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith('.po'):
|
||||
print('Processing %s...' % (po))
|
||||
do_clean(po, pot_messages)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n\n *** Running %r *** \n" % __file__)
|
||||
main()
|
167
po/merge_po.py
Executable file
167
po/merge_po.py
Executable file
@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# update the pot file according the POTFILES.in
|
||||
|
||||
import sys
|
||||
import collections
|
||||
|
||||
from codecs import open
|
||||
|
||||
|
||||
def read_messages(fname):
|
||||
def stripeol(s):
|
||||
return s.rstrip("\n\r")
|
||||
|
||||
last_message = None
|
||||
|
||||
if hasattr(collections, 'OrderedDict'):
|
||||
messages = collections.OrderedDict()
|
||||
commented_messages = collections.OrderedDict()
|
||||
else:
|
||||
messages = {}
|
||||
commented_messages = {}
|
||||
|
||||
reading_message = False
|
||||
reading_translation = False
|
||||
commented = False
|
||||
message = ""
|
||||
translation = ""
|
||||
message_lines = []
|
||||
translation_lines = []
|
||||
comment_lines = []
|
||||
with open(fname, 'r', "utf-8") as handle:
|
||||
while True:
|
||||
line = handle.readline()
|
||||
|
||||
if not line:
|
||||
break
|
||||
|
||||
line = stripeol(line)
|
||||
if line.startswith("msgid") or line.startswith("#~ msgid"):
|
||||
if reading_translation:
|
||||
last_message['translation'] = translation
|
||||
translation_lines = []
|
||||
|
||||
reading_message = True
|
||||
reading_translation = False
|
||||
|
||||
if line.startswith('#~'):
|
||||
message = line[10:-1]
|
||||
commented = True
|
||||
else:
|
||||
message = line[7:-1]
|
||||
commented = False
|
||||
|
||||
message_lines.append(message)
|
||||
elif line.startswith("msgstr") or line.startswith("#~ msgstr"):
|
||||
reading_message = False
|
||||
reading_translation = True
|
||||
last_message = {'comment_lines': comment_lines,
|
||||
'message_lines': message_lines,
|
||||
'translation_lines': translation_lines}
|
||||
|
||||
if commented:
|
||||
translation = line[11:-1]
|
||||
commented_messages[message] = last_message
|
||||
else:
|
||||
translation = line[8:-1]
|
||||
messages[message] = last_message
|
||||
|
||||
message_lines = []
|
||||
comment_lines = []
|
||||
translation_lines.append(translation)
|
||||
elif not line.startswith('"') and not line.startswith('#~ "'):
|
||||
if reading_translation:
|
||||
last_message['translation'] = translation
|
||||
else:
|
||||
comment_lines.append(line)
|
||||
|
||||
reading_message = False
|
||||
reading_translation = False
|
||||
message_lines = []
|
||||
translation_lines = []
|
||||
elif reading_message:
|
||||
if line.startswith('#~ "'):
|
||||
m = line[4:-1]
|
||||
else:
|
||||
m = line[1:-1]
|
||||
|
||||
message += m
|
||||
message_lines.append(m)
|
||||
elif reading_translation:
|
||||
if line.startswith('#~ "'):
|
||||
t = line[4:-1]
|
||||
else:
|
||||
t = line[1:-1]
|
||||
|
||||
translation += t
|
||||
translation_lines.append(t)
|
||||
|
||||
return (messages, commented_messages)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) == 3:
|
||||
dst_messages, tmp = read_messages(sys.argv[1])
|
||||
from_messages, tmp = read_messages(sys.argv[2])
|
||||
|
||||
for msgid in dst_messages:
|
||||
msg = dst_messages.get(msgid)
|
||||
from_msg = from_messages.get(msgid)
|
||||
|
||||
if from_msg and from_msg['translation']:
|
||||
msg['translation'] = from_msg['translation']
|
||||
msg['translation_lines'] = from_msg['translation_lines']
|
||||
|
||||
with open(sys.argv[1], 'w', 'utf-8') as handle:
|
||||
for msgid in dst_messages:
|
||||
item = dst_messages[msgid]
|
||||
|
||||
for x in item['comment_lines']:
|
||||
handle.write(x + "\n")
|
||||
|
||||
first = True
|
||||
for x in item['message_lines']:
|
||||
if first:
|
||||
handle.write("msgid \"%s\"\n" % x)
|
||||
else:
|
||||
handle.write("\"%s\"\n" % x)
|
||||
first = False
|
||||
|
||||
first = True
|
||||
for x in item['translation_lines']:
|
||||
if first:
|
||||
handle.write("msgstr \"%s\"\n" % x)
|
||||
else:
|
||||
handle.write("\"%s\"\n" % x)
|
||||
first = False
|
||||
|
||||
handle.write("\n")
|
||||
else:
|
||||
print('Usage: %s <destination-po> <source-po>' % (sys.argv[0]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n\n *** Running %r *** \n" % __file__)
|
||||
main()
|
5433
po/messages.txt
5433
po/messages.txt
File diff suppressed because it is too large
Load Diff
@ -25,29 +25,43 @@
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
CURRENT_DIR = os.path.dirname(__file__)
|
||||
GETTEXT_MSGFMT_EXECUTABLE = "msgfmt"
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, "..")))
|
||||
LOCALE_DIR = os.path.join(SOURCE_DIR, "release", "bin", ".blender", "locale")
|
||||
|
||||
DOMAIN = "blender"
|
||||
|
||||
|
||||
def main():
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith(".po"):
|
||||
lang = po[:-3]
|
||||
# show stats
|
||||
cmd = ("msgfmt",
|
||||
"--statistics",
|
||||
os.path.join(CURRENT_DIR, "%s.po" % lang),
|
||||
"-o",
|
||||
os.path.join(LOCALE_DIR, lang, "LC_MESSAGES", "%s.mo" % DOMAIN),
|
||||
)
|
||||
def process_po(po):
|
||||
lang = os.path.basename(po)[:-3]
|
||||
|
||||
print(" ".join(cmd))
|
||||
process = subprocess.Popen(cmd)
|
||||
process.wait()
|
||||
# show stats
|
||||
cmd = (GETTEXT_MSGFMT_EXECUTABLE,
|
||||
"--statistics",
|
||||
os.path.join(CURRENT_DIR, "%s.po" % lang),
|
||||
"-o",
|
||||
os.path.join(LOCALE_DIR, lang, "LC_MESSAGES", "%s.mo" % DOMAIN),
|
||||
)
|
||||
|
||||
print(" ".join(cmd))
|
||||
process = subprocess.Popen(cmd)
|
||||
process.wait()
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
for lang in sys.argv[1:]:
|
||||
po = os.path.join(CURRENT_DIR, lang + '.po')
|
||||
|
||||
if os.path.exists(po):
|
||||
process_po(po)
|
||||
else:
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith(".po"):
|
||||
process_po(po)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\n\n *** Running %r *** \n" % __file__)
|
||||
|
249
po/update_msg.py
249
po/update_msg.py
@ -17,7 +17,7 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
# <pep8-80 compliant>
|
||||
|
||||
# Write out messages.txt from blender
|
||||
|
||||
@ -26,67 +26,190 @@
|
||||
|
||||
import os
|
||||
|
||||
CURRENT_DIR = os.path.dirname(__file__)
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, "..")))
|
||||
|
||||
FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt")
|
||||
COMMENT_PREFIX = "#~ "
|
||||
|
||||
|
||||
def dump_messages_rna(messages):
|
||||
import bpy
|
||||
|
||||
def classBlackList():
|
||||
blacklist_rna_class = [
|
||||
# core classes
|
||||
"Context", "Event", "Function", "UILayout",
|
||||
"BlendData",
|
||||
# registerable classes
|
||||
"Panel", "Menu", "Header", "RenderEngine",
|
||||
"Operator", "OperatorMacro", "Macro",
|
||||
"KeyingSetInfo", "UnknownType",
|
||||
# window classes
|
||||
"WindowManager", "Window"
|
||||
]
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Collect internal operators
|
||||
|
||||
# extend with all internal operators
|
||||
# note that this uses internal api introspection functions
|
||||
# all possible operator names
|
||||
op_names = list(sorted(set(
|
||||
[cls.bl_rna.identifier for cls in
|
||||
bpy.types.OperatorProperties.__subclasses__()] +
|
||||
[cls.bl_rna.identifier for cls in
|
||||
bpy.types.Operator.__subclasses__()] +
|
||||
[cls.bl_rna.identifier for cls in
|
||||
bpy.types.OperatorMacro.__subclasses__()]
|
||||
)))
|
||||
|
||||
get_inatance = __import__("_bpy").ops.get_instance
|
||||
path_resolve = type(bpy.context).__base__.path_resolve
|
||||
for idname in op_names:
|
||||
op = get_inatance(idname)
|
||||
if 'INTERNAL' in path_resolve(op, "bl_options"):
|
||||
blacklist_rna_class.append(idname)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Collect builtin classes we dont need to doc
|
||||
blacklist_rna_class.append("Property")
|
||||
blacklist_rna_class.extend(
|
||||
[cls.__name__ for cls in
|
||||
bpy.types.Property.__subclasses__()])
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Collect classes which are attached to collections, these are api
|
||||
# access only.
|
||||
collection_props = set()
|
||||
for cls_id in dir(bpy.types):
|
||||
cls = getattr(bpy.types, cls_id)
|
||||
for prop in cls.bl_rna.properties:
|
||||
if prop.type == 'COLLECTION':
|
||||
prop_cls = prop.srna
|
||||
if prop_cls is not None:
|
||||
collection_props.add(prop_cls.identifier)
|
||||
blacklist_rna_class.extend(sorted(collection_props))
|
||||
|
||||
return blacklist_rna_class
|
||||
|
||||
blacklist_rna_class = classBlackList()
|
||||
|
||||
def filterRNA(bl_rna):
|
||||
id = bl_rna.identifier
|
||||
if id in blacklist_rna_class:
|
||||
print(" skipping", id)
|
||||
return True
|
||||
return False
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Function definitions
|
||||
|
||||
def walkProperties(properties):
|
||||
def walkProperties(bl_rna):
|
||||
import bpy
|
||||
for prop in properties:
|
||||
messages.add(prop.name)
|
||||
messages.add(prop.description)
|
||||
|
||||
# get our parents properties not to export them multiple times
|
||||
bl_rna_base = bl_rna.base
|
||||
if bl_rna_base:
|
||||
bl_rna_base_props = bl_rna_base.properties.values()
|
||||
else:
|
||||
bl_rna_base_props = ()
|
||||
|
||||
for prop in bl_rna.properties:
|
||||
# only write this property is our parent hasn't got it.
|
||||
if prop in bl_rna_base_props:
|
||||
continue
|
||||
if prop.identifier == "rna_type":
|
||||
continue
|
||||
|
||||
msgsrc = "bpy.types.%s.%s" % (bl_rna.identifier, prop.identifier)
|
||||
if prop.name and prop.name != prop.identifier:
|
||||
messages.setdefault(prop.name, []).append(msgsrc)
|
||||
if prop.description:
|
||||
messages.setdefault(prop.description, []).append(msgsrc)
|
||||
|
||||
if isinstance(prop, bpy.types.EnumProperty):
|
||||
for item in prop.enum_items:
|
||||
messages.add(item.name)
|
||||
messages.add(item.description)
|
||||
msgsrc = "bpy.types.%s.%s, '%s'" % (bl_rna.identifier,
|
||||
prop.identifier,
|
||||
item.identifier,
|
||||
)
|
||||
# Here identifier and name can be the same!
|
||||
if item.name: # and item.name != item.identifier:
|
||||
messages.setdefault(item.name, []).append(msgsrc)
|
||||
if item.description:
|
||||
messages.setdefault(item.description, []).append(msgsrc)
|
||||
|
||||
def walkRNA(bl_rna):
|
||||
|
||||
if filterRNA(bl_rna):
|
||||
return
|
||||
|
||||
msgsrc = "bpy.types.%s" % bl_rna.identifier
|
||||
|
||||
if bl_rna.name and bl_rna.name != bl_rna.identifier:
|
||||
messages.add(bl_rna.name)
|
||||
messages.setdefault(bl_rna.name, []).append(msgsrc)
|
||||
|
||||
if bl_rna.description:
|
||||
messages.add(bl_rna.description)
|
||||
messages.setdefault(bl_rna.description, []).append(msgsrc)
|
||||
|
||||
walkProperties(bl_rna.properties)
|
||||
if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
|
||||
messages.setdefault(bl_rna.bl_label, []).append(msgsrc)
|
||||
|
||||
walkProperties(bl_rna)
|
||||
|
||||
def walkClass(cls):
|
||||
walkRNA(cls.bl_rna)
|
||||
|
||||
def walk_keymap_hierarchy(hier):
|
||||
def walk_keymap_hierarchy(hier, msgsrc_prev):
|
||||
for lvl in hier:
|
||||
messages.add(lvl[0])
|
||||
msgsrc = "%s.%s" % (msgsrc_prev, lvl[1])
|
||||
messages.setdefault(lvl[0], []).append(msgsrc)
|
||||
|
||||
if lvl[3]:
|
||||
walk_keymap_hierarchy(lvl[3])
|
||||
walk_keymap_hierarchy(lvl[3], msgsrc)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Dump Messages
|
||||
|
||||
for cls in type(bpy.context).__base__.__subclasses__():
|
||||
def full_class_id(cls):
|
||||
""" gives us 'ID.Lamp.AreaLamp' which is best for sorting.
|
||||
"""
|
||||
cls_id = ""
|
||||
bl_rna = cls.bl_rna
|
||||
while bl_rna:
|
||||
cls_id = "%s.%s" % (bl_rna.identifier, cls_id)
|
||||
bl_rna = bl_rna.base
|
||||
return cls_id
|
||||
|
||||
cls_list = type(bpy.context).__base__.__subclasses__()
|
||||
cls_list.sort(key=full_class_id)
|
||||
for cls in cls_list:
|
||||
walkClass(cls)
|
||||
|
||||
for cls in bpy.types.Space.__subclasses__():
|
||||
cls_list = bpy.types.Space.__subclasses__()
|
||||
cls_list.sort(key=full_class_id)
|
||||
for cls in cls_list:
|
||||
walkClass(cls)
|
||||
|
||||
for cls in bpy.types.Operator.__subclasses__():
|
||||
cls_list = bpy.types.Operator.__subclasses__()
|
||||
cls_list.sort(key=full_class_id)
|
||||
for cls in cls_list:
|
||||
walkClass(cls)
|
||||
|
||||
from bl_ui.space_userpref_keymap import KM_HIERARCHY
|
||||
cls_list = bpy.types.OperatorProperties.__subclasses__()
|
||||
cls_list.sort(key=full_class_id)
|
||||
for cls in cls_list:
|
||||
walkClass(cls)
|
||||
|
||||
walk_keymap_hierarchy(KM_HIERARCHY)
|
||||
cls_list = bpy.types.Menu.__subclasses__()
|
||||
cls_list.sort(key=full_class_id)
|
||||
for cls in cls_list:
|
||||
walkClass(cls)
|
||||
|
||||
from bpy_extras.keyconfig_utils import KM_HIERARCHY
|
||||
|
||||
## XXX. what is this supposed to do, we wrote the file already???
|
||||
#_walkClass(bpy.types.SpaceDopeSheetEditor)
|
||||
walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
|
||||
|
||||
|
||||
def dump_messages_pytext(messages):
|
||||
@ -121,26 +244,30 @@ def dump_messages_pytext(messages):
|
||||
# -------------------------------------------------------------------------
|
||||
# Function definitions
|
||||
|
||||
def extract_strings(fp, node_container):
|
||||
def extract_strings(fp_rel, node_container):
|
||||
""" Recursively get strings, needed incase we have "Blah" + "Blah",
|
||||
passed as an argument in that case it wont evaluate to a string.
|
||||
"""
|
||||
|
||||
for node in ast.walk(node_container):
|
||||
if type(node) == ast.Str:
|
||||
eval_str = ast.literal_eval(node)
|
||||
if eval_str:
|
||||
# print("%s:%d: %s" % (fp, node.lineno, eval_str)) # testing
|
||||
messages.add(eval_str)
|
||||
# print("%s:%d: %s" % (fp, node.lineno, eval_str))
|
||||
msgsrc = "%s:%s" % (fp_rel, node.lineno)
|
||||
messages.setdefault(eval_str, []).append(msgsrc)
|
||||
|
||||
def extract_strings_from_file(fn):
|
||||
filedata = open(fn, 'r', encoding="utf8")
|
||||
root_node = ast.parse(filedata.read(), fn, 'exec')
|
||||
def extract_strings_from_file(fp):
|
||||
filedata = open(fp, 'r', encoding="utf8")
|
||||
root_node = ast.parse(filedata.read(), fp, 'exec')
|
||||
filedata.close()
|
||||
|
||||
fp_rel = os.path.relpath(fp, SOURCE_DIR)
|
||||
|
||||
for node in ast.walk(root_node):
|
||||
if type(node) == ast.Call:
|
||||
# print("found function at")
|
||||
# print("%s:%d" % (fn, node.lineno))
|
||||
# print("%s:%d" % (fp, node.lineno))
|
||||
|
||||
# lambda's
|
||||
if type(node.func) == ast.Name:
|
||||
@ -155,29 +282,60 @@ def dump_messages_pytext(messages):
|
||||
# do nothing if not found
|
||||
for arg_kw, arg_pos in translate_args:
|
||||
if arg_pos < len(node.args):
|
||||
extract_strings(fn, node.args[arg_pos])
|
||||
extract_strings(fp_rel, node.args[arg_pos])
|
||||
else:
|
||||
for kw in node.keywords:
|
||||
if kw.arg == arg_kw:
|
||||
extract_strings(fn, kw.value)
|
||||
extract_strings(fp_rel, kw.value)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Dump Messages
|
||||
|
||||
mod_dir = os.path.join(SOURCE_DIR, "release", "scripts", "startup", "bl_ui")
|
||||
mod_dir = os.path.join(SOURCE_DIR,
|
||||
"release",
|
||||
"scripts",
|
||||
"startup",
|
||||
"bl_ui")
|
||||
|
||||
files = [os.path.join(mod_dir, f)
|
||||
for f in os.listdir(mod_dir)
|
||||
if not f.startswith("_")
|
||||
if f.endswith("py")
|
||||
files = [os.path.join(mod_dir, fn)
|
||||
for fn in sorted(os.listdir(mod_dir))
|
||||
if not fn.startswith("_")
|
||||
if fn.endswith("py")
|
||||
]
|
||||
|
||||
for fn in files:
|
||||
extract_strings_from_file(fn)
|
||||
for fp in files:
|
||||
extract_strings_from_file(fp)
|
||||
|
||||
|
||||
def dump_messages():
|
||||
messages = {""}
|
||||
|
||||
def filter_message(msg):
|
||||
|
||||
# check for strings like ": %d"
|
||||
msg_test = msg
|
||||
for ignore in ("%d", "%s", "%r", # string formatting
|
||||
"*", ".", "(", ")", "-", "/", "\\", "+", ":", "#", "%"
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"x", # used on its own eg: 100x200
|
||||
"X", "Y", "Z", # used alone. no need to include
|
||||
):
|
||||
msg_test = msg_test.replace(ignore, "")
|
||||
msg_test = msg_test.strip()
|
||||
if not msg_test:
|
||||
# print("Skipping: '%s'" % msg)
|
||||
return True
|
||||
|
||||
# we could filter out different strings here
|
||||
|
||||
return False
|
||||
|
||||
if 1:
|
||||
import collections
|
||||
messages = collections.OrderedDict()
|
||||
else:
|
||||
messages = {}
|
||||
|
||||
messages[""] = []
|
||||
|
||||
# get strings from RNA
|
||||
dump_messages_rna(messages)
|
||||
@ -185,10 +343,21 @@ def dump_messages():
|
||||
# get strings from UI layout definitions text="..." args
|
||||
dump_messages_pytext(messages)
|
||||
|
||||
messages.remove("")
|
||||
del messages[""]
|
||||
|
||||
message_file = open(FILE_NAME_MESSAGES, 'w', encoding="utf8")
|
||||
message_file.writelines("\n".join(sorted(messages)))
|
||||
# message_file.writelines("\n".join(sorted(messages)))
|
||||
|
||||
for key, value in messages.items():
|
||||
|
||||
# filter out junk values
|
||||
if filter_message(key):
|
||||
continue
|
||||
|
||||
for msgsrc in value:
|
||||
message_file.write("%s%s\n" % (COMMENT_PREFIX, msgsrc))
|
||||
message_file.write("%s\n" % key)
|
||||
|
||||
message_file.close()
|
||||
|
||||
print("Written %d messages to: %r" % (len(messages), FILE_NAME_MESSAGES))
|
||||
|
@ -25,27 +25,41 @@
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
CURRENT_DIR = os.path.dirname(__file__)
|
||||
GETTEXT_MSGMERGE_EXECUTABLE = "msgmerge"
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
DOMAIN = "blender"
|
||||
|
||||
|
||||
def process_po(po):
|
||||
lang = os.path.basename(po)[:-3]
|
||||
|
||||
# update po file
|
||||
cmd = (GETTEXT_MSGMERGE_EXECUTABLE,
|
||||
"--update",
|
||||
"--backup=none",
|
||||
"--lang=%s" % lang,
|
||||
os.path.join(CURRENT_DIR, "%s.po" % lang),
|
||||
os.path.join(CURRENT_DIR, "%s.pot" % DOMAIN),
|
||||
)
|
||||
|
||||
print(" ".join(cmd))
|
||||
process = subprocess.Popen(cmd)
|
||||
process.wait()
|
||||
|
||||
|
||||
def main():
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith(".po"):
|
||||
lang = po[:-3]
|
||||
if len(sys.argv) > 1:
|
||||
for lang in sys.argv[1:]:
|
||||
po = os.path.join(CURRENT_DIR, lang + '.po')
|
||||
|
||||
# update po file
|
||||
cmd = ("msgmerge",
|
||||
"--update",
|
||||
"--lang=%s" % lang,
|
||||
os.path.join(CURRENT_DIR, "%s.po" % lang),
|
||||
os.path.join(CURRENT_DIR, "%s.pot" % DOMAIN),
|
||||
)
|
||||
|
||||
print(" ".join(cmd))
|
||||
process = subprocess.Popen(cmd)
|
||||
process.wait()
|
||||
if os.path.exists(po):
|
||||
process_po(po)
|
||||
else:
|
||||
for po in os.listdir(CURRENT_DIR):
|
||||
if po.endswith(".po"):
|
||||
process_po(po)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -25,11 +25,13 @@
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
from codecs import open
|
||||
|
||||
GETTEXT_XGETTEXT_EXECUTABLE = "xgettext"
|
||||
CURRENT_DIR = os.path.dirname(__file__)
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, "..")))
|
||||
DOMAIN = "blender"
|
||||
COMMENT_PREFIX = "#~ " # from update_msg.py
|
||||
|
||||
FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot")
|
||||
FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt")
|
||||
@ -55,7 +57,7 @@ def main():
|
||||
pot_messages = {}
|
||||
reading_message = False
|
||||
message = ""
|
||||
with open(FILE_NAME_POT, 'r') as handle:
|
||||
with open(FILE_NAME_POT, 'r', "utf-8") as handle:
|
||||
while True:
|
||||
line = handle.readline()
|
||||
|
||||
@ -73,8 +75,9 @@ def main():
|
||||
message += line[1:-1]
|
||||
|
||||
# add messages collected automatically from RNA
|
||||
with open(FILE_NAME_POT, "a") as pot_handle:
|
||||
with open(FILE_NAME_MESSAGES, 'r') as handle:
|
||||
with open(FILE_NAME_POT, "a", "utf-8") as pot_handle:
|
||||
with open(FILE_NAME_MESSAGES, 'r', "utf-8") as handle:
|
||||
msgsrc_ls = []
|
||||
while True:
|
||||
line = handle.readline()
|
||||
|
||||
@ -82,13 +85,21 @@ def main():
|
||||
break
|
||||
|
||||
line = stripeol(line)
|
||||
line = line.replace("\\", "\\\\")
|
||||
line = line.replace("\"", "\\\"")
|
||||
|
||||
if not pot_messages.get(line):
|
||||
pot_handle.write("\n#: Automatically collected from RNA\n")
|
||||
pot_handle.write("msgid \"%s\"\n" % (line))
|
||||
pot_handle.write("msgstr \"\"\n")
|
||||
# COMMENT_PREFIX
|
||||
if line.startswith(COMMENT_PREFIX):
|
||||
msgsrc_ls.append(line[len(COMMENT_PREFIX):].strip())
|
||||
else:
|
||||
line = line.replace("\\", "\\\\")
|
||||
line = line.replace("\"", "\\\"")
|
||||
line = line.replace("\t", "\\t")
|
||||
|
||||
if not pot_messages.get(line):
|
||||
for msgsrc in msgsrc_ls:
|
||||
pot_handle.write("#: %s\n" % msgsrc)
|
||||
pot_handle.write("msgid \"%s\"\n" % line)
|
||||
pot_handle.write("msgstr \"\"\n\n")
|
||||
msgsrc_ls[:] = []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1,24 +0,0 @@
|
||||
English:en_US
|
||||
Japanese:ja_JP
|
||||
Dutch:nl_NL
|
||||
Italian:it_IT
|
||||
German:de_DE
|
||||
Finnish:fi_FI
|
||||
Swedish:sv_SE
|
||||
French:fr_FR
|
||||
Spanish:es_ES
|
||||
Catalan:ca_ES
|
||||
Czech:cs_CZ
|
||||
Brazilian Portuguese:pt_BR
|
||||
Simplified Chinese:zh_CN
|
||||
Traditional Chinese:zh_TW
|
||||
Russian:ru_RU
|
||||
Croatian:hr_HR
|
||||
Serbian:sr_RS
|
||||
Ukrainian:uk_UA
|
||||
Polish:pl_PL
|
||||
Romanian:ro_RO
|
||||
Arabic:ar_SA
|
||||
Bulgarian:bg_BG
|
||||
Greek:el_GR
|
||||
Korean:ko_KR
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user