diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-12-14 20:32:24 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2008-12-14 20:32:24 +0300 |
commit | ec00764dd2349f723ba22b45515ec34ee81edcc3 (patch) | |
tree | cf506e71af7172ec63b89aa3d284fab27a2085e6 | |
parent | 131fa2e00c35ff78042a4f793891eaeb880d715c (diff) | |
parent | 8449f0d77640c466acbda7d6ceeb71bc48317b44 (diff) |
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17434:HEAD
82 files changed, 2457 insertions, 475 deletions
diff --git a/SConstruct b/SConstruct index bf5356a4073..6cd89671bd9 100644 --- a/SConstruct +++ b/SConstruct @@ -249,7 +249,7 @@ if len(B.quickdebug) > 0 and printdebug != 0: # remove stdc++ from LLIBS if we are building a statc linked CXXFLAGS if env['WITH_BF_STATICCXX']: if 'stdc++' in env['LLIBS']: - env['LLIBS'] = env['LLIBS'].replace('stdc++', ' ') + env['LLIBS'].remove('stdc++') else: print '\tcould not remove stdc++ library from LLIBS, WITH_BF_STATICCXX may not work for your platform' @@ -425,8 +425,18 @@ if env['OURPLATFORM']!='darwin': dn.remove('CVS') if '.svn' in dn: dn.remove('.svn') + for f in df: - dotblendlist.append(dp+os.sep+f) + if not env['WITH_BF_INTERNATIONAL']: + if 'locale' in dp: + continue + if f == '.Blanguages': + continue + if not env['WITH_BF_FREETYPE']: + if f.endswith('.ttf'): + continue + + dotblendlist.append(os.path.join(dp, f)) dottargetlist.append(env['BF_INSTALLDIR']+dp[3:]+os.sep+f) dotblenderinstall = [] @@ -434,16 +444,17 @@ if env['OURPLATFORM']!='darwin': td, tf = os.path.split(targetdir) dotblenderinstall.append(env.Install(dir=td, source=srcfile)) - #-- .blender/scripts - scriptpath='release/scripts' - for dp, dn, df in os.walk(scriptpath): - if 'CVS' in dn: - dn.remove('CVS') - if '.svn' in dn: - dn.remove('.svn') - dir=env['BF_INSTALLDIR']+'/.blender/scripts'+dp[len(scriptpath):] - source=[dp+os.sep+f for f in df] - scriptinstall.append(env.Install(dir=dir,source=source)) + if env['WITH_BF_PYTHON']: + #-- .blender/scripts + scriptpath='release/scripts' + for dp, dn, df in os.walk(scriptpath): + if 'CVS' in dn: + dn.remove('CVS') + if '.svn' in dn: + dn.remove('.svn') + dir=env['BF_INSTALLDIR']+'/.blender/scripts'+dp[len(scriptpath):] + source=[dp+os.sep+f for f in df] + scriptinstall.append(env.Install(dir=dir,source=source)) #-- icons if env['OURPLATFORM']=='linux2': @@ -465,6 +476,13 @@ if env['OURPLATFORM']=='linux2': td, tf = os.path.split(targetdir) iconinstall.append(env.Install(dir=td, source=srcfile)) +# dlls for linuxcross +# TODO - add more libs, for now this lets blenderlite run +if env['OURPLATFORM']=='linuxcross': + dir=env['BF_INSTALLDIR'] + source = ['../lib/windows/pthreads/lib/pthreadGC2.dll'] + scriptinstall.append(env.Install(dir=dir, source=source)) + #-- plugins pluglist = [] plugtargetlist = [] diff --git a/config/darwin-config.py b/config/darwin-config.py index 7c118b78861..3ef7b7132d9 100644 --- a/config/darwin-config.py +++ b/config/darwin-config.py @@ -216,14 +216,14 @@ CXXFLAGS = [ '-pipe','-fPIC','-funsigned-char', '-fpascal-strings'] PLATFORM_LINKFLAGS = '-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime' #note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4 -LLIBS = 'stdc++ SystemStubs' +LLIBS = ['stdc++', 'SystemStubs'] # some flags shuffling for different Os versions if MAC_MIN_VERS == '10.3': CFLAGS = ['-fuse-cxa-atexit']+CFLAGS CXXFLAGS = ['-fuse-cxa-atexit']+CXXFLAGS PLATFORM_LINKFLAGS = '-fuse-cxa-atexit '+PLATFORM_LINKFLAGS - LLIBS = LLIBS + ' crt3.o' + LLIBS.append('crt3.o') if USE_SDK==True: SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS] @@ -261,6 +261,7 @@ CC_WARN = ['-Wall', '-Wno-long-double'] ##DYNLDFLAGS = -shared $(LDFLAGS) BF_PROFILE_CCFLAGS = ['-pg', '-g '] +BF_PROFILE_LINKFLAGS = ['-pg'] BF_PROFILE = False BF_DEBUG = False diff --git a/config/irix6-config.py b/config/irix6-config.py new file mode 100644 index 00000000000..b643affb0b3 --- /dev/null +++ b/config/irix6-config.py @@ -0,0 +1,231 @@ +import os + +LCGDIR = os.getcwd()+"/../lib/irix-6.5-mips" +LIBDIR = LCGDIR +print LCGDIR + +WITH_BF_VERSE = 'false' +BF_VERSE_INCLUDE = "#extern/verse/dist" + +BF_PYTHON = LCGDIR+'/python' +BF_PYTHON_VERSION = '2.5' +WITH_BF_STATICPYTHON = 'true' +BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' +BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' +BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}' #BF_PYTHON+'/lib/python'+BF_PYTHON_VERSION+'/config/libpython'+BF_PYTHON_VERSION+'.a' +BF_PYTHON_LINKFLAGS = ['-Xlinker', '-export-dynamic'] +BF_PYTHON_LIB_STATIC = '${BF_PYTHON}/lib/python2.5/config/libpython${BF_PYTHON_VERSION}.a' + +WITH_BF_OPENAL = 'true' +WITH_BF_STATICOPENAL = 'true' +BF_OPENAL = LCGDIR+'/openal' +BF_OPENAL_INC = '${BF_OPENAL}/include' +BF_OPENAL_LIB = 'openal' +BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' +BF_OPENAL_LIBPATH = LIBDIR + '/lib' + +# some distros have a separate libalut +# if you get linker complaints, you need to uncomment the line below +# BF_OPENAL_LIB = 'openal alut' +# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a' + +BF_CXX = '/usr' +WITH_BF_STATICCXX = 'false' +BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' + +WITH_BF_SDL = 'true' +BF_SDL = LCGDIR+'/SDL' #$(shell sdl-config --prefix) +BF_SDL_INC = '${BF_SDL}/include/SDL' #$(shell $(BF_SDL)/bin/sdl-config --cflags) +BF_SDL_LIB = 'SDL audio iconv charset' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer +BF_SDL_LIBPATH = '${BF_SDL}/lib' + +WITH_BF_FMOD = 'false' +BF_FMOD = LIBDIR + '/fmod' + +WITH_BF_OPENEXR = 'false' +WITH_BF_STATICOPENEXR = 'false' +BF_OPENEXR = '/usr' +# when compiling with your own openexr lib you might need to set... +# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include' + +BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR' +BF_OPENEXR_LIB = 'Half IlmImf Iex Imath ' +BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a' +# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib' + + +WITH_BF_DDS = 'false' + +WITH_BF_JPEG = 'false' +BF_JPEG = LCGDIR+'/jpeg' +BF_JPEG_INC = '${BF_JPEG}/include' +BF_JPEG_LIB = 'jpeg' +BF_JPEG_LIBPATH = '${BF_JPEG}/lib' + +WITH_BF_PNG = 'false' +BF_PNG = LCGDIR+"/png" +BF_PNG_INC = '${BF_PNG}/include' +BF_PNG_LIB = 'png' +BF_PNG_LIBPATH = '${BF_PNG}/lib' + +BF_TIFF = '/usr/nekoware' +BF_TIFF_INC = '${BF_TIFF}/include' + +WITH_BF_ZLIB = 'true' +BF_ZLIB = LCGDIR+"/zlib" +BF_ZLIB_INC = '${BF_ZLIB}/include' +BF_ZLIB_LIB = 'z' +BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib' + +WITH_BF_INTERNATIONAL = 'true' + +BF_GETTEXT = LCGDIR+'/gettext' +BF_GETTEXT_INC = '${BF_GETTEXT}/include' +BF_GETTEXT_LIB = 'gettextpo intl' +BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' + +WITH_BF_FTGL = 'true' +BF_FTGL = '#extern/bFTGL' +BF_FTGL_INC = '${BF_FTGL}/include' +BF_FTGL_LIB = 'extern_ftgl' + +WITH_BF_GAMEENGINE='false' + +WITH_BF_ODE = 'false' +BF_ODE = LIBDIR + '/ode' +BF_ODE_INC = BF_ODE + '/include' +BF_ODE_LIB = BF_ODE + '/lib/libode.a' + +WITH_BF_BULLET = 'true' +BF_BULLET = '#extern/bullet2/src' +BF_BULLET_INC = '${BF_BULLET}' +BF_BULLET_LIB = 'extern_bullet' + +BF_SOLID = '#extern/solid' +BF_SOLID_INC = '${BF_SOLID}' +BF_SOLID_LIB = 'extern_solid' + +WITH_BF_YAFRAY = 'true' + +#WITH_BF_NSPR = 'true' +#BF_NSPR = $(LIBDIR)/nspr +#BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr +#BF_NSPR_LIB = + +# Uncomment the following line to use Mozilla inplace of netscape +#CPPFLAGS += -DMOZ_NOT_NET +# Location of MOZILLA/Netscape header files... +#BF_MOZILLA = $(LIBDIR)/mozilla +#BF_MOZILLA_INC = -I$(BF_MOZILLA)/include/mozilla/nspr -I$(BF_MOZILLA)/include/mozilla -I$(BF_MOZILLA)/include/mozilla/xpcom -I$(BF_MOZILLA)/include/mozilla/idl +#BF_MOZILLA_LIB = +# Will fall back to look in BF_MOZILLA_INC/nspr and BF_MOZILLA_LIB +# if this is not set. +# +# Be paranoid regarding library creation (do not update archives) +#BF_PARANOID = 'true' + +# enable freetype2 support for text objects +BF_FREETYPE = LCGDIR+'/freetype' +BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2' +BF_FREETYPE_LIB = 'freetype' +BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib' + +WITH_BF_QUICKTIME = 'false' # -DWITH_QUICKTIME +BF_QUICKTIME = '/usr/local' +BF_QUICKTIME_INC = '${BF_QUICKTIME}/include' + +WITH_BF_ICONV = 'true' +BF_ICONV = LIBDIR + "/iconv" +BF_ICONV_INC = '${BF_ICONV}/include' +BF_ICONV_LIB = 'iconv charset' +BF_ICONV_LIBPATH = '${BF_ICONV}/lib' + +WITH_BF_BINRELOC = 'false' + +# enable ffmpeg support +WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG +# Uncomment the following two lines to use system's ffmpeg +BF_FFMPEG = LCGDIR+'/ffmpeg' +BF_FFMPEG_LIB = 'avformat avcodec swscale avutil faad faac vorbis x264 ogg mp3lame z' +BF_FFMPEG_INC = '${BF_FFMPEG}/include' +BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib' + +# enable ogg, vorbis and theora in ffmpeg +WITH_BF_OGG = 'false' # -DWITH_OGG +BF_OGG = '/usr' +BF_OGG_INC = '${BF_OGG}/include' +BF_OGG_LIB = 'ogg vorbis theoraenc theoradec' + +WITH_BF_OPENJPEG = 'false' +BF_OPENJPEG = '#extern/libopenjpeg' +BF_OPENJPEG_LIB = '' +BF_OPENJPEG_INC = '${BF_OPENJPEG}/include' +BF_OPENJPEG_LIBPATH='${BF_OPENJPEG}/lib' + +WITH_BF_REDCODE = 'false' +BF_REDCODE = '#extern/libredcode' +BF_REDCODE_LIB = '' +BF_REDCODE_INC = '${BF_REDCODE}/include' +BF_REDCODE_LIBPATH='${BF_REDCODE}/lib' + +# Mesa Libs should go here if your using them as well.... +WITH_BF_STATICOPENGL = 'false' +BF_OPENGL = '/usr' +BF_OPENGL_INC = '${BF_OPENGL}/include' +BF_OPENGL_LIB = 'GL GLU X11 Xi Xext' +BF_OPENGL_LIBPATH = '/usr/X11R6/lib' +BF_OPENGL_LIB_STATIC = '${BF_OPENGL}/libGL.a ${BF_OPENGL}/libGLU.a ${BF_OPENGL}/libXxf86vm.a ${BF_OPENGL}/libX11.a ${BF_OPENGL}/libXi.a ${BF_OPENGL}/libXext.a ${BF_OPENGL}/libXxf86vm.a' + + +CC = 'c99' +CXX = 'CC' + + +CCFLAGS = ['-pipe','-fPIC', '-n32'] + +CPPFLAGS = ['-DXP_UNIX'] +CXXFLAGS = ['-pipe','-fPIC', '-n32'] +REL_CFLAGS = ['-O2'] +REL_CCFLAGS = ['-O2'] +##BF_DEPEND = 'true' +## +##AR = ar +##ARFLAGS = ruv +##ARFLAGSQUIET = ru +## +C_WARN = '-no_prelink -ptused' + +CC_WARN = '-no_prelink -ptused' + +##FIX_STUBS_WARNINGS = -Wno-unused + +LLIBS = 'c m dl pthread dmedia movie' +##LOPTS = --dynamic +##DYNLDFLAGS = -shared $(LDFLAGS) + +BF_PROFILE_FLAGS = ['-pg','-g'] +BF_PROFILE = 'false' + +BF_DEBUG = 'false' +BF_DEBUG_FLAGS = '-g' + +BF_BUILDDIR = '../build/irix6' +BF_INSTALLDIR='../install/irix6' +BF_DOCDIR='../install/doc' + +#Link against pthread +LDIRS = [] +LDIRS.append(BF_FREETYPE_LIBPATH) +LDIRS.append(BF_PNG_LIBPATH) +LDIRS.append(BF_ZLIB_LIBPATH) +LDIRS.append(BF_SDL_LIBPATH) +LDIRS.append(BF_OPENAL_LIBPATH) +LDIRS.append(BF_ICONV_LIBPATH) + +PLATFORM_LINKFLAGS = [] +for x in LDIRS: + PLATFORM_LINKFLAGS.append("-L"+x) + +PLATFORM_LINKFLAGS += ['-L${LCGDIR}/jpeg/lib' , '-L/usr/lib32', '-n32', '-v', '-no_prelink'] +print PLATFORM_LINKFLAGS +LINKFLAGS= PLATFORM_LINKFLAGS diff --git a/config/linux2-config.py b/config/linux2-config.py index 19b62dd2395..2984c06d2df 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -193,12 +193,13 @@ CC_WARN = ['-Wall'] ##FIX_STUBS_WARNINGS = -Wno-unused -LLIBS = 'util c m dl pthread stdc++' +LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++'] ##LOPTS = --dynamic ##DYNLDFLAGS = -shared $(LDFLAGS) BF_PROFILE = False BF_PROFILE_CCFLAGS = ['-pg','-g'] +BF_PROFILE_LINKFLAGS = ['-pg'] BF_DEBUG = False BF_DEBUG_CCFLAGS = ['-g'] diff --git a/config/linuxcross-config.py b/config/linuxcross-config.py index 4c5f4859a6c..5981c8b96e5 100644 --- a/config/linuxcross-config.py +++ b/config/linuxcross-config.py @@ -1,4 +1,4 @@ -LCGDIR = '../lib/windows' +LCGDIR = '#../lib/windows' LIBDIR = '${LCGDIR}' WITH_BF_VERSE = False @@ -101,6 +101,9 @@ BF_SOLID = '#extern/solid' BF_SOLID_INC = '${BF_SOLID}' BF_SOLID_LIB = 'extern_solid' +BF_WINTAB = LIBDIR + '/wintab' +BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE' + # enable freetype2 support for text objects BF_FREETYPE = LIBDIR + '/gcc/freetype' BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2' @@ -146,6 +149,10 @@ LLIBS = [ '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lw BF_DEBUG = False BF_DEBUG_CCFLAGS= [] +BF_PROFILE = False +BF_PROFILE_CCFLAGS = ['-pg','-g'] +BF_PROFILE_LINKFLAGS = ['-pg'] + BF_BUILDDIR = '../build/linuxcross' BF_INSTALLDIR='../install/linuxcross' BF_DOCDIR='../install/doc' diff --git a/config/openbsd3-config.py b/config/openbsd3-config.py index cd46d11867e..8fc334874f9 100644 --- a/config/openbsd3-config.py +++ b/config/openbsd3-config.py @@ -151,12 +151,13 @@ CC_WARN = ['-Wall'] ##FIX_STUBS_WARNINGS = -Wno-unused -LLIBS = 'm stdc++ pthread util' +LLIBS = ['m', 'stdc++', 'pthread', 'util'] ##LOPTS = --dynamic ##DYNLDFLAGS = -shared $(LDFLAGS) -BF_PROFILE_CCFLAGS = ['-pg', '-g'] BF_PROFILE = False +BF_PROFILE_CCFLAGS = ['-pg','-g'] +BF_PROFILE_LINKFLAGS = ['-pg'] BF_DEBUG = False BF_DEBUG_CCFLAGS = ['-g'] diff --git a/config/sunos5-config.py b/config/sunos5-config.py index 4e7e99bc884..a44a9df7c75 100644 --- a/config/sunos5-config.py +++ b/config/sunos5-config.py @@ -165,11 +165,12 @@ CC_WARN = ['-Wall'] ##FIX_STUBS_WARNINGS = -Wno-unused -LLIBS = 'c m dl pthread stdc++' +LLIBS = ['c', 'm', 'dl', 'pthread', 'stdc++'] ##LOPTS = --dynamic ##DYNLDFLAGS = -shared $(LDFLAGS) -BF_PROFILE_CCFLAGS = ['-pg','-g'] +BF_PROFILE_CCFLAGS = ['-pg', '-g '] +BF_PROFILE_LINKFLAGS = ['-pg'] BF_PROFILE = False BF_DEBUG = False diff --git a/config/win32-mingw-config.py b/config/win32-mingw-config.py index 6483b215182..e9e9aac1589 100644 --- a/config/win32-mingw-config.py +++ b/config/win32-mingw-config.py @@ -164,7 +164,8 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32 BF_DEBUG = False BF_DEBUG_CCFLAGS= ['-g'] -BF_PROFILE_CCFLAGS = ['-pg','-g'] +BF_PROFILE_CCFLAGS = ['-pg', '-g '] +BF_PROFILE_LINKFLAGS = ['-pg'] BF_PROFILE_FLAGS = BF_PROFILE_CCFLAGS BF_PROFILE = False diff --git a/config/win32-vc-config.py b/config/win32-vc-config.py index f6f97f5e982..8ba8c8f04e6 100644 --- a/config/win32-vc-config.py +++ b/config/win32-vc-config.py @@ -181,10 +181,15 @@ C_WARN = [] CC_WARN = [] CXX_WARN = [] -LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid' +LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid'] PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/ENTRY:mainCRTStartup','/INCREMENTAL:NO','/NODEFAULTLIB:"msvcprt.lib"','/NODEFAULTLIB:"glut32.lib"','/NODEFAULTLIB:"libc.lib"','/NODEFAULTLIB:"libcd.lib"','/NODEFAULTLIB:"libcpd.lib"','/NODEFAULTLIB:"libcp.lib"','/LARGEADDRESSAWARE'] +# # Todo +# BF_PROFILE_CCFLAGS = ['-pg', '-g '] +# BF_PROFILE_LINKFLAGS = ['-pg'] +# BF_PROFILE = False + BF_BUILDDIR = '..\\build\\win32-vc' BF_INSTALLDIR='..\\install\\win32-vc' BF_DOCDIR='..\\install\\doc' diff --git a/extern/Makefile b/extern/Makefile index 26ee25b608f..51213698ebb 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -57,10 +57,7 @@ ifeq ($(WITH_BINRELOC), true) DIRS += binreloc endif -TARGET = -ifneq ($(OS),irix) - TARGET=solid -endif +TARGET = solid all:: @[ -d $(OCGDIR)/extern ] || mkdir -p $(OCGDIR)/extern diff --git a/intern/SoundSystem/Makefile b/intern/SoundSystem/Makefile index d00339f351c..051e2643a87 100644 --- a/intern/SoundSystem/Makefile +++ b/intern/SoundSystem/Makefile @@ -47,6 +47,9 @@ ifneq ($(NAN_NO_OPENAL),true) ifeq ($(OS),$(findstring $(OS), "linux freebsd solaris")) DIRS += openal sdl endif + ifeq ($(OS), irix) + DIRS += sdl + endif else export CPPFLAGS += -DNO_SOUND endif diff --git a/intern/elbeem/intern/utilities.h b/intern/elbeem/intern/utilities.h index 825e92251fe..a5f63e696a6 100644 --- a/intern/elbeem/intern/utilities.h +++ b/intern/elbeem/intern/utilities.h @@ -154,12 +154,18 @@ int writePng(const char *fileName, unsigned char **rowsp, int w, int h); */ /* minimum */ +#ifdef MIN +#undef MIN +#endif template < class T > inline T MIN( T a, T b ) { return (a < b) ? a : b ; } /* maximum */ +#ifdef MAX +#undef MAX +#endif template < class T > inline T MAX( T a, T b ) diff --git a/projectfiles_vc9/blender/blender.sln b/projectfiles_vc9/blender/blender.sln index 647e60674e0..cc4c2d46416 100644 --- a/projectfiles_vc9/blender/blender.sln +++ b/projectfiles_vc9/blender/blender.sln @@ -154,6 +154,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenderplayer", "..\gameeng {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292}
{670EC17A-0548-4BBF-A27B-636C7C188139} = {670EC17A-0548-4BBF-A27B-636C7C188139}
{4C3AB78A-52CA-4276-A041-39776E52D8C8} = {4C3AB78A-52CA-4276-A041-39776E52D8C8}
+ {E784098D-3ED8-433A-9353-9679415DDDC5} = {E784098D-3ED8-433A-9353-9679415DDDC5}
{6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC}
{CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}
{76D90B92-ECC7-409C-9F98-A8814B90F3C0} = {76D90B92-ECC7-409C-9F98-A8814B90F3C0}
@@ -170,13 +171,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blenderplayer", "..\gameeng {E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358}
{8B8D4FC3-3234-4E54-8376-5AB83D00D164} = {8B8D4FC3-3234-4E54-8376-5AB83D00D164}
{4B6AFCC5-968C-424A-8F20-76E41B3BEF74} = {4B6AFCC5-968C-424A-8F20-76E41B3BEF74}
+ {0112CAD5-3584-412A-A2E5-1315A00437B4} = {0112CAD5-3584-412A-A2E5-1315A00437B4}
{5A2EA6DC-1A53-4E87-9166-52870CE3B4EA} = {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}
{E86B7BDE-C33C-4E55-9433-E74C141D7538} = {E86B7BDE-C33C-4E55-9433-E74C141D7538}
{32CC75E2-EE85-45E6-8E3D-513F58464F43} = {32CC75E2-EE85-45E6-8E3D-513F58464F43}
{9A307EE5-CD77-47BC-BD87-62508C7E19D8} = {9A307EE5-CD77-47BC-BD87-62508C7E19D8}
{AB590CED-F71F-4A17-A89B-18583ECD633D} = {AB590CED-F71F-4A17-A89B-18583ECD633D}
+ {B83C6BED-11EC-46C8-AFFA-121EEDE94373} = {B83C6BED-11EC-46C8-AFFA-121EEDE94373}
{1CC733F1-6AB5-4904-8F63-C08C46B79DD9} = {1CC733F1-6AB5-4904-8F63-C08C46B79DD9}
{B789C2F3-279E-4A85-8F0A-7F7AC068E598} = {B789C2F3-279E-4A85-8F0A-7F7AC068E598}
+ {524264F4-DF21-4B79-847F-E7CA643ECD0B} = {524264F4-DF21-4B79-847F-E7CA643ECD0B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KX_blenderhook", "..\gameengine\blenderhook\KX_blenderhook.vcproj", "{8154A59A-CAED-403D-AB94-BC4E7C032666}"
@@ -944,7 +948,9 @@ Global {0112CAD5-3584-412A-A2E5-1315A00437B4}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.Blender Release|Win32.Build.0 = Blender Release|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32
{0112CAD5-3584-412A-A2E5-1315A00437B4}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32
@@ -958,7 +964,9 @@ Global {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Release|Win32.Build.0 = Blender Release|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32
{B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32
@@ -972,7 +980,9 @@ Global {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Release|Win32.Build.0 = Blender Release|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32
{524264F4-DF21-4B79-847F-E7CA643ECD0B}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32
@@ -1048,6 +1058,7 @@ Global {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Blender Release|Win32.Build.0 = Blender Release|Win32
{6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32
{6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
{6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
{6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32
@@ -1105,7 +1116,9 @@ Global {E784098D-3ED8-433A-9353-9679415DDDC5}.Blender Release|Win32.ActiveCfg = Blender Release|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.Blender Release|Win32.Build.0 = Blender Release|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32
+ {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32
+ {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.Debug|Win32.ActiveCfg = 3DPlugin Debug|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.Debug|Win32.Build.0 = 3DPlugin Debug|Win32
{E784098D-3ED8-433A-9353-9679415DDDC5}.Release|Win32.ActiveCfg = 3DPlugin Release|Win32
diff --git a/projectfiles_vc9/blender/nodes/nodes.vcproj b/projectfiles_vc9/blender/nodes/nodes.vcproj index ba1617a525b..b5f60bedc31 100644 --- a/projectfiles_vc9/blender/nodes/nodes.vcproj +++ b/projectfiles_vc9/blender/nodes/nodes.vcproj @@ -617,10 +617,18 @@ >
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_coord.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_curves.c"
>
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_distance.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_hueSatVal.c"
>
</File>
diff --git a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj index 43e692e9bad..ab0b05c208c 100644 --- a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj +++ b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj @@ -72,12 +72,12 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386
"
- AdditionalDependencies="odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
+ AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
ShowProgress="0"
OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\build\msvc_9\libs\intern\debug;..\..\..\..\..\build\msvc_9\libs\extern\debug;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"
+ AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"
IgnoreDefaultLibraryNames="libc.lib;libcmt.lib;msvcrt.lib;libcd.lib;msvcrtd.lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\debug\blenderplayer.pdb"
@@ -166,11 +166,11 @@ <Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="odelib.lib fmodvc.lib libbmfont.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
+ AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
OutputFile="..\..\..\..\bin\blenderplayer.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\build\msvc_9\libs\intern;..\..\..\..\..\build\msvc_9\libs\extern;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"
+ AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"
IgnoreDefaultLibraryNames="libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib"
ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\blenderplayer.pdb"
SubSystem="1"
diff --git a/release/Makefile b/release/Makefile index f440e2dface..43a369d8f77 100644 --- a/release/Makefile +++ b/release/Makefile @@ -57,6 +57,12 @@ ifeq ($(OS),$(findstring $(OS), "freebsd irix linux openbsd solaris")) NOPLUGINS?=true endif endif + # don"t build plugins on irix if using gcc + ifeq ($(OS), irix) + ifeq ($(IRIX_USE_GCC), true) + NOPLUGINS?=true + endif + endif endif ifeq ($(OS),windows) diff --git a/release/scripts/bpymodules/BPyImage.py b/release/scripts/bpymodules/BPyImage.py index 2c342ddec39..504e4ee29ba 100644 --- a/release/scripts/bpymodules/BPyImage.py +++ b/release/scripts/bpymodules/BPyImage.py @@ -79,7 +79,7 @@ def addSlash(path): return path + sys.sep -def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False): +def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False, CONVERT_CALLBACK=None): ''' imagePath: The image filename If a path precedes it, this will be searched as well. @@ -93,13 +93,30 @@ def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=Tr RECURSIVE: If True, directories will be recursivly searched. Be carefull with this if you have files in your root directory because it may take a long time. + + CASE_INSENSITIVE: for non win32 systems, find the correct case for the file. + + CONVERT_CALLBACK: a function that takes an existing path and returns a new one. + Use this when loading image formats blender may not support, the CONVERT_CALLBACK + can take the path for a GIF (for example), convert it to a PNG and return the PNG's path. + For formats blender can read, simply return the path that is given. ''' + # VERBOSE = True + if VERBOSE: print 'img:', imagePath, 'file:', filePath + + if os == None and CASE_INSENSITIVE: + CASE_INSENSITIVE = True + # When we have the file load it with this. try/except niceness. def imageLoad(path): #if path.endswith('\\') or path.endswith('/'): # raise 'INVALID PATH' + + if CONVERT_CALLBACK: + path = CONVERT_CALLBACK(path) + try: img = bpy.data.images.new(filename=path) if VERBOSE: print '\t\tImage loaded "%s"' % path diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py index 27736b4169e..bfa1dcc3c61 100644 --- a/release/scripts/bpymodules/BPyMathutils.py +++ b/release/scripts/bpymodules/BPyMathutils.py @@ -225,15 +225,5 @@ from math import pi, sin, cos, sqrt def angleToLength(angle): # Alredy accounted for - if angle < 0.000001: - return 1.0 - - angle = 2*pi*angle/360 - x,y = cos(angle), sin(angle) - # print "YX", x,y - # 0 d is hoz to the right. - # 90d is vert upward. - fac=1/x - x=x*fac - y=y*fac - return sqrt((x*x)+(y*y)) + if angle < 0.000001: return 1.0 + else: return abs(1.0 / cos(pi*angle/180)); diff --git a/release/scripts/bpymodules/BPySys.py b/release/scripts/bpymodules/BPySys.py index 594264fad84..a2d2120ebff 100644 --- a/release/scripts/bpymodules/BPySys.py +++ b/release/scripts/bpymodules/BPySys.py @@ -12,3 +12,63 @@ def cleanName(name): for ch in invalid: name = name.replace(ch, '_') return name +def caseInsensitivePath(path, RET_FOUND=False): + ''' + Get a case insensitive path on a case sensitive system + + RET_FOUND is for internal use only, to avoid too many calls to os.path.exists + # Example usage + getCaseInsensitivePath('/hOmE/mE/sOmEpAtH.tXt') + ''' + import os # todo, what happens with no os? + + if os==None: + if RET_FOUND: ret = path, True + else: ret = path + return ret + + if path=='' or os.path.exists(path): + if RET_FOUND: ret = path, True + else: ret = path + return ret + + f = os.path.basename(path) # f may be a directory or a file + d = os.path.dirname(path) + + suffix = '' + if not f: # dir ends with a slash? + if len(d) < len(path): + suffix = path[:len(path)-len(d)] + + f = os.path.basename(d) + d = os.path.dirname(d) + + if not os.path.exists(d): + d, found = caseInsensitivePath(d, True) + + if not found: + if RET_FOUND: ret = path, False + else: ret = path + return ret + + # at this point, the directory exists but not the file + + try: # we are expecting 'd' to be a directory, but it could be a file + files = os.listdir(d) + except: + if RET_FOUND: ret = path, False + else: ret = path + + f_low = f.lower() + + try: f_nocase = [fl for fl in files if fl.lower() == f_low][0] + except: f_nocase = None + + if f_nocase: + if RET_FOUND: ret = os.path.join(d, f_nocase) + suffix, True + else: ret = os.path.join(d, f_nocase) + suffix + return ret + else: + if RET_FOUND: ret = path, False + else: ret = path + return ret # cant find the right one, just return the path as is.
\ No newline at end of file diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py index 3f02a71f951..ce17f78c5e2 100644 --- a/release/scripts/export_fbx.py +++ b/release/scripts/export_fbx.py @@ -66,8 +66,6 @@ import BPyMesh import BPySys import BPyMessages -import sys - ## This was used to make V, but faster not to do all that ##valid = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_,.()[]{}' ##v = range(255) @@ -184,7 +182,19 @@ def sane_texname(data): return sane_name(data, sane_name_mapping_tex) def sane_takename(data): return sane_name(data, sane_name_mapping_take) def sane_groupname(data): return sane_name(data, sane_name_mapping_group) - +def derived_paths(fname_orig, basepath, FORCE_CWD=False): + ''' + fname_orig - blender path, can be relative + basepath - fname_rel will be relative to this + FORCE_CWD - dont use the basepath, just add a ./ to the filename. + use when we know the file will be in the basepath. + ''' + fname = Blender.sys.expandpath(fname_orig) + fname_strip = strip_path(fname) + if FORCE_CWD: fname_rel = '.' + Blender.sys.sep + fname_strip + else: fname_rel = Blender.sys.relpath(fname, basepath) + if fname_rel.startswith('//'): fname_rel = '.' + Blender.sys.sep + fname_rel[2:] + return fname, fname_strip, fname_rel def mat4x4str(mat): @@ -342,6 +352,8 @@ def write(filename, batch_objects = None, \ # end batch support + # Use this for working out paths relative to the export location + basepath = Blender.sys.dirname(filename) # ---------------------------------------------- # storage classes @@ -1141,10 +1153,9 @@ def write(filename, batch_objects = None, \ Property: "Width", "int", "",0 Property: "Height", "int", "",0''') if tex: - fname = tex.filename - fname_strip = strip_path(fname) + fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: - fname = fname_strip = '' + fname = fname_strip = fname_rel = '' file.write('\n\t\t\tProperty: "Path", "charptr", "", "%s"' % fname_strip) @@ -1163,7 +1174,7 @@ def write(filename, batch_objects = None, \ file.write('\n\t\tFilename: "%s"' % fname_strip) if fname_strip: fname_strip = '/' + fname_strip - file.write('\n\t\tRelativeFilename: "fbx%s"' % fname_strip) # make relative + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # make relative file.write('\n\t}') @@ -1202,13 +1213,14 @@ def write(filename, batch_objects = None, \ }''') file.write('\n\t\tMedia: "Video::%s"' % texname) + if tex: - fname = tex.filename - file.write('\n\t\tFileName: "%s"' % strip_path(fname)) - file.write('\n\t\tRelativeFilename: "fbx/%s"' % strip_path(fname)) # need some make relative command + fname, fname_strip, fname_rel = derived_paths(tex.filename, basepath, EXP_IMAGE_COPY) else: - file.write('\n\t\tFileName: ""') - file.write('\n\t\tRelativeFilename: "fbx"') + fname = fname_strip = fname_rel = '' + + file.write('\n\t\tFileName: "%s"' % fname_strip) + file.write('\n\t\tRelativeFilename: "%s"' % fname_rel) # need some make relative command file.write(''' ModelUVTranslation: 0,0 @@ -2658,7 +2670,7 @@ Takes: {''') # copy images if enabled if EXP_IMAGE_COPY: - copy_images( Blender.sys.dirname(filename), [ tex[1] for tex in textures if tex[1] != None ]) + copy_images( basepath, [ tex[1] for tex in textures if tex[1] != None ]) print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time) return True diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py index bb0119a9a81..6a1981bb262 100644 --- a/release/scripts/import_dxf.py +++ b/release/scripts/import_dxf.py @@ -7,7 +7,7 @@ Group: 'Import' Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).' """ __author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)' -__version__ = '1.12 - 2008.08.03 by migius' +__version__ = '1.12 - 2008.11.16 by migius' __url__ = ["http://blenderartists.org/forum/showthread.php?t=84319", "http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"] __email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"] @@ -111,6 +111,9 @@ History: -- support ortho mode for VIEWs and VPORTs as cameras + v1.12 - 2008.11.16 by migius + d1 remove try_finally: cause not supported in python <2.5 + d1 add Bezier curves bevel radius support (default 1.0) v1.12 - 2008.08.03 by migius c2 warningfix: relocating of globals: layersmap, oblist c2 modif UI: buttons newScene+targetLayer moved to start panel @@ -299,7 +302,7 @@ History: import Blender from Blender import * #from Blender.Mathutils import Vector, Matrix -import bpy +#import bpy #not used yet #import BPyMessages from dxfReader import readDXF @@ -311,7 +314,7 @@ from math import * try: import os - if os.name:# != 'mac': + if os.name != 'mac': import psyco psyco.log(Blender.Get('tempdir')+"/blender.log-psyco") #psyco.log() @@ -320,7 +323,7 @@ try: psyco.profile(0.2) #print 'psyco imported' except ImportError: - #print 'psyco not imported' + print 'psyco not imported' pass #try: Curve.orderU @@ -346,7 +349,7 @@ THIN_RESOLUTION = 8 #(4-64) thin_cylinder arc_resolution - number of segments MIN_THICK = MIN_DIST * 10.0 #minimal thickness by forced thickness MIN_WIDTH = MIN_DIST * 10.0 #minimal width by forced width TRIM_LIMIT = 3.0 #limit for triming of polylines-wide-segments (values:0.0 - 5.0) -ELEVATION = 0.0 #standard elevation = coordinate Z +ELEVATION = 0.0 #standard elevation = coordinate Z value BYBLOCK = 0 BYLAYER = 256 @@ -817,6 +820,7 @@ class Line: #----------------------------------------------------------------- curve.append(BezTriple.New(points[1])) for point in curve: point.handleTypes = [VECT, VECT] + point.radius = 1.0 curve.flagU = 0 # 0 sets the curve not cyclic=open c.setResolu(settings.var['curve_res']) c.update() #important for handles calculation @@ -1341,9 +1345,11 @@ class Polyline: #-------------------------------------------------------------- nurbs_points.append(pkt) firstpoint = nurbs_points[0] curve = pline.appendNurb(firstpoint) - curve.setType(4) # set curvetype NURBS + curve.setType(4) # set curve_type NURBS + print 'deb: dir(curve):', dir(curve[-1]) #---------------- for point in nurbs_points[1:]: curve.append(point) + #TODO: what is the trick for bevel radius? curve[-1].radius = 1.0 if self.closed: curve.flagU = 1+0 # Set curve cyclic=close and uni else: @@ -1359,6 +1365,7 @@ class Polyline: #-------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [AUTO, AUTO] + point.radius = 1.0 if self.closed: curve.flagU = 1 # Set curve cyclic=close else: @@ -1380,6 +1387,7 @@ class Polyline: #-------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [AUTO, AUTO] + point.radius = 1.0 #curve.setType(1) #Bezier curve if self.closed: curve.flagU = 5 #1 # Set curve cyclic=close @@ -1392,6 +1400,7 @@ class Polyline: #-------------------------------------------------------------- p0h1 = [p0h1[i]+begtangent[i] for i in range(3)] curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2)) curve[0].handleTypes = [FREE, ALIGN] #remi--todo----- + curve[0].radius = 1.0 if endtangent: #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #----- #print 'deb:polyline2dCurve.draw endtangent:', endtangent #----- @@ -1401,6 +1410,7 @@ class Polyline: #-------------------------------------------------------------- curve.__setitem__(-1,BezTriple.New(p0h1+p0+p0h2)) #print 'deb:polyline2dCurve.draw curve[-1].vec:', curve[-1].vec #----- curve[-1].handleTypes = [ALIGN, FREE] #remi--todo----- + curve[-1].radius = 1.0 @@ -1420,13 +1430,16 @@ class Polyline: #-------------------------------------------------------------- if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0])) else: curve.append(BezTriple.New(verts[0])) curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents + curve[-1].radius = 1.0 for p in verts[1:]: curve.append(BezTriple.New(p)) curve[-1].handleTypes = [AUTO, AUTO] + curve[-1].radius = 1.0 else: if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc)) else: curve.append(BezTriple.New(point1.loc)) curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents + curve[-1].radius = 1.0 elif True: #----- optimised Bezier-Handles calculation -------------------------------- #print 'deb:drawPlineCurve: i:', i #--------- @@ -1446,10 +1459,12 @@ class Polyline: #-------------------------------------------------------------- if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0])) else: curve.append(BezTriple.New(VectorTriples[0])) curve[-1].handleTypes = [prevHandleType, FREE] + curve[-1].radius = 1.0 for p in VectorTriples[1:-1]: curve.append(BezTriple.New(p)) curve[-1].handleTypes = [FREE, FREE] + curve[-1].radius = 1.0 prevHandleVect = VectorTriples[-1][:3] prevHandleType = FREE @@ -1462,11 +1477,13 @@ class Polyline: #-------------------------------------------------------------- curve.append(BezTriple.New(VectorTriples)) curve[-1].handleTypes = [FREE, VECT] prevHandleType = VECT + curve[-1].radius = 1.0 else: if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc)) else: curve.append(BezTriple.New(point1.loc)) curve[-1].handleTypes = [VECT, VECT] - + curve[-1].radius = 1.0 + #print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #---------- @@ -1486,10 +1503,12 @@ class Polyline: #-------------------------------------------------------------- curve.__setitem__(0,BezTriple.New(p0h1+p0+p0h2)) curve[0].handleTypes = [FREE,prevHandleType2] + curve[0].radius = 1.0 #print 'deb:drawPlineCurve:closed curve[0].vec:', curve[0].vec #---------- #print 'deb:drawPlineCurve:closed curve[0].handleTypes:', curve[0].handleTypes #---------- else: curve[0].handleTypes[0] = VECT + curve[0].radius = 1.0 else: curve.flagU = 0 # Set curve not cyclic=open @@ -2177,9 +2196,10 @@ DXF: X value; APP: 3D point, Y and Z values of control points (in WCS) (one entr self.ctrlpk_len = getit(obj, 73, 0) # Number of control points self.fit_pk_len = getit(obj, 74, 0) # Number of fit points (if any) + #TODO: import SPLINE as Bezier curve directly, possible? #print 'deb:Spline self.fit_pk_len=', self.fit_pk_len #------------------------ #self.fit_pk_len = 0 # temp for debug - if self.fit_pk_len and 'spline_as'==5: + if self.fit_pk_len and settings.var['splines_as']==5: self.spline = False self.curved = True else: @@ -2675,6 +2695,7 @@ class Circle: #---------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [FREE, FREE] + point.radius = 1.0 else: # standard version c = Curve.New(obname) # create new curve data p1 = (0, -radius, 0) @@ -2693,6 +2714,7 @@ class Circle: #---------------------------------------------------------------- curve.append(p4) for point in curve: point.handleTypes = [AUTO, AUTO] + point.radius = 1.0 curve.flagU = 1 # 1 sets the curve cyclic=closed if settings.var['fill_on']: @@ -2893,6 +2915,7 @@ class Arc: #----------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [FREE, FREE] + point.radius = 1.0 curve.flagU = 0 # 0 sets the curve not cyclic=open arc.setResolu(settings.var['curve_res']) @@ -3449,6 +3472,7 @@ class Ellipse: #--------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [FREE, FREE] + point.radius = 1.0 curve.flagU = 1 # 0 sets the curve not cyclic=open if settings.var['fill_on']: arc.setFlag(6) # 2+4 set top and button caps @@ -3459,6 +3483,7 @@ class Ellipse: #--------------------------------------------------------------- curve.append(BezTriple.New(p)) for point in curve: point.handleTypes = [FREE, FREE] + point.radius = 1.0 curve.flagU = 0 # 0 sets the curve not cyclic=open arc.setResolu(settings.var['curve_res']) @@ -4397,8 +4422,7 @@ def analyzeDXF(dxfFile): #--------------------------------------- Draw.PupMenu('DXF importer: report saved in INF-file:%t|' + '\'%s\'' %infFile) except: Draw.PupMenu('DXF importer: ERROR by writing report in INF-file:%t|' + '\'%s\'' %infFile) - finally: - f.close() + #finally: f.close() @@ -4417,7 +4441,8 @@ def main(dxfFile): #---------------#############################----------- global cur_COUNTER #counter for progress_bar cur_COUNTER = 0 - try: + #try: + if 1: #print "Getting settings..." global GUI_A, GUI_B, g_scale_as if not GUI_A['g_scale_on'].val: @@ -4500,7 +4525,7 @@ def main(dxfFile): #---------------#############################----------- #settings.write(message) if UI_MODE: Draw.PupMenu('DXF importer: Done!|finished in %.4f sec.' % time_text) - finally: + #finally: # restore state even if things didn't work #print 'deb:drawEntities finally!' #----------------------- Window.WaitCursor(False) @@ -5190,6 +5215,7 @@ def drawCurveCircle(circle): #--- no more used -------------------------------- curve.append(p4) for point in curve: point.handleTypes = [AUTO, AUTO] + point.radius = 1.0 curve.flagU = 1 # Set curve cyclic c.update() @@ -5231,6 +5257,7 @@ def drawCurveArc(self): #---- only for ELLIPSE -------------------------------- curve.append(p4) for point in curve: point.handleTypes = [AUTO, AUTO] + point.radius = 1.0 curve.flagU = 1 # Set curve cyclic a.update() @@ -5270,12 +5297,12 @@ GUI_B = {} # GUI-buttons dictionary for drawingTypes # settings default, initialize ------------------------ points_as_menu = "convert to: %t|empty %x1|mesh.vertex %x2|thin sphere %x3|thin box %x4|*curve.vertex %x5" -lines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|thin box %x4|Bezier-curve %x5|NURBS-curve %x6" +lines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|thin box %x4|Bezier-curve %x5|*NURBS-curve %x6" mlines_as_menu = "convert to: %t|*edge %x1|*mesh %x2|*thin cylinder %x3|*thin box %x|*curve %x5" plines_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6" -splines_as_menu = "convert to: %t|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6" +splines_as_menu = "convert to: %t|mesh %x2|*thin cylinder %x3|*thin box %x4|*Bezier-curve %x5|NURBS-curve %x6" plines3_as_menu = "convert to: %t|*edge %x1|mesh %x2|*thin cylinder %x3|*thin box %x4|Bezier-curve %x5|NURBS-curve %x6" -plmesh_as_menu = "convert to: %t|*edge %x1|mesh %x2|NURBS-surface %x6" +plmesh_as_menu = "convert to: %t|*edge %x1|mesh %x2|*NURBS-surface %x6" solids_as_menu = "convert to: %t|*edge %x1|mesh %x2" blocks_as_menu = "convert to: %t|dupliGroup %x1|*real.Group %x2|*exploded %x3" texts_as_menu = "convert to: %t|text %x1|*mesh %x2|*curve %x5" @@ -5456,11 +5483,9 @@ def saveConfig(): #--todo----------------------------------------------- else: #if BPyMessages.Warning_SaveOver(iniFile): #<- remi find it too abstarct if sys.exists(iniFile): - try: - f = file(iniFile, 'r') - try: header_str = f.readline() - finally: f.close() - except: pass + f = file(iniFile, 'r') + header_str = f.readline() + f.close() if header_str.startswith(INIFILE_HEADER[0:13]): if Draw.PupMenu(' OK ? %t|SAVE OVER: ' + '\'%s\'' %iniFile) == 1: save_ok = True @@ -5480,10 +5505,9 @@ def saveConfig(): #--todo----------------------------------------------- output_str = '{\n'.join(output_str.split('{')) try: f = file(iniFile, 'w') - try: - f.write(INIFILE_HEADER + '\n# this is a comment line\n') - f.write(output_str) - finally: f.close() + f.write(INIFILE_HEADER + '\n# this is a comment line\n') + f.write(output_str) + f.close() #Draw.PupMenu('DXF importer: INI-file: Done!%t|config-data saved in ' + '\'%s\'' %iniFile) except: Draw.PupMenu('DXF importer: INI-file: Error!%t|failure by writing to ' + '\'%s\'|no config-data saved!' %iniFile) @@ -5508,25 +5532,22 @@ def loadConfig(): #remi--todo----------------------------------------------- update_RegistryKey('iniFileName', iniFile) #print 'deb:loadConfig iniFile: ', iniFile #---------------------- if iniFile.lower().endswith(INIFILE_EXTENSION) and sys.exists(iniFile): - try: - f = file(iniFile, 'r') - try: - header_str = f.readline() - if header_str.startswith(INIFILE_HEADER): - data_str = f.read() - f.close() - #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #----------------- - data = eval(data_str) - for k, v in data[0].iteritems(): - try: GUI_A[k].val = v - except: GUI_A[k] = Draw.Create(v) - for k, v in data[1].iteritems(): - try: GUI_B[k].val = v - except: GUI_B[k] = Draw.Create(v) - else: - Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile) - finally: f.close() - except: pass + f = file(iniFile, 'r') + header_str = f.readline() + if header_str.startswith(INIFILE_HEADER): + data_str = f.read() + f.close() + #print 'deb:loadConfig data_str from %s: \n' %iniFile , data_str #----------------- + data = eval(data_str) + for k, v in data[0].iteritems(): + try: GUI_A[k].val = v + except: GUI_A[k] = Draw.Create(v) + for k, v in data[1].iteritems(): + try: GUI_B[k].val = v + except: GUI_B[k] = Draw.Create(v) + else: + f.close() + Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid header in INI-file: ' + '\'%s\'' %iniFile) else: Draw.PupMenu('DXF importer: INI-file: Alert!%t|no valid INI-file selected!') print "DXF importer: Alert!: no valid INI-file selected." diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py index 9447f15fb79..06cde898ef2 100755 --- a/release/scripts/import_web3d.py +++ b/release/scripts/import_web3d.py @@ -48,6 +48,27 @@ def baseName(path): def dirName(path): return path[:-len(baseName(path))] +def imageConvertCompat(path): + + try: import os + except: + return path + + if path.endswith('.gif'): + path_to = path[:-3] + 'png' + + ''' + if exists(path_to): + return path_to + ''' + # print '\n'+path+'\n'+path_to+'\n' + os.system('convert "%s" "%s"' % (path, path_to)) # for now just hope we have image magick + + if exists(path_to): + return path_to + + return path + # notes # transform are relative # order dosnt matter for loc/size/rot @@ -78,6 +99,7 @@ def vrmlFormat(data): return l # Most cases accounted for! if we have a comment at the end of the line do this... + #j = l.find('url "') j = l.find('"') if j == -1: # simple no strings @@ -96,7 +118,40 @@ def vrmlFormat(data): data = '\n'.join([strip_comment(l) for l in data.split('\n') ]) # remove all whitespace + EXTRACT_STRINGS = True # only needed when strings or filesnames containe ,[]{} chars :/ + + if EXTRACT_STRINGS: + + # We need this so we can detect URL's + data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace + string_ls = [] + + #search = 'url "' + search = '"' + + ok = True + last_i = 0 + while ok: + ok = False + i = data.find(search, last_i) + if i != -1: + + start = i + len(search) # first char after end of search + end = data.find('"', start) + if end != -1: + item = data[start:end] + string_ls.append( item ) + data = data[:start] + data[end:] + ok = True # keep looking + + last_i = end - len(item) + 1 + # print last_i, item, '|' + data[last_i] + '|' + + # done with messy extracting strings part + + + # Bad, dont take strings into account ''' data = data.replace('#', '\n#') @@ -108,6 +163,27 @@ def vrmlFormat(data): data = data.replace(']', '\n]\n') data = data.replace(',', ' , ') # make sure comma's seperate + if EXTRACT_STRINGS: + # add strings back in + + search = '"' # fill in these empty strings + + ok = True + last_i = 0 + while ok: + ok = False + i = data.find(search + '"', last_i) + + if i != -1: + start = i + len(search) # first char after end of search + item = string_ls.pop(0) + data = data[:start] + item + data[start:] + + last_i = start + len(item) + + ok = True + + # More annoying obscure cases where USE or DEF are placed on a newline # data = data.replace('\nDEF ', ' DEF ') # data = data.replace('\nUSE ', ' USE ') @@ -199,21 +275,46 @@ def is_numline(i): ''' Does this line start with a number? ''' + + # Works but too slow. + ''' l = lines[i] + for w in l.split(): + if w==',': + pass + else: + try: + float(w) + return True + + except: + return False + + return False + ''' + + l = lines[i] + + line_start = 0 + + if l.startswith(', '): + line_start += 2 + line_end = len(l)-1 - line_end_new = l.find(' ') # comma's always have a space before them + line_end_new = l.find(' ', line_start) # comma's always have a space before them if line_end_new != -1: line_end = line_end_new try: - float(l[:line_end]) # works for a float or int + float(l[line_start:line_end]) # works for a float or int return True except: return False + class vrmlNode(object): - __slots__ = 'id', 'fields', 'node_type', 'parent', 'children', 'parent', 'array_data', 'reference', 'lineno', 'filename', 'blendObject', 'DEF_NAMESPACE', 'FIELD_NAMESPACE', 'x3dNode' + __slots__ = 'id', 'fields', 'node_type', 'parent', 'children', 'parent', 'array_data', 'reference', 'lineno', 'filename', 'blendObject', 'DEF_NAMESPACE', 'ROUTE_IPO_NAMESPACE', 'FIELD_NAMESPACE', 'x3dNode' def __init__(self, parent, node_type, lineno): self.id = None self.node_type = node_type @@ -231,6 +332,7 @@ class vrmlNode(object): # Store in the root node because each inline file needs its own root node and its own namespace self.DEF_NAMESPACE = None + self.ROUTE_IPO_NAMESPACE = None self.FIELD_NAMESPACE = None self.reference = None @@ -257,12 +359,25 @@ class vrmlNode(object): return self.DEF_NAMESPACE else: return self.parent.getDefDict() + + def getRouteIpoDict(self): + if self.ROUTE_IPO_NAMESPACE != None: + return self.ROUTE_IPO_NAMESPACE + else: + return self.parent.getRouteIpoDict() def setRoot(self, filename): self.filename = filename - self.FIELD_NAMESPACE = {} - self.DEF_NAMESPACE= {} - + self.FIELD_NAMESPACE = {} + self.DEF_NAMESPACE = {} + self.ROUTE_IPO_NAMESPACE = {} + + def isRoot(self): + if self.filename == None: + return False + else: + return True + def getFilename(self): if self.filename: return self.filename @@ -284,6 +399,11 @@ class vrmlNode(object): except: return None + def getPrefix(self): + if self.id: + return self.id[0] + return None + def getDefName(self): self_real = self.getRealNode() @@ -464,11 +584,13 @@ class vrmlNode(object): child_array = None for child in self_real.children: + # print "ID IS", child.id if child.id and len(child.id) == 1 and child.id[0] == field: child_array = child break if child_array==None: + # For x3d, should work ok with vrml too # for x3d arrays are fields, vrml they are nodes, annoying but not tooo bad. data_split = self.getFieldName(field) @@ -489,9 +611,12 @@ class vrmlNode(object): print '\tWarning, could not parse array data from field' array_data = [] else: - + # print child_array # Normal vrml array_data = child_array.array_data + + + # print 'array_data', array_data if group==-1 or len(array_data)==0: return array_data @@ -520,8 +645,6 @@ class vrmlNode(object): # We requested a flat array if group == 0: return flat_array - - new_array = [] sub_array = [] @@ -537,6 +660,30 @@ class vrmlNode(object): return new_array + def getFieldAsStringArray(self, field): + ''' + Get a list of strings + ''' + self_real = self.getRealNode() # incase we're an instance + + child_array = None + for child in self_real.children: + if child.id and len(child.id) == 1 and child.id[0] == field: + child_array = child + break + if not child_array: + return [] + + # each string gets its own list, remove ""'s + try: + new_array = [f[0][1:-1] for f in child_array.fields] + except: + print '\twarning, string array could not be made' + new_array = [] + + return new_array + + def getLevel(self): # Ignore self_real level = 0 @@ -564,19 +711,24 @@ class vrmlNode(object): else: text = '' - text += ind + 'ID: ' + str(self.id) + ' ' + str(level) + ('lineno %d\n' % self.lineno) + text += ind + 'ID: ' + str(self.id) + ' ' + str(level) + (' lineno %d\n' % self.lineno) if self.node_type==NODE_REFERENCE: + text += ind + "(reference node)\n" return text - for item in self.fields: + text += ind + 'FIELDS:\n' + + for i,item in enumerate(self.fields): + text += ind + 'FIELD:\n' text += ind + str(item) +'\n' #text += ind + 'ARRAY: ' + str(len(self.array_data)) + ' ' + str(self.array_data) + '\n' text += ind + 'ARRAY: ' + str(len(self.array_data)) + '[...] \n' text += ind + 'CHILDREN: ' + str(len(self.children)) + '\n' - for child in self.children: + for i, child in enumerate(self.children): + text += ind + ('CHILD%d:\n' % i) text += str(child) text += '\n' + ind + brackets[1] @@ -590,12 +742,24 @@ class vrmlNode(object): # If we were an inline then try load the file if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline': + url = self.getFieldAsString('url', None) if url != None: - if not exists(url): - url = dirName(self.getFilename()) + baseName(url) - if not exists(url): + urls = [] + urls.append( url ) + urls.append( BPySys.caseInsensitivePath(urls[-1]) ) + + urls.append( dirName(self.getFilename()) + baseName(url) ) + urls.append( BPySys.caseInsensitivePath(urls[-1]) ) + + try: + url = [url for url in urls if exists(url)][0] + url_found = True + except: + url_found = False + + if not url_found: print '\tWarning: Inline URL could not be found:', url else: if url==self.getFilename(): @@ -603,12 +767,12 @@ class vrmlNode(object): else: try: - f = open(url, 'rU') + data = gzipOpen(url) except: print '\tWarning: cant open the file:', url - f = None + data = None - if f: + if data: # Tricky - inline another VRML print '\tLoading Inline:"%s"...' % url @@ -616,12 +780,15 @@ class vrmlNode(object): lines_old = lines[:] - lines[:] = vrmlFormat( f.read() ) - f.close() + lines[:] = vrmlFormat( data ) lines.insert(0, '{') lines.insert(0, 'root_node____') lines.append('}') + ''' + ff = open('/test.txt', 'w') + ff.writelines([l+'\n' for l in lines]) + ''' child = vrmlNode(self, NODE_NORMAL, -1) child.setRoot(url) # initialized dicts @@ -723,7 +890,9 @@ class vrmlNode(object): values = l_split # This should not extend over multiple lines however it is possible - self.array_data.extend( values ) + # print self.array_data + if values: + self.array_data.extend( values ) i+=1 else: words = l.split() @@ -843,12 +1012,12 @@ def vrml_parse(path): lines.insert(0, '{') lines.insert(0, 'dymmy_node') lines.append('}') - # Use for testing our parsed output, so we can check on line numbers. - ## ff = open('m:\\test.txt', 'w') - ## ff.writelines([l+'\n' for l in lines]) - + ''' + ff = open('/test.txt', 'w') + ff.writelines([l+'\n' for l in lines]) + ''' # Now evaluate it node_type, new_i = is_nodeline(0, []) @@ -866,9 +1035,14 @@ def vrml_parse(path): # Parse recursively root.parse(0) - # print root + # This prints a load of text + ''' + print root + ''' + return root, '' + # ====================== END VRML @@ -996,6 +1170,9 @@ for i, f in enumerate(files): # ----------------------------------------------------------------------------------- import bpy import BPyImage +import BPySys +reload(BPySys) +reload(BPyImage) import Blender from Blender import Texture, Material, Mathutils, Mesh, Types, Window from Blender.Mathutils import TranslationMatrix @@ -1090,6 +1267,7 @@ def translateTexTransform(node): return new_mat + def getFinalMatrix(node, mtx, ancestry): transform_nodes = [node_tx for node_tx in ancestry if node_tx.getSpec() == 'Transform'] @@ -1343,7 +1521,8 @@ def importMesh_IndexedFaceSet(geom, bpyima): if len(ifs_vcol) < color_index: c.r, c.g, c.b = ifs_vcol[color_index] else: - print '\tWarning: per face color index out of range' + #print '\tWarning: per face color index out of range' + pass else: if vcolor_spot: # use 1 color, when ifs_vcol is [] for c in fcol: @@ -1517,6 +1696,9 @@ def importShape(node, ancestry): bpymat = None bpyima = None texmtx = None + + depth = 0 # so we can set alpha face flag later + if appr: #mat = appr.getChildByName('material') # 'Material' @@ -1561,12 +1743,17 @@ def importShape(node, ancestry): if ima: - # print ima + ima_url = ima.getFieldAsString('url') + + if ima_url==None: + try: ima_url = ima.getFieldAsStringArray('url')[0] # in some cases we get a list of images. + except: ima_url = None + if ima_url==None: print "\twarning, image with no URL, this is odd" else: - bpyima= BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER= False, RECURSIVE= False) + bpyima= BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER= False, RECURSIVE= False, CONVERT_CALLBACK= imageConvertCompat) if bpyima: texture= bpy.data.textures.new() texture.setType('Image') @@ -1588,7 +1775,8 @@ def importShape(node, ancestry): ima_repS = ima.getFieldAsBool('repeatS', True) ima_repT = ima.getFieldAsBool('repeatT', True) - texture.repeat = max(1, ima_repS * 512), max(1, ima_repT * 512) + # To make this work properly we'd need to scale the UV's too, better to ignore th + # texture.repeat = max(1, ima_repS * 512), max(1, ima_repT * 512) if not ima_repS: bpyima.clampX = True if not ima_repT: bpyima.clampY = True @@ -1632,15 +1820,22 @@ def importShape(node, ancestry): # Only ever 1 material per shape if bpymat: bpydata.materials = [bpymat] - if bpydata.faceUV and texmtx: - # Apply texture transform? - uv_copy = Vector() - for f in bpydata.faces: - for uv in f.uv: - uv_copy.x = uv.x - uv_copy.y = uv.y - - uv.x, uv.y = (uv_copy * texmtx)[0:2] + if bpydata.faceUV: + + if depth==32: # set the faces alpha flag? + transp = Mesh.FaceTranspModes.ALPHA + for f in bpydata.faces: + f.transp = transp + + if texmtx: + # Apply texture transform? + uv_copy = Vector() + for f in bpydata.faces: + for uv in f.uv: + uv_copy.x = uv.x + uv_copy.y = uv.y + + uv.x, uv.y = (uv_copy * texmtx)[0:2] # Done transforming the texture @@ -1733,7 +1928,7 @@ def importLamp_SpotLight(node): # Convert # lamps have their direction as -z, y==up - mtx = TranslationMatrix(Vector(location)) * Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() + mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() * TranslationMatrix(Vector(location)) return bpylamp, mtx @@ -1760,14 +1955,14 @@ def importViewpoint(node, ancestry): fieldOfView = node.getFieldAsFloat('fieldOfView', 0.785398) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher. # jump = node.getFieldAsBool('jump', True) orientation = node.getFieldAsFloatTuple('orientation', (0.0, 0.0, 1.0, 0.0)) - position = node.getFieldAsFloatTuple('position', (0.0, 0.0, 10.0)) + position = node.getFieldAsFloatTuple('position', (0.0, 0.0, 0.0)) description = node.getFieldAsString('description', '') bpycam = bpy.data.cameras.new(name) bpycam.angle = fieldOfView - mtx = TranslationMatrix(Vector(position)) * translateRotation(orientation) * MATRIX_Z_TO_Y + mtx = translateRotation(orientation) * TranslationMatrix(Vector(position)) bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpycam) @@ -1781,6 +1976,149 @@ def importTransform(node, ancestry): bpyob = node.blendObject = bpy.data.scenes.active.objects.new('Empty', name) # , name) bpyob.setMatrix( getFinalMatrix(node, None, ancestry) ) + +#def importTimeSensor(node): + + +def translatePositionInterpolator(node, ipo): + key = node.getFieldAsArray('key', 0) + keyValue = node.getFieldAsArray('keyValue', 3) + + loc_x = ipo.addCurve('LocX') + loc_y = ipo.addCurve('LocY') + loc_z = ipo.addCurve('LocZ') + + loc_x.interpolation = loc_y.interpolation = loc_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR + + for i, time in enumerate(key): + x,y,z = keyValue[i] + + loc_x.append((time,x)) + loc_y.append((time,y)) + loc_z.append((time,z)) + +def translateOrientationInterpolator(node, ipo): + key = node.getFieldAsArray('key', 0) + keyValue = node.getFieldAsArray('keyValue', 4) + + rot_x = ipo.addCurve('RotX') + rot_y = ipo.addCurve('RotY') + rot_z = ipo.addCurve('RotZ') + + rot_x.interpolation = rot_y.interpolation = rot_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR + + for i, time in enumerate(key): + + mtx = translateRotation(keyValue[i]) + eul = mtx.toEuler() + rot_x.append((time,eul.x/10.0)) + rot_y.append((time,eul.y/10.0)) + rot_z.append((time,eul.z/10.0)) + +# Untested! +def translateScalarInterpolator(node, ipo): + key = node.getFieldAsArray('key', 0) + keyValue = node.getFieldAsArray('keyValue', 4) + + sca_x = ipo.addCurve('SizeX') + sca_y = ipo.addCurve('SizeY') + sca_z = ipo.addCurve('SizeZ') + + sca_x.interpolation = sca_y.interpolation = sca_z.interpolation = Blender.IpoCurve.InterpTypes.LINEAR + + for i, time in enumerate(key): + x,y,z = keyValue[i] + sca_x.append((time,x/10.0)) + sca_y.append((time,y/10.0)) + sca_z.append((time,z/10.0)) + +def translateTimeSensor(node, ipo): + ''' + Apply a time sensor to an IPO, VRML has many combinations of loop/start/stop/cycle times + to give different results, for now just do the basics + ''' + + time_cu = ipo.addCurve('Time') + time_cu.interpolation = Blender.IpoCurve.InterpTypes.LINEAR + + cycleInterval = node.getFieldAsFloat('cycleInterval', None) + + startTime = node.getFieldAsFloat('startTime', 0.0) + stopTime = node.getFieldAsFloat('stopTime', 250.0) + + if cycleInterval != None: + stopTime = startTime+cycleInterval + + loop = node.getFieldAsBool('loop', False) + + time_cu.append((1+startTime, 0.0)) + time_cu.append((1+stopTime, 1.0/10.0))# anoying, the UI uses /10 + + + if loop: + time_cu.extend = Blender.IpoCurve.ExtendTypes.CYCLIC # or - EXTRAP, CYCLIC_EXTRAP, CONST, + + +def importRoute(node): + ''' + Animation route only at the moment + ''' + + routeIpoDict = node.getRouteIpoDict() + + def getIpo(id): + try: ipo = routeIpoDict[id] + except: ipo = routeIpoDict[id] = bpy.data.ipos.new('web3d_ipo', 'Object') + return ipo + + # for getting definitions + defDict = node.getDefDict() + ''' + Handles routing nodes to eachother + +ROUTE vpPI.value_changed TO champFly001.set_position +ROUTE vpOI.value_changed TO champFly001.set_orientation +ROUTE vpTs.fraction_changed TO vpPI.set_fraction +ROUTE vpTs.fraction_changed TO vpOI.set_fraction +ROUTE champFly001.bindTime TO vpTs.set_startTime + ''' + + #from_id, from_type = node.id[1].split('.') + #to_id, to_type = node.id[3].split('.') + + #value_changed + set_position_node = None + set_orientation_node = None + time_node = None + + for field in node.fields: + if field and field[0]=='ROUTE': + from_id, from_type = field[1].split('.') + to_id, to_type = field[3].split('.') + + if from_type == 'value_changed': + if to_type == 'set_position': + ipo = getIpo(to_id) + set_data_from_node = defDict[from_id] + translatePositionInterpolator(set_data_from_node, ipo) + + if to_type == 'set_orientation': + ipo = getIpo(to_id) + set_data_from_node = defDict[from_id] + translateOrientationInterpolator(set_data_from_node, ipo) + + if to_type == 'set_scale': + ipo = getIpo(to_id) + set_data_from_node = defDict[from_id] + translateScalarInterpolator(set_data_from_node, ipo) + + elif from_type == 'bindTime': + ipo = getIpo(from_id) + time_node = defDict[to_id] + translateTimeSensor(time_node, ipo) + + + def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC = None): @@ -1818,14 +2156,44 @@ def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC = None): elif spec=='Transform': # Only use transform nodes when we are not importing a flat object hierarchy if PREF_FLAT==False: - importTransform(node, ancestry) - else: + importTransform(node, ancestry) + ''' + # These are delt with later within importRoute + elif spec=='PositionInterpolator': + ipo = bpy.data.ipos.new('web3d_ipo', 'Object') + translatePositionInterpolator(node, ipo) + ''' + else: # Note, include this function so the VRML/X3D importer can be extended # by an external script. if HELPER_FUNC: HELPER_FUNC(node, ancestry) + + + + # After we import all nodes, route events - anim paths + for node, ancestry in all_nodes: + importRoute(node) + + for node, ancestry in all_nodes: + if node.isRoot(): + # we know that all nodes referenced from will be in + # routeIpoDict so no need to run node.getDefDict() for every node. + routeIpoDict = node.getRouteIpoDict() + defDict = node.getDefDict() + for key, ipo in routeIpoDict.iteritems(): + + # Assign anim curves + node = defDict[key] + if node.blendObject==None: # Add an object if we need one for animation + node.blendObject = bpy.data.scenes.active.objects.new('Empty', 'AnimOb') # , name) + + node.blendObject.setIpo(ipo) + + + # Add in hierarchy if PREF_FLAT==False: child_dict = {} @@ -1886,7 +2254,7 @@ def load_ui(path): if __name__ == '__main__': Window.FileSelector(load_ui, 'Import X3D/VRML97') - + # Testing stuff # load_web3d('/test.x3d') diff --git a/source/Makefile b/source/Makefile index 12f2516a982..fe48b26c14c 100644 --- a/source/Makefile +++ b/source/Makefile @@ -194,7 +194,7 @@ ifeq ($(WITH_FREETYPE2), true) else COMLIB += $(NAN_FTGL)/lib/libftgl.a ifeq ($(OS), irix) - COMLIB += $(NAN_FREETYPE)/lib32/libfreetype.a + COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a else COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a endif @@ -417,9 +417,16 @@ else NAN_SND_LIBS += $(ALUT) NAN_SND_LIBS += $(SOUNDSYSTEM) else - NAN_SND_LIBS = $(SOUNDSYSTEM) - NAN_SND_LIBS += $(DUMMYSOUND) - NAN_SND_LIBS += $(SOUNDSYSTEM) + ifeq ($(OS), irix) + NAN_SND_LIBS = $(SOUNDSYSTEM) + NAN_SND_LIBS += $(DUMMYSOUND) + NAN_SND_LIBS += $(SDLSOUND) + NAN_SND_LIBS += $(SOUNDSYSTEM) + else + NAN_SND_LIBS = $(SOUNDSYSTEM) + NAN_SND_LIBS += $(DUMMYSOUND) + NAN_SND_LIBS += $(SOUNDSYSTEM) + endif endif endif endif diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index f1f4653f092..398d203709f 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -53,6 +53,7 @@ int brush_clone_image_delete(struct Brush *brush); /* sampling */ float brush_sample_falloff(struct Brush *brush, float dist); +float brush_sample_falloff_noalpha(struct Brush *brush, float dist); void brush_sample_tex(struct Brush *brush, float *xy, float *rgba); void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size, struct ImBuf **imbuf); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index c84b690bc49..10791968f79 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -198,8 +198,12 @@ int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_named_layer_index(const struct CustomData *data, int type, char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); +int CustomData_get_clone_layer_index(const struct CustomData *data, int type); +int CustomData_get_mask_layer_index(const struct CustomData *data, int type); int CustomData_get_active_layer(const struct CustomData *data, int type); int CustomData_get_render_layer(const struct CustomData *data, int type); +int CustomData_get_clone_layer(const struct CustomData *data, int type); +int CustomData_get_mask_layer(const struct CustomData *data, int type); /* copies the data from source to the data element at index in the first * layer of type @@ -227,10 +231,14 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi /* sets the nth layer of type as active */ void CustomData_set_layer_active(struct CustomData *data, int type, int n); void CustomData_set_layer_render(struct CustomData *data, int type, int n); +void CustomData_set_layer_clone(struct CustomData *data, int type, int n); +void CustomData_set_layer_mask(struct CustomData *data, int type, int n); /* same as above but works with an index from CustomData_get_layer_index */ void CustomData_set_layer_active_index(struct CustomData *data, int type, int n); void CustomData_set_layer_render_index(struct CustomData *data, int type, int n); +void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n); +void CustomData_set_layer_mask_index(struct CustomData *data, int type, int n); /* adds flag to the layer flags */ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index fa3a654c1c2..1c5b6b124b2 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -401,6 +401,8 @@ struct TexResult; #define TEX_NODE_ROTATE 114 #define TEX_NODE_VIEWER 115 #define TEX_NODE_TRANSLATE 116 +#define TEX_NODE_COORD 117 +#define TEX_NODE_DISTANCE 118 /* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */ #define TEX_NODE_PROC 200 diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 1c53af97dbb..021f76fd2f1 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -328,6 +328,23 @@ float brush_sample_falloff(Brush *brush, float dist) return 0.0f; } +float brush_sample_falloff_noalpha(Brush *brush, float dist) +{ + float outer, inner; + + outer = brush->size >> 1; + inner = outer*brush->innerradius; + + if (dist <= inner) { + return 1.0f; + } + else if ((dist < outer) && (inner < outer)) { + return 1.0f - sqrt((dist - inner)/(outer - inner)); + } + else + return 0.0f; +} + void brush_sample_tex(Brush *brush, float *xy, float *rgba) { MTex *mtex= brush->mtex[brush->texact]; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 1a671dfe771..7fa4f406c7b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -833,7 +833,6 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu sum= (float *)MEM_callocN(sizeof(float)*len, "makeNurbcurve1"); resolu= (resolu*SEGMENTSU(nu)); - if((nu->flagu & CU_CYCLIC)==0) resolu++; if(resolu==0) { MEM_freeN(sum); @@ -1685,7 +1684,6 @@ void makeBevelList(Object *ob) else if((nu->type & 7)==CU_NURBS) { if(nu->pntsv==1) { len= (resolu*SEGMENTSU(nu)); - if((nu->flagu & CU_CYCLIC)==0) len++; bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList3"); BLI_addtail(&(cu->bev), bl); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index e93266c85f3..05271aa59a7 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -606,7 +606,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, { const LayerTypeInfo *typeInfo; CustomDataLayer *layer, *newlayer; - int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0; + int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0; for(i = 0; i < source->totlayer; ++i) { layer = &source->layers[i]; @@ -618,6 +618,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, number = 0; lastactive = layer->active; lastrender = layer->active_rnd; + lastclone = layer->active_clone; + lastmask = layer->active_mask; lasttype = type; } else @@ -637,6 +639,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, if(newlayer) { newlayer->active = lastactive; newlayer->active_rnd = lastrender; + newlayer->active_clone = lastclone; + newlayer->active_mask = lastmask; } } } @@ -736,6 +740,28 @@ int CustomData_get_render_layer_index(const CustomData *data, int type) return -1; } +int CustomData_get_clone_layer_index(const CustomData *data, int type) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + return i + data->layers[i].active_clone; + + return -1; +} + +int CustomData_get_mask_layer_index(const CustomData *data, int type) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + return i + data->layers[i].active_mask; + + return -1; +} + int CustomData_get_active_layer(const CustomData *data, int type) { int i; @@ -758,6 +784,27 @@ int CustomData_get_render_layer(const CustomData *data, int type) return -1; } +int CustomData_get_clone_layer(const CustomData *data, int type) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + return data->layers[i].active_clone; + + return -1; +} + +int CustomData_get_mask_layer(const CustomData *data, int type) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + return data->layers[i].active_mask; + + return -1; +} void CustomData_set_layer_active(CustomData *data, int type, int n) { @@ -777,6 +824,24 @@ void CustomData_set_layer_render(CustomData *data, int type, int n) data->layers[i].active_rnd = n; } +void CustomData_set_layer_clone(CustomData *data, int type, int n) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + data->layers[i].active_clone = n; +} + +void CustomData_set_layer_mask(CustomData *data, int type, int n) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + data->layers[i].active_mask = n; +} + /* for using with an index from CustomData_get_active_layer_index and CustomData_get_render_layer_index */ void CustomData_set_layer_active_index(CustomData *data, int type, int n) { @@ -796,6 +861,23 @@ void CustomData_set_layer_render_index(CustomData *data, int type, int n) data->layers[i].active_rnd = n-i; } +void CustomData_set_layer_clone_index(CustomData *data, int type, int n) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + data->layers[i].active_clone = n-i; +} + +void CustomData_set_layer_mask_index(CustomData *data, int type, int n) +{ + int i; + + for(i=0; i < data->totlayer; ++i) + if(data->layers[i].type == type) + data->layers[i].active_mask = n-i; +} void CustomData_set_layer_flag(struct CustomData *data, int type, int flag) { @@ -882,9 +964,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, if(index > 0 && data->layers[index-1].type == type) { data->layers[index].active = data->layers[index-1].active; data->layers[index].active_rnd = data->layers[index-1].active_rnd; + data->layers[index].active_clone = data->layers[index-1].active_clone; + data->layers[index].active_mask = data->layers[index-1].active_mask; } else { data->layers[index].active = 0; data->layers[index].active_rnd = 0; + data->layers[index].active_clone = 0; + data->layers[index].active_mask = 0; } customData_update_offsets(data); @@ -944,6 +1030,8 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) for (; i < data->totlayer && data->layers[i].type == type; i++) { data->layers[i].active--; data->layers[i].active_rnd--; + data->layers[i].active_clone--; + data->layers[i].active_mask--; } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 44aa439ee3e..84025204ee4 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -890,7 +890,6 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) } else if((nu->type & 7)==CU_NURBS) { len= (resolu*SEGMENTSU(nu)); - if((nu->flagu & CU_CYCLIC)==0) len++; dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); @@ -1384,7 +1383,7 @@ void makeDispListSurf(Object *ob, ListBase *dispbase, int forRender) for (nu=nubase->first; nu; nu=nu->next) { if(forRender || nu->hide==0) { if(nu->pntsv==1) { - len= nu->pntsu*nu->resolu; + len= SEGMENTSU(nu)*nu->resolu; dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index e189891d884..0e43ecd61e1 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -2886,6 +2886,8 @@ static void registerTextureNodes(ListBase *ntypelist) nodeRegisterType(ntypelist, &tex_node_curve_time); nodeRegisterType(ntypelist, &tex_node_invert); nodeRegisterType(ntypelist, &tex_node_hue_sat); + nodeRegisterType(ntypelist, &tex_node_coord); + nodeRegisterType(ntypelist, &tex_node_distance); nodeRegisterType(ntypelist, &tex_node_output); nodeRegisterType(ntypelist, &tex_node_viewer); diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h index e840ffd167a..ed202c11429 100644 --- a/source/blender/blenlib/BLI_linklist.h +++ b/source/blender/blenlib/BLI_linklist.h @@ -45,6 +45,7 @@ typedef struct LinkNode { } LinkNode; int BLI_linklist_length (struct LinkNode *list); +int BLI_linklist_index (struct LinkNode *list, void *ptr); void BLI_linklist_reverse (struct LinkNode **listp); diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index 34d732e1862..a2954f8fa0d 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -50,6 +50,7 @@ typedef struct MemArena MemArena; struct MemArena* BLI_memarena_new (int bufsize); void BLI_memarena_free (struct MemArena *ma); +void BLI_memarena_use_malloc (struct MemArena *ma); void BLI_memarena_use_calloc (struct MemArena *ma); void* BLI_memarena_alloc (struct MemArena *ma, int size); diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 01a9a1eab0e..f664b75af5a 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -23,7 +23,7 @@ if env['OURPLATFORM'] == 'linux2': cflags='-pthread' incs += ' ../../../extern/binreloc/include' -if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'): +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'): incs += ' ' + env['BF_PTHREADS_INC'] env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core', 'intern', 'player'], priority = [85,150,195], compileflags =cflags ) diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index 506a1036ed6..962bbeea373 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -50,6 +50,18 @@ int BLI_linklist_length(LinkNode *list) { } } +int BLI_linklist_index(struct LinkNode *list, void *ptr) +{ + int index; + + for (index = 0; list; list= list->next, index++) { + if (list->link == ptr) + return index; + } + + return -1; +} + void BLI_linklist_reverse(LinkNode **listp) { LinkNode *rhead= NULL, *cur= *listp; diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index 69dd13cd335..87d2f0426b2 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -60,6 +60,10 @@ void BLI_memarena_use_calloc(MemArena *ma) { ma->use_calloc= 1; } +void BLI_memarena_use_malloc(MemArena *ma) { + ma->use_calloc= 0; +} + void BLI_memarena_free(MemArena *ma) { BLI_linklist_free(ma->bufs, (void(*)(void*)) MEM_freeN); MEM_freeN(ma); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 0f2226fc872..a47d37eb69a 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -1351,8 +1351,8 @@ void Mat4ToQuat( float m[][4], float *q) void QuatOne(float *q) { - q[0]= q[2]= q[3]= 0.0; - q[1]= 1.0; + q[0]= 1.0; + q[1]= q[2]= q[3]= 0.0; } void NormalQuat(float *q) diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index ca7a376d3a2..8ba03ad1343 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -47,9 +47,9 @@ #include <time.h> #include <sys/stat.h> -#if defined (__sun__) || defined (__sun) +#if defined (__sun__) || defined (__sun) || defined (__sgi) #include <sys/statvfs.h> /* Other modern unix os's should probably use this also */ -#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__)) +#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__)) #include <sys/statfs.h> #endif @@ -179,7 +179,7 @@ double BLI_diskfree(char *dir) return (double) (freec*bytesps*sectorspc); #else -#if defined (__sun__) || defined (__sun) +#if defined (__sun__) || defined (__sun) || defined (__sgi) struct statvfs disk; #else struct statfs disk; @@ -204,9 +204,9 @@ double BLI_diskfree(char *dir) return -1; #endif -#if defined (__sun__) || defined (__sun) +#if defined (__sun__) || defined (__sun) || defined (__sgi) if (statvfs(name, &disk)) return(-1); -#elif !defined(__FreeBSD__) && !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__)) +#elif !defined(__FreeBSD__) && !defined(linux) && (defined(__sparc) || defined(__sparc__)) /* WARNING - This may not be supported by geeneric unix os's - Campbell */ if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1); #endif diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 9df8bbc81e3..07c02b8024f 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -42,7 +42,7 @@ /* for checking system threads - BLI_system_thread_count */ #ifdef WIN32 -#include "Windows.h" +#include "windows.h" #elif defined(__APPLE__) #include <sys/types.h> #include <sys/sysctl.h> diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa44f00c607..df2c680c951 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8259,6 +8259,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 2)) { + Scene *sce; + + /* Note, these will need to be added for painting */ + for (sce= main->scene.first; sce; sce= sce->id.next) { + sce->toolsettings->imapaint.seam_bleed = 2; + sce->toolsettings->imapaint.normal_angle = 80; + } + } + if (main->versionfile < 250) { bScreen *screen; diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index d4d8030bf10..8bc1439fd09 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -403,9 +403,14 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf); * * @attention defined in imageprocess.c */ -void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float x, float y, int xout, int yout); +void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); + +void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); +void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); +void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v); + /** * Change the ordering of the color bytes pointed to by rect from * rgba to abgr. size * 4 color bytes are reordered. diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index d7f1ab4419d..fe7e26eac2b 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -80,6 +80,17 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) } } } +static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y) + +{ + int offset = ibuf->x * y * 4 + 4*x; + + if (ibuf->rect) + *outI= (unsigned char *)ibuf->rect + offset; + + if (ibuf->rect_float) + *outF= (float *)ibuf->rect_float + offset; +} /************************************************************************** * INTERPOLATIONS @@ -92,32 +103,40 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) /* More info: http://wiki.blender.org/index.php/User:Damiles#Bicubic_pixel_interpolation */ /* function assumes out to be zero'ed, only does RGBA */ + +static float P(float k){ + float p1, p2, p3, p4; + p1 = MAX2(k+2.0f,0); + p2 = MAX2(k+1.0f,0); + p3 = MAX2(k,0); + p4 = MAX2(k-1.0f,0); + return (float)(1.0f/6.0f)*( p1*p1*p1 - 4.0f * p2*p2*p2 + 6.0f * p3*p3*p3 - 4.0f * p4*p4*p4); +} + + +#if 0 +/* older, slower function, works the same as above */ static float P(float k){ return (float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f)); } +#endif -void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) +void bicubic_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) { int i,j,n,m,x1,y1; - unsigned char *dataI,*outI; - float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF,*outF; - int do_rect, do_float; - - if (in == NULL) return; - if (in->rect == NULL && in->rect_float == NULL) return; + unsigned char *dataI; + float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF; - do_rect= (out->rect != NULL); - do_float= (out->rect_float != NULL); + /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */ - i= (int)floor(x); - j= (int)floor(y); - a= x - i; - b= y - j; + i= (int)floor(u); + j= (int)floor(v); + a= u - i; + b= v - j; - outR= 0.0f; - outG= 0.0f; - outB= 0.0f; - outA= 0.0f; + outR = outG = outB = outA = 0.0f; + +/* Optimized and not so easy to read */ /* avoid calling multiple times */ wy[0] = P(b-(-1)); @@ -137,14 +156,14 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in /* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */ w = wx * wy[m+1]; - if (do_float) { + if (outF) { dataF= in->rect_float + in->x * y1 * 4 + 4*x1; outR+= dataF[0] * w; outG+= dataF[1] * w; outB+= dataF[2] * w; outA+= dataF[3] * w; } - if (do_rect) { + if (outI) { dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1; outR+= dataI[0] * w; outG+= dataI[1] * w; @@ -155,15 +174,42 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in } } } - if (do_rect) { - outI= (unsigned char *)out->rect + out->x * yout * 4 + 4*xout; + +/* Done with optimized part */ + +#if 0 + /* older, slower function, works the same as above */ + for(n= -1; n<= 2; n++){ + for(m= -1; m<= 2; m++){ + x1= i+n; + y1= j+m; + if (x1>0 && x1 < in->x && y1>0 && y1<in->y) { + if (do_float) { + dataF= in->rect_float + in->x * y1 * 4 + 4*x1; + outR+= dataF[0] * P(n-a) * P(b-m); + outG+= dataF[1] * P(n-a) * P(b-m); + outB+= dataF[2] * P(n-a) * P(b-m); + outA+= dataF[3] * P(n-a) * P(b-m); + } + if (do_rect) { + dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1; + outR+= dataI[0] * P(n-a) * P(b-m); + outG+= dataI[1] * P(n-a) * P(b-m); + outB+= dataI[2] * P(n-a) * P(b-m); + outA+= dataI[3] * P(n-a) * P(b-m); + } + } + } + } +#endif + + if (outI) { outI[0]= (int)outR; outI[1]= (int)outG; outI[2]= (int)outB; outI[3]= (int)outA; } - if (do_float) { - outF= (float *)out->rect_float + out->x * yout * 4 + 4*xout; + if (outF) { outF[0]= outR; outF[1]= outG; outF[2]= outB; @@ -171,23 +217,33 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in } } + +void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +{ + + unsigned char *outI = NULL; + float *outF = NULL; + + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + + pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ + + bicubic_interpolation_color(in, outI, outF, u, v); +} + /* function assumes out to be zero'ed, only does RGBA */ /* BILINEAR INTERPOLATION */ -void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +void bilinear_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) { - float *row1, *row2, *row3, *row4, a, b, *outF; - unsigned char *row1I, *row2I, *row3I, *row4I, *outI; + float *row1, *row2, *row3, *row4, a, b; + unsigned char *row1I, *row2I, *row3I, *row4I; float a_b, ma_b, a_mb, ma_mb; float empty[4]= {0.0f, 0.0f, 0.0f, 0.0f}; unsigned char emptyI[4]= {0, 0, 0, 0}; int y1, y2, x1, x2; - int do_rect, do_float; - - if (in==NULL) return; - if (in->rect==NULL && in->rect_float==NULL) return; - - do_rect= (out->rect != NULL); - do_float= (out->rect_float != NULL); + + + /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */ x1= (int)floor(u); x2= (int)ceil(u); @@ -197,16 +253,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i // sample area entirely outside image? if (x2<0 || x1>in->x-1 || y2<0 || y1>in->y-1) return; - if (do_rect) - outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout; - else - outI= NULL; - if (do_float) - outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout; - else - outF= NULL; - - if (do_float) { + if (outF) { // sample including outside of edges of image if (x1<0 || y1<0) row1= empty; else row1= (float *)in->rect_float + in->x * y1 * 4 + 4*x1; @@ -229,7 +276,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i outF[2]= ma_mb*row1[2] + a_mb*row3[2] + ma_b*row2[2]+ a_b*row4[2]; outF[3]= ma_mb*row1[3] + a_mb*row3[3] + ma_b*row2[3]+ a_b*row4[3]; } - if (do_rect) { + if (outI) { // sample including outside of edges of image if (x1<0 || y1<0) row1I= emptyI; else row1I= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1; @@ -254,45 +301,44 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i } } +void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout) +{ + + unsigned char *outI = NULL; + float *outF = NULL; + + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + + pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ + + bilinear_interpolation_color(in, outI, outF, u, v); +} + /* function assumes out to be zero'ed, only does RGBA */ /* NEAREST INTERPOLATION */ -void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, int yout) +void neareast_interpolation_color(struct ImBuf *in, unsigned char *outI, float *outF, float u, float v) { - float *outF,*dataF; - unsigned char *dataI,*outI; + float *dataF; + unsigned char *dataI; int y1, x1; - int do_rect, do_float; - - if (in==NULL) return; - if (in->rect==NULL && in->rect_float==NULL) return; - - do_rect= (out->rect != NULL); - do_float= (out->rect_float != NULL); + /* ImBuf in must have a valid rect or rect_float, assume this is alredy checked */ + x1= (int)(u); y1= (int)(v); - if (do_rect) - outI=(unsigned char *)out->rect + out->x * yout * 4 + 4*xout; - else - outI= NULL; - if (do_float) - outF=(float *)out->rect_float + out->x * yout * 4 + 4*xout; - else - outF= NULL; - // sample area entirely outside image? if (x1<0 || x1>in->x-1 || y1<0 || y1>in->y-1) return; // sample including outside of edges of image if (x1<0 || y1<0) { - if (do_rect) { + if (outI) { outI[0]= 0; outI[1]= 0; outI[2]= 0; outI[3]= 0; } - if (do_float) { + if (outF) { outF[0]= 0.0f; outF[1]= 0.0f; outF[2]= 0.0f; @@ -300,14 +346,14 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in } } else { dataI= (unsigned char *)in->rect + in->x * y1 * 4 + 4*x1; - if (do_rect) { + if (outI) { outI[0]= dataI[0]; outI[1]= dataI[1]; outI[2]= dataI[2]; outI[3]= dataI[3]; } dataF= in->rect_float + in->x * y1 * 4 + 4*x1; - if (do_float) { + if (outF) { outF[0]= dataF[0]; outF[1]= dataF[1]; outF[2]= dataF[2]; @@ -315,3 +361,16 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float u, float v,int xout, in } } } + +void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) +{ + + unsigned char *outI = NULL; + float *outF = NULL; + + if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) return; + + pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ + + neareast_interpolation_color(in, outI, outF, x, y); +} diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 6c098e220bb..e6b18641d2a 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -37,6 +37,8 @@ typedef struct CustomDataLayer { int flag; /* general purpose flag */ int active; /* number of the active layer of this type */ int active_rnd; /* number of the layer to render*/ + int active_clone; /* number of the layer to render*/ + int active_mask; /* number of the layer to render*/ char pad[4]; char name[32]; /* layer name */ void *data; /* layer data */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5397d890789..859b3abd7e2 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -344,7 +344,9 @@ typedef struct TimeMarker { typedef struct ImagePaintSettings { struct Brush *brush; short flag, tool; - int pad3; + + /* for projection painting only */ + short seam_bleed,normal_angle; } ImagePaintSettings; typedef struct ParticleBrushData { @@ -826,6 +828,15 @@ typedef struct Scene { #define IMAGEPAINT_DRAW_TOOL 2 #define IMAGEPAINT_DRAW_TOOL_DRAWING 4 +/* projection painting only */ +#define IMAGEPAINT_PROJECT_DISABLE 8 /* Non projection 3D painting */ +#define IMAGEPAINT_PROJECT_XRAY 16 +#define IMAGEPAINT_PROJECT_BACKFACE 32 +#define IMAGEPAINT_PROJECT_FLAT 64 +#define IMAGEPAINT_PROJECT_LAYER_CLONE 128 +#define IMAGEPAINT_PROJECT_LAYER_MASK 256 +#define IMAGEPAINT_PROJECT_LAYER_MASK_INV 512 + /* toolsettings->uvcalc_flag */ #define UVCALC_FILLHOLES 1 #define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */ diff --git a/source/blender/makesdna/DNA_scriptlink_types.h b/source/blender/makesdna/DNA_scriptlink_types.h index 95e20dd004d..9b50eb91a20 100644 --- a/source/blender/makesdna/DNA_scriptlink_types.h +++ b/source/blender/makesdna/DNA_scriptlink_types.h @@ -65,10 +65,12 @@ typedef struct ScriptLink { /* these are special scriptlinks that can be assigned to * a given space in a given ScrArea to: * - (EVENT type) handle events sent to that space; - * - (DRAW type) draw on the space after its own drawing function finishes + * - (EVENT_ALL type): handle release events, too; + * - (DRAW type) draw on the space after its own drawing function finishes. */ -#define SPACEHANDLER_VIEW3D_EVENT 1 -#define SPACEHANDLER_VIEW3D_DRAW 2 +#define SPACEHANDLER_VIEW3D_DRAW 1 +#define SPACEHANDLER_VIEW3D_EVENT 2 +#define SPACEHANDLER_VIEW3D_EVENT_ALL 3 #ifdef __cplusplus diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index b7d55a0ca1a..4aa8d6a9d54 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/SConscript @@ -18,9 +18,15 @@ makesdna_tool.Append (CPPPATH = ['#/intern/guardedalloc', '../../makesdna']) if env['OURPLATFORM'] == 'linuxcross': - makesdna_tool.Replace(CC='gcc') - makesdna_tool.Replace(AR='ar') - makesdna_tool.Replace(LINK='gcc') + USE_WINE = True # when cross compiling on linux 64bit this is useful +else: + USE_WINE = False + +if not USE_WINE: + if env['OURPLATFORM'] == 'linuxcross': + makesdna_tool.Replace(CC='gcc') + makesdna_tool.Replace(AR='ar') + makesdna_tool.Replace(LINK='gcc') if sys.platform != 'cygwin': makesdna_tool.Append (CCFLAGS = cflags) @@ -30,7 +36,7 @@ if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'): targetdir = '#'+targetdir makesdna_tool.Append (LIBPATH = targetdir) if env['BF_PROFILE']: - makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_FLAGS']) + makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_LINKFLAGS']) targetdir = root_build_dir + '/makesdna' @@ -43,7 +49,10 @@ dna_dict = dna.Dictionary() dna.Depends ('dna.c', makesdna) dna.Depends ('dna.c', header_files) if env['OURPLATFORM'] != 'linuxcross': - dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET") + if USE_WINE: + dna.Command ('dna.c', '', 'wine ' + root_build_dir+os.sep+"makesdna $TARGET") + else: + dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna $TARGET") else: dna.Command ('dna.c', '', root_build_dir+os.sep+"makesdna.exe $TARGET") obj = ['intern/dna.c', 'intern/dna_genfile.c'] diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 7f003cb2b42..7daf32361de 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -23,7 +23,7 @@ # # ***** END GPL LICENSE BLOCK ***** -FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c) +FILE(GLOB SRC intern/*.c intern/CMP_nodes/*.c intern/SHD_nodes/*.c intern/TEX_nodes/*.c) SET(INC . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h index 6be2123b96d..40cb65eacce 100644 --- a/source/blender/nodes/TEX_node.h +++ b/source/blender/nodes/TEX_node.h @@ -52,6 +52,8 @@ extern bNodeType tex_node_curve_rgb; extern bNodeType tex_node_curve_time; extern bNodeType tex_node_invert; extern bNodeType tex_node_hue_sat; +extern bNodeType tex_node_coord; +extern bNodeType tex_node_distance; extern bNodeType tex_node_rotate; extern bNodeType tex_node_translate; diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_coord.c b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c new file mode 100644 index 00000000000..da487c190af --- /dev/null +++ b/source/blender/nodes/intern/TEX_nodes/TEX_coord.c @@ -0,0 +1,66 @@ +/** + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Mathias Panzenböck (panzi) <grosser.meister.morti@gmx.net>. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../TEX_util.h" + +static bNodeSocketType outputs[]= { + { SOCK_VECTOR, 0, "Coordinates", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { -1, 0, "" } +}; + +static void vectorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread) +{ + out[0] = coord[0]; + out[1] = coord[1]; + out[2] = coord[2]; +} + +static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + tex_output(node, in, out[0], &vectorfn); + + tex_do_preview(node, out[0], data); +} + +bNodeType tex_node_coord= { + /* *next,*prev */ NULL, NULL, + /* type code */ TEX_NODE_COORD, + /* name */ "Coordinates", + /* width+range */ 120, 110, 160, + /* class+opts */ NODE_CLASS_INPUT, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ outputs, + /* storage */ "node_coord", + /* execfunc */ exec, + /* butfunc */ NULL, + /* initfunc */ NULL, + /* freestoragefunc */ NULL, + /* copystoragefunc */ NULL, + /* id */ NULL +}; + diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_distance.c b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c new file mode 100644 index 00000000000..ff9ec4db76b --- /dev/null +++ b/source/blender/nodes/intern/TEX_nodes/TEX_distance.c @@ -0,0 +1,79 @@ +/** + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Mathias Panzenböck (panzi) <grosser.meister.morti@gmx.net>. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <math.h> +#include "BLI_arithb.h" +#include "../TEX_util.h" + +static bNodeSocketType inputs[]= { + { SOCK_VECTOR, 1, "Coordinate 1", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { SOCK_VECTOR, 1, "Coordinate 2", 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f }, + { -1, 0, "" } +}; + +static bNodeSocketType outputs[]= { + { SOCK_VALUE, 0, "Value", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, + { -1, 0, "" } +}; + +static void valuefn(float *out, float *coord, bNode *node, bNodeStack **in, short thread) +{ + float coord1[3], coord2[3]; + float x, y, z; + + tex_input_vec(coord1, in[0], coord, thread); + tex_input_vec(coord2, in[1], coord, thread); + + *out = VecLenf(coord2, coord1); +} + +static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + tex_output(node, in, out[0], &valuefn); + + tex_do_preview(node, out[0], data); +} + +bNodeType tex_node_distance= { + /* *next,*prev */ NULL, NULL, + /* type code */ TEX_NODE_DISTANCE, + /* name */ "Distance", + /* width+range */ 120, 110, 160, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ inputs, + /* output sock */ outputs, + /* storage */ "node_distance", + /* execfunc */ exec, + /* butfunc */ NULL, + /* initfunc */ NULL, + /* freestoragefunc */ NULL, + /* copystoragefunc */ NULL, + /* id */ NULL +}; + + diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c index 10fe3bab26c..562072328a8 100644 --- a/source/blender/nodes/intern/TEX_util.c +++ b/source/blender/nodes/intern/TEX_util.c @@ -46,25 +46,32 @@ void tex_call_delegate(TexDelegate *dg, float *out, float *coord, short thread) dg->fn(out, coord, dg->node, dg->in, thread); } -void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread) +void tex_input(float *out, int sz, bNodeStack *in, float *coord, short thread) { TexDelegate *dg = in->data; if(dg) { - tex_call_delegate(dg, out, coord, thread); + tex_call_delegate(dg, in->vec, coord, thread); - if(in->hasoutput && in->sockettype == SOCK_VALUE) { - out[1] = out[2] = out[0]; - out[3] = 1; - } - } - else { - QUATCOPY(out, in->vec); + if(in->hasoutput && in->sockettype == SOCK_VALUE) + in->vec[1] = in->vec[2] = in->vec[0]; } + memcpy(out, in->vec, sz * sizeof(float)); +} + +void tex_input_vec(float *out, bNodeStack *in, float *coord, short thread) +{ + tex_input(out, 3, in, coord, thread); } void tex_input_rgba(float *out, bNodeStack *in, float *coord, short thread) { - tex_input_vec(out, in, coord, thread); + tex_input(out, 4, in, coord, thread); + + if(in->hasoutput && in->sockettype == SOCK_VALUE) + { + out[1] = out[2] = out[0]; + out[3] = 1; + } if(in->hasoutput && in->sockettype == SOCK_VECTOR) { out[0] = out[0] * .5f + .5f; @@ -83,8 +90,8 @@ float tex_input_value(bNodeStack *in, float *coord, short thread) static void init_preview(bNode *node) { - int xsize = node->prvr.xmax - node->prvr.xmin; - int ysize = node->prvr.ymax - node->prvr.ymin; + int xsize = (int)(node->prvr.xmax - node->prvr.xmin); + int ysize = (int)(node->prvr.ymax - node->prvr.ymin); if(xsize == 0) { xsize = PREV_RES; diff --git a/source/creator/creator.c b/source/creator/creator.c index b9f7ffed198..bfc03c976fb 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -29,6 +29,13 @@ #include <stdlib.h> #include <string.h> + +/* for setuid / getuid */ +#ifdef __sgi +#include <sys/types.h> +#include <unistd.h> +#endif + /* This little block needed for linking to Blender... */ #include "MEM_guardedalloc.h" @@ -177,7 +184,7 @@ static void print_help(void) printf (" -t <threads>\tUse amount of <threads> for rendering (background mode only).\n"); printf (" [1-8], 0 for systems processor count.\n"); printf ("\nAnimation playback options:\n"); - printf (" -a <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n"); + printf (" -a <options> <file(s)>\tPlayback <file(s)>, only operates this way when -b is not used.\n"); printf (" -p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>\n"); printf (" -m\t\tRead from disk (Don't buffer)\n"); printf (" -f <fps> <fps-base>\t\tSpecify FPS to start with\n"); diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile index 7ee825d186b..b1be56ac47f 100644 --- a/source/gameengine/BlenderRoutines/Makefile +++ b/source/gameengine/BlenderRoutines/Makefile @@ -35,6 +35,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(NAN_SUMO)/include -I$(NAN_SOLID)/include CPPFLAGS += -I$(NAN_SOLID) CPPFLAGS += -I$(NAN_STRING)/include diff --git a/source/gameengine/GamePlayer/common/unix/Makefile b/source/gameengine/GamePlayer/common/unix/Makefile index a2bdb7225a0..3d44a41afee 100644 --- a/source/gameengine/GamePlayer/common/unix/Makefile +++ b/source/gameengine/GamePlayer/common/unix/Makefile @@ -35,6 +35,7 @@ include nan_compile.mk CCFLAGS += $(LEVEL_1_CPP_WARNINGS) +CPPFLAGS += -I$(NAN_GLEW)/include CPPFLAGS += -I$(OPENGL_HEADERS) CPPFLAGS += -I$(NAN_STRING)/include diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index bf838e60210..3a20bbfbb11 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -185,7 +185,8 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost) m_savedMass = GetMass(); m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; m_savedCollisionFilterMask = handle->m_collisionFilterMask; - body->setActivationState(DISABLE_SIMULATION); + m_savedActivationState = body->getActivationState(); + body->forceActivationState(DISABLE_SIMULATION); GetPhysicsEnvironment()->updateCcdPhysicsController(this, 0.0, btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), @@ -204,7 +205,7 @@ void KX_BulletPhysicsController::RestoreDynamics() m_savedCollisionFlags, m_savedCollisionFilterGroup, m_savedCollisionFilterMask); - GetRigidBody()->forceActivationState(ACTIVE_TAG); + GetRigidBody()->forceActivationState(m_savedActivationState); } } diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index cdcb82c87ca..d5fca4ec6d3 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -9,6 +9,7 @@ class KX_BulletPhysicsController : public KX_IPhysicsController ,public CcdPhysi { private: int m_savedCollisionFlags; + int m_savedActivationState; short int m_savedCollisionFilterGroup; short int m_savedCollisionFilterMask; MT_Scalar m_savedMass; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 53b3e348a36..fb91c793765 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -259,10 +259,75 @@ void KX_Camera::ExtractFrustumSphere() if (m_set_frustum_center) return; - // The most extreme points on the near and far plane. (normalized device coords) - MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.); + // compute sphere for the general case and not only symmetric frustum: + // the mirror code in ImageRender can use very asymmetric frustum. + // We will put the sphere center on the line that goes from origin to the center of the far clipping plane + // This is the optimal position if the frustum is symmetric or very asymmetric and probably close + // to optimal for the general case. The sphere center position is computed so that the distance to + // the near and far extreme frustum points are equal. + + // get the transformation matrix from device coordinate to camera coordinate MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix; clip_camcs_matrix.invert(); + + // detect which of the corner of the far clipping plane is the farthest to the origin + MT_Vector4 nfar; // far point in device normalized coordinate + MT_Point3 farpoint; // most extreme far point in camera coordinate + MT_Point3 nearpoint;// most extreme near point in camera coordinate + MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate + MT_Scalar F=1.0, N; // square distance of far and near point to origin + MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0 + MT_Scalar e, s; // far and near clipping distance (<0) + MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance + MT_Scalar z; // projection of sphere center on z axis (<0) + // tmp value + MT_Vector4 npoint(1., 1., 1., 1.); + MT_Vector4 hpoint; + MT_Point3 point; + MT_Scalar len; + for (int i=0; i<4; i++) + { + hpoint = clip_camcs_matrix*npoint; + point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]); + len = point.dot(point); + if (len > F) + { + nfar = npoint; + farpoint = point; + F = len; + } + // rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane + len = npoint[0]; + npoint[0] = -npoint[1]; + npoint[1] = len; + farcenter += point; + } + // the far center is the average of the far clipping points + farcenter *= 0.25; + // the extreme near point is the opposite point on the near clipping plane + nfar.setValue(-nfar[0], -nfar[1], -1., 1.); + nfar = clip_camcs_matrix*nfar; + nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]); + N = nearpoint.dot(nearpoint); + e = farpoint[2]; + s = nearpoint[2]; + // projection on XY plane for distance to axis computation + MT_Point2 farxy(farpoint[0], farpoint[1]); + // f is forced positive by construction + f = farxy.length(); + // get corresponding point on the near plane + farxy *= s/e; + // this formula preserve the sign of n + n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length(); + c = MT_Point2(farcenter[0], farcenter[1]).length()/e; + // the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case + z = (F-N)/(2.0*(e-s+c*(f-n))); + m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z); + m_frustum_radius = m_frustum_center.distance(farpoint); + +#if 0 + // The most extreme points on the near and far plane. (normalized device coords) + MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.); // Transform to hom camera local space hnear = clip_camcs_matrix*hnear; @@ -273,10 +338,12 @@ void KX_Camera::ExtractFrustumSphere() MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]); // Compute center + // don't use camera data in case the user specifies the matrix directly m_frustum_center = MT_Point3(0., 0., - (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(m_camdata.m_clipend - m_camdata.m_clipstart))); + (nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/))); m_frustum_radius = m_frustum_center.distance(farpoint); - +#endif + // Transform to world space. m_frustum_center = GetCameraToWorld()(m_frustum_center); m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index a168beb9a70..e4a37b589a8 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -615,6 +615,7 @@ void KX_GameObject::setAngularVelocity(const MT_Vector3& ang_vel,bool local) m_pPhysicsController1->SetAngularVelocity(ang_vel,local); } + void KX_GameObject::ResolveCombinedVelocities( const MT_Vector3 & lin_vel, const MT_Vector3 & ang_vel, @@ -969,6 +970,10 @@ PyMethodDef KX_GameObject::Methods[] = { {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS}, {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O}, {"setWorldPosition", (PyCFunction) KX_GameObject::sPySetWorldPosition, METH_O}, + {"applyForce", (PyCFunction) KX_GameObject::sPyApplyForce, METH_VARARGS}, + {"applyTorque", (PyCFunction) KX_GameObject::sPyApplyTorque, METH_VARARGS}, + {"applyRotation", (PyCFunction) KX_GameObject::sPyApplyRotation, METH_VARARGS}, + {"applyMovement", (PyCFunction) KX_GameObject::sPyApplyMovement, METH_VARARGS}, {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS}, {"setLinearVelocity", (PyCFunction) KX_GameObject::sPySetLinearVelocity, METH_VARARGS}, {"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS}, @@ -1261,6 +1266,65 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr return SCA_IObject::_setattr(attr, value); } +PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args) +{ + int local = 0; + PyObject* pyvect; + + if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + MT_Vector3 force; + if (PyVecTo(pyvect, force)) { + ApplyForce(force, (local!=0)); + Py_RETURN_NONE; + } + } + return NULL; +} + +PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args) +{ + int local = 0; + PyObject* pyvect; + + if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + MT_Vector3 torque; + if (PyVecTo(pyvect, torque)) { + ApplyTorque(torque, (local!=0)); + Py_RETURN_NONE; + } + } + return NULL; +} + +PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args) +{ + int local = 0; + PyObject* pyvect; + + if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + MT_Vector3 rotation; + if (PyVecTo(pyvect, rotation)) { + ApplyRotation(rotation, (local!=0)); + Py_RETURN_NONE; + } + } + return NULL; +} + +PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args) +{ + int local = 0; + PyObject* pyvect; + + if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) { + MT_Vector3 movement; + if (PyVecTo(pyvect, movement)) { + ApplyMovement(movement, (local!=0)); + Py_RETURN_NONE; + } + } + return NULL; +} PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 20b15787d27..4f26031356f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -772,6 +772,10 @@ public: KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition); KX_PYMETHOD_O(KX_GameObject,SetPosition); KX_PYMETHOD_O(KX_GameObject,SetWorldPosition); + KX_PYMETHOD_VARARGS(KX_GameObject, ApplyForce); + KX_PYMETHOD_VARARGS(KX_GameObject, ApplyTorque); + KX_PYMETHOD_VARARGS(KX_GameObject, ApplyRotation); + KX_PYMETHOD_VARARGS(KX_GameObject, ApplyMovement); KX_PYMETHOD_VARARGS(KX_GameObject,GetLinearVelocity); KX_PYMETHOD_VARARGS(KX_GameObject,SetLinearVelocity); KX_PYMETHOD_VARARGS(KX_GameObject,GetAngularVelocity); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 4184202c518..8516049f6d8 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -184,7 +184,6 @@ private: void RenderDebugProperties(); void RenderShadowBuffers(KX_Scene *scene); void SetBackGround(KX_WorldInfo* worldinfo); - void SetWorldSettings(KX_WorldInfo* worldinfo); void DoSound(KX_Scene* scene); public: @@ -193,6 +192,7 @@ public: virtual ~KX_KetsjiEngine(); // set the devices and stuff. the client must take care of creating these + void SetWorldSettings(KX_WorldInfo* worldinfo); void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice); void SetMouseDevice(SCA_IInputDevice* mousedevice); void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice); @@ -205,6 +205,8 @@ public: void SetGame2IpoMode(bool game2ipo,int startFrame); RAS_IRasterizer* GetRasterizer(){return m_rasterizer;}; + RAS_ICanvas* GetCanvas(){return m_canvas;}; + RAS_IRenderTools* GetRenderTools(){return m_rendertools;}; ///returns true if an update happened to indicate -> Render bool NextFrame(); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index caa71441b1d..476a931355f 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1249,7 +1249,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam // If the camera is inside this node, then the object is visible. if (!vis) { - vis = gameobj->GetSGNode()->inside( GetActiveCamera()->GetCameraLocation() ); + vis = gameobj->GetSGNode()->inside( cam->GetCameraLocation() ); } // Test the object's bound sphere against the view frustum. diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index 505ce253dd1..efeffab2eed 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -123,6 +123,50 @@ class KX_GameObject: @return: The game object's rotation matrix @note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed. """ + def applyMovement(movement, local = 0): + """ + Sets the game object's movement. + + @type movement: 3d vector. + @param movement: movement vector. + @type local: boolean + @param local: - False: you get the "global" movement ie: relative to world orientation (default). + - True: you get the "local" movement ie: relative to object orientation. + """ + def applyRotation(movement, local = 0): + """ + Sets the game object's rotation. + + @type rotation: 3d vector. + @param rotation: rotation vector. + @type local: boolean + @param local: - False: you get the "global" rotation ie: relative to world orientation (default). + - True: you get the "local" rotation ie: relative to object orientation. + """ + def applyForce(force, local = 0): + """ + Sets the game object's force. + + This requires a dynamic object. + + @type force: 3d vector. + @param force: force vector. + @type local: boolean + @param local: - False: you get the "global" force ie: relative to world orientation (default). + - True: you get the "local" force ie: relative to object orientation. + """ + def applyTorque(torque, local = 0): + """ + Sets the game object's torque. + + This requires a dynamic object. + + @type torque: 3d vector. + @param torque: torque vector. + @type local: boolean + @param local: - False: you get the "global" torque ie: relative to world orientation (default). + - True: you get the "local" torque ie: relative to object orientation. + """ def getLinearVelocity(local = 0): """ Gets the game object's linear velocity. @@ -143,6 +187,8 @@ class KX_GameObject: This method sets game object's velocity through it's centre of mass, ie no angular velocity component. + This requires a dynamic object. + @type velocity: 3d vector. @param velocity: linear velocity vector. @type local: boolean @@ -163,6 +209,8 @@ class KX_GameObject: """ Sets the game object's angular velocity. + This requires a dynamic object. + @type velocity: 3d vector. @param velocity: angular velocity vector. @type local: boolean diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index d2cfa7d07f9..282c7306285 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -58,7 +58,7 @@ RAS_2DFilterManager::RAS_2DFilterManager(): texturewidth(-1), textureheight(-1), canvaswidth(-1), canvasheight(-1), -numberoffilters(0) +numberoffilters(0), need_tex_update(true) { isshadersupported = GLEW_ARB_shader_objects && GLEW_ARB_fragment_shader && GLEW_ARB_multitexture; @@ -217,50 +217,50 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex) glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); - if (uniformLoc != -1) - { + if (uniformLoc != -1) + { glUniform1iARB(uniformLoc, 0); - } + } - /* send depth texture to glsl program if it needs */ + /* send depth texture to glsl program if it needs */ if(texflag[passindex] & 0x1){ - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture"); - glActiveTextureARB(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, texname[1]); + uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture"); + glActiveTextureARB(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texname[1]); - if (uniformLoc != -1) - { - glUniform1iARB(uniformLoc, 1); - } - } + if (uniformLoc != -1) + { + glUniform1iARB(uniformLoc, 1); + } + } - /* send luminance texture to glsl program if it needs */ + /* send luminance texture to glsl program if it needs */ if(texflag[passindex] & 0x2){ - uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture"); - glActiveTextureARB(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, texname[2]); - - if (uniformLoc != -1) - { - glUniform1iARB(uniformLoc, 2); - } + uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture"); + glActiveTextureARB(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, texname[2]); + + if (uniformLoc != -1) + { + glUniform1iARB(uniformLoc, 2); + } } uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_TextureCoordinateOffset"); - if (uniformLoc != -1) - { - glUniform2fvARB(uniformLoc, 9, textureoffsets); - } + if (uniformLoc != -1) + { + glUniform2fvARB(uniformLoc, 9, textureoffsets); + } uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureWidth"); - if (uniformLoc != -1) - { + if (uniformLoc != -1) + { glUniform1fARB(uniformLoc,texturewidth); - } + } uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_RenderedTextureHeight"); - if (uniformLoc != -1) - { + if (uniformLoc != -1) + { glUniform1fARB(uniformLoc,textureheight); - } + } int i, objProperties = m_properties[passindex].size(); for(i=0; i<objProperties; i++) @@ -332,20 +332,20 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas) RAS_Rect canvas_rect = canvas->GetWindowArea(); canvaswidth = canvas->GetWidth(); canvasheight = canvas->GetHeight(); - texturewidth = canvaswidth; - textureheight = canvasheight; + texturewidth = canvaswidth + canvas_rect.GetLeft(); + textureheight = canvasheight + canvas_rect.GetBottom(); GLint i,j; i = 0; - while ((1 << i) <= texturewidth) - i++; - texturewidth = (1 << (i)); + while ((1 << i) <= texturewidth) + i++; + texturewidth = (1 << (i)); - // Now for height - i = 0; - while ((1 << i) <= textureheight) - i++; - textureheight = (1 << (i)); + // Now for height + i = 0; + while ((1 << i) <= textureheight) + i++; + textureheight = (1 << (i)); GLfloat xInc = 1.0f / (GLfloat)texturewidth; GLfloat yInc = 1.0f / (GLfloat)textureheight; @@ -360,6 +360,23 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas) } } +void RAS_2DFilterManager::UpdateCanvasTextureCoord(unsigned int * viewport) +{ + /* + This function update canvascoord[]. + These parameters are used to create texcoord[1] + That way we can access the texcoord relative to the canvas: + (0.0,0.0) bottom left, (1.0,1.0) top right, (0.5,0.5) center + */ + canvascoord[0] = (GLfloat) viewport[0] / viewport[2]; + canvascoord[0] *= -1; + canvascoord[1] = (GLfloat) (texturewidth - viewport[0]) / viewport[2]; + + canvascoord[2] = (GLfloat) viewport[1] / viewport[3]; + canvascoord[2] *= -1; + canvascoord[3] = (GLfloat)(textureheight - viewport[1]) / viewport[3]; +} + void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) { bool need_depth=false; @@ -387,27 +404,35 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) if(num_filters <= 0) return; + GLuint viewport[4]={0}; + glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); + if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight()) { UpdateOffsetMatrix(canvas); + UpdateCanvasTextureCoord((unsigned int*)viewport); + need_tex_update = true; + } + + if(need_tex_update) + { SetupTextures(need_depth, need_luminance); + need_tex_update = false; } - GLuint viewport[4]={0}; if(need_depth){ glActiveTextureARB(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texname[1]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, viewport[0], viewport[1], texturewidth,textureheight, 0); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0); } if(need_luminance){ glActiveTextureARB(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texname[2]); - glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, viewport[0], viewport[1] , texturewidth,textureheight, 0); + glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0, texturewidth,textureheight, 0); } - glGetIntegerv(GL_VIEWPORT,(GLint *)viewport); - glViewport(viewport[0],viewport[1], texturewidth, textureheight); + glViewport(0,0, texturewidth, textureheight); glDisable(GL_DEPTH_TEST); glMatrixMode(GL_TEXTURE); @@ -425,20 +450,15 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewport[0], viewport[1], texturewidth, textureheight, 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0); glClear(GL_COLOR_BUFFER_BIT); - float canvascoordx, canvascoordy; - - canvascoordx = (GLfloat) texturewidth / canvaswidth; - canvascoordy = (GLfloat) textureheight / canvasheight; - glBegin(GL_QUADS); glColor4f(1.f, 1.f, 1.f, 1.f); - glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, canvascoordy); glVertex2f(1,1); - glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, canvascoordy); glVertex2f(-1,1); - glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); glVertex2f(-1,-1); - glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE1_ARB, canvascoordx, 0.0); glVertex2f(1,-1); + glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[3]); glVertex2f(1,1); + glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[3]); glVertex2f(-1,1); + glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[2]); glVertex2f(-1,-1); + glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[2]); glVertex2f(1,-1); glEnd(); } } @@ -454,7 +474,7 @@ void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* game return; if(pass<0 || pass>=MAX_RENDER_PASS) return; - + need_tex_update = true; if(mode == RAS_2DFILTER_DISABLED) { m_enabled[pass] = 0; diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h index 454643a5077..6a420a974d4 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h @@ -44,7 +44,9 @@ private: void FreeTextures(); void UpdateOffsetMatrix(RAS_ICanvas* canvas); - + void UpdateCanvasTextureCoord(unsigned int * viewport); + + float canvascoord[4]; float textureoffsets[18]; float view[4]; /* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/ @@ -60,6 +62,7 @@ private: bool isshadersupported; bool errorprinted; + bool need_tex_update; unsigned int m_filters[MAX_RENDER_PASS]; short m_enabled[MAX_RENDER_PASS]; diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 9cb59f300f7..610bd13ff12 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -212,9 +212,6 @@ public : RAS_FrameFrustum &frustum ); - -private : - static void ComputeDefaultFrustum( @@ -225,6 +222,8 @@ private : RAS_FrameFrustum & frustum ); +private : + static void ComputeBestFitViewRect( diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 411b28fa3b7..b4b90c3608b 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -200,6 +200,7 @@ public: * @return true if stereo mode is enabled. */ virtual bool Stereo()=0; + virtual StereoMode GetStereoMode()=0; virtual bool InterlacedStereo()=0; /** * Sets which eye buffer subsequent primitives will be rendered to. diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 87a0a1d8b9e..3cad5fe74f2 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -406,14 +406,16 @@ void RAS_OpenGLRasterizer::SetRenderArea() break; } } - void RAS_OpenGLRasterizer::SetStereoMode(const StereoMode stereomode) { m_stereomode = stereomode; } - +RAS_IRasterizer::StereoMode RAS_OpenGLRasterizer::GetStereoMode() +{ + return m_stereomode; +} bool RAS_OpenGLRasterizer::Stereo() { @@ -775,7 +777,7 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix( float frustnear, float frustfar, float focallength, - bool + bool ){ MT_Matrix4x4 result; double mat[16]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 0717cce0ce8..d39fd642f86 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -137,6 +137,7 @@ public: virtual void SetRenderArea(); virtual void SetStereoMode(const StereoMode stereomode); + virtual RAS_IRasterizer::StereoMode GetStereoMode(); virtual bool Stereo(); virtual bool InterlacedStereo(); virtual void SetEye(const StereoEye eye); diff --git a/source/gameengine/VideoTexture/Exception.cpp b/source/gameengine/VideoTexture/Exception.cpp index 3f939de6bc2..8704d49f2a7 100644 --- a/source/gameengine/VideoTexture/Exception.cpp +++ b/source/gameengine/VideoTexture/Exception.cpp @@ -204,6 +204,12 @@ void registerAllExceptions(void) ImageSizesNotMatchDesc.registerDesc(); SceneInvalidDesc.registerDesc(); CameraInvalidDesc.registerDesc(); + ObserverInvalidDesc.registerDesc(); + MirrorInvalidDesc.registerDesc(); + MirrorSizeInvalidDesc.registerDesc(); + MirrorNormalInvalidDesc.registerDesc(); + MirrorHorizontalDesc.registerDesc(); + MirrorTooSmallDesc.registerDesc(); SourceVideoEmptyDesc.registerDesc(); SourceVideoCreationDesc.registerDesc(); } diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h index 5345e87f199..1a3c25071b1 100644 --- a/source/gameengine/VideoTexture/Exception.h +++ b/source/gameengine/VideoTexture/Exception.h @@ -202,6 +202,12 @@ extern ExpDesc MaterialNotAvailDesc; extern ExpDesc ImageSizesNotMatchDesc; extern ExpDesc SceneInvalidDesc; extern ExpDesc CameraInvalidDesc; +extern ExpDesc ObserverInvalidDesc; +extern ExpDesc MirrorInvalidDesc; +extern ExpDesc MirrorSizeInvalidDesc; +extern ExpDesc MirrorNormalInvalidDesc; +extern ExpDesc MirrorHorizontalDesc; +extern ExpDesc MirrorTooSmallDesc; extern ExpDesc SourceVideoEmptyDesc; extern ExpDesc SourceVideoCreationDesc; diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index a8f7871fa21..58697ed3cc7 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -24,96 +24,238 @@ http://www.gnu.org/copyleft/lesser.txt. #include <PyObjectPlus.h> #include <structmember.h> +#include <float.h> +#include <math.h> -#include <KX_BlenderCanvas.h> -#include <KX_BlenderRenderTools.h> -#include <RAS_IRasterizer.h> -#include <RAS_OpenGLRasterizer.h> -#include <KX_WorldInfo.h> -#include <KX_Light.h> -#include "ImageRender.h" +#include <BIF_gl.h> + +#include "KX_PythonInit.h" +#include "DNA_scene_types.h" +#include "RAS_CameraData.h" +#include "RAS_MeshObject.h" +#include "BLI_arithb.h" +#include "ImageRender.h" #include "ImageBase.h" #include "BlendType.h" #include "Exception.h" +#include "Texture.h" -ExceptionID SceneInvalid, CameraInvalid; +ExceptionID SceneInvalid, CameraInvalid, ObserverInvalid; +ExceptionID MirrorInvalid, MirrorSizeInvalid, MirrorNormalInvalid, MirrorHorizontal, MirrorTooSmall; ExpDesc SceneInvalidDesc (SceneInvalid, "Scene object is invalid"); ExpDesc CameraInvalidDesc (CameraInvalid, "Camera object is invalid"); - -#if 0 // not yet supported +ExpDesc ObserverInvalidDesc (ObserverInvalid, "Observer object is invalid"); +ExpDesc MirrorInvalidDesc (MirrorInvalid, "Mirror object is invalid"); +ExpDesc MirrorSizeInvalidDesc (MirrorSizeInvalid, "Mirror has no vertex or no size"); +ExpDesc MirrorNormalInvalidDesc (MirrorNormalInvalid, "Cannot determine mirror plane"); +ExpDesc MirrorHorizontalDesc (MirrorHorizontal, "Mirror is horizontal in local space"); +ExpDesc MirrorTooSmallDesc (MirrorTooSmall, "Mirror is too small"); // constructor -ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : m_scene(scene), -m_camera(camera) +ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : + ImageViewport(), + m_render(true), + m_scene(scene), + m_camera(camera), + m_owncamera(false), + m_observer(NULL), + m_mirror(NULL), + m_clip(100.f) { - // create screen area - m_area.winrct.xmin = m_upLeft[0]; - m_area.winrct.ymin = m_upLeft[1]; - m_area.winx = m_size[0]; - m_area.winy = m_size[1]; - // create canvas - m_canvas = new KX_BlenderCanvas(&m_area); - // create render tools - m_rendertools = new KX_BlenderRenderTools(); - // create rasterizer - m_rasterizer = new RAS_OpenGLRasterizer(m_canvas); - m_rasterizer->Init(); // initialize background colour - setBackground(0, 0, 255); - // refresh lights - refreshLights(); + setBackground(0, 0, 255, 255); + // retrieve rendering objects + m_engine = KX_GetActiveEngine(); + m_rasterizer = m_engine->GetRasterizer(); + m_canvas = m_engine->GetCanvas(); + m_rendertools = m_engine->GetRenderTools(); } // destructor ImageRender::~ImageRender (void) { - // release allocated objects - delete m_rasterizer; - delete m_rendertools; - delete m_canvas; + if (m_owncamera) + m_camera->Release(); } // set background color -void ImageRender::setBackground (unsigned char red, unsigned char green, unsigned char blue) +void ImageRender::setBackground (int red, int green, int blue, int alpha) { - m_background[0] = red; - m_background[1] = green; - m_background[2] = blue; - m_rasterizer->SetBackColor(m_background[0], m_background[1], m_background[2], 1.0); + m_background[0] = (red < 0) ? 0.f : (red > 255) ? 1.f : float(red)/255.f; + m_background[1] = (green < 0) ? 0.f : (green > 255) ? 1.f : float(green)/255.f; + m_background[2] = (blue < 0) ? 0.f : (blue > 255) ? 1.f : float(blue)/255.f; + m_background[3] = (alpha < 0) ? 0.f : (alpha > 255) ? 1.f : float(alpha)/255.f; } // capture image from viewport void ImageRender::calcImage (unsigned int texId) { - // setup camera - bool cameraPasive = !m_camera->GetViewport(); - // render scene - Render(); - // reset camera - if (cameraPasive) m_camera->EnableViewport(false); + if (m_rasterizer->GetDrawingMode() != RAS_IRasterizer::KX_TEXTURED || // no need for texture + m_camera->GetViewport() || // camera must be inactive + m_camera == m_scene->GetActiveCamera()) + { + // no need to compute texture in non texture rendering + m_avail = false; + return; + } + // render the scene from the camera + Render(); // get image from viewport ImageViewport::calcImage(texId); + // restore OpenGL state + m_canvas->EndFrame(); } void ImageRender::Render() { - // -} + RAS_FrameFrustum frustrum; + + if (!m_render) + return; + + if (m_mirror) + { + // mirror mode, compute camera frustrum, position and orientation + // convert mirror position and normal in world space + const MT_Matrix3x3 & mirrorObjWorldOri = m_mirror->GetSGNode()->GetWorldOrientation(); + const MT_Point3 & mirrorObjWorldPos = m_mirror->GetSGNode()->GetWorldPosition(); + const MT_Vector3 & mirrorObjWorldScale = m_mirror->GetSGNode()->GetWorldScaling(); + MT_Point3 mirrorWorldPos = + mirrorObjWorldPos + mirrorObjWorldScale * (mirrorObjWorldOri * m_mirrorPos); + MT_Vector3 mirrorWorldZ = mirrorObjWorldOri * m_mirrorZ; + // get observer world position + const MT_Point3 & observerWorldPos = m_observer->GetSGNode()->GetWorldPosition(); + // get plane D term = mirrorPos . normal + MT_Scalar mirrorPlaneDTerm = mirrorWorldPos.dot(mirrorWorldZ); + // compute distance of observer to mirror = D - observerPos . normal + MT_Scalar observerDistance = mirrorPlaneDTerm - observerWorldPos.dot(mirrorWorldZ); + // if distance < 0.01 => observer is on wrong side of mirror, don't render + if (observerDistance < 0.01f) + return; + // set camera world position = observerPos + normal * 2 * distance + MT_Point3 cameraWorldPos = observerWorldPos + (MT_Scalar(2.0)*observerDistance)*mirrorWorldZ; + m_camera->GetSGNode()->SetLocalPosition(cameraWorldPos); + // set camera orientation: z=normal, y=mirror_up in world space, x= y x z + MT_Vector3 mirrorWorldY = mirrorObjWorldOri * m_mirrorY; + MT_Vector3 mirrorWorldX = mirrorObjWorldOri * m_mirrorX; + MT_Matrix3x3 cameraWorldOri( + mirrorWorldX[0], mirrorWorldY[0], mirrorWorldZ[0], + mirrorWorldX[1], mirrorWorldY[1], mirrorWorldZ[1], + mirrorWorldX[2], mirrorWorldY[2], mirrorWorldZ[2]); + m_camera->GetSGNode()->SetLocalOrientation(cameraWorldOri); + m_camera->GetSGNode()->UpdateWorldData(0.0); + // compute camera frustrum: + // get position of mirror relative to camera: offset = mirrorPos-cameraPos + MT_Vector3 mirrorOffset = mirrorWorldPos - cameraWorldPos; + // convert to camera orientation + mirrorOffset = mirrorOffset * cameraWorldOri; + // scale mirror size to world scale: + // get closest local axis for mirror Y and X axis and scale height and width by local axis scale + MT_Scalar x, y; + x = fabs(m_mirrorY[0]); + y = fabs(m_mirrorY[1]); + float height = (x > y) ? + ((x > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorY[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + x = fabs(m_mirrorX[0]); + y = fabs(m_mirrorX[1]); + float width = (x > y) ? + ((x > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[0] : mirrorObjWorldScale[2]): + ((y > fabs(m_mirrorX[2])) ? mirrorObjWorldScale[1] : mirrorObjWorldScale[2]); + width *= m_mirrorHalfWidth; + height *= m_mirrorHalfHeight; + // left = offsetx-width + // right = offsetx+width + // top = offsety+height + // bottom = offsety-height + // near = -offsetz + // far = near+100 + frustrum.x1 = mirrorOffset[0]-width; + frustrum.x2 = mirrorOffset[0]+width; + frustrum.y1 = mirrorOffset[1]-height; + frustrum.y2 = mirrorOffset[1]+height; + frustrum.camnear = -mirrorOffset[2]; + frustrum.camfar = -mirrorOffset[2]+m_clip; + } + const float ortho = 100.0; + const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode(); + + // The screen area that ImageViewport will copy is also the rendering zone + m_canvas->SetViewPort(m_position[0], m_position[1], m_position[0]+m_capSize[0]-1, m_position[1]+m_capSize[1]-1); + m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]); + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER); + m_rasterizer->BeginFrame(RAS_IRasterizer::KX_TEXTURED,m_engine->GetClockTime()); + m_rendertools->BeginFrame(m_rasterizer); + m_engine->SetWorldSettings(m_scene->GetWorldInfo()); + m_rendertools->SetAuxilaryClientInfo(m_scene); + m_rasterizer->DisplayFog(); + // matrix calculation, don't apply any of the stereo mode + m_rasterizer->SetStereoMode(RAS_IRasterizer::RAS_STEREO_NOSTEREO); + if (m_mirror) + { + // frustrum was computed above + // get frustrum matrix and set projection matrix + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } else if (m_camera->hasValidProjectionMatrix()) + { + m_rasterizer->SetProjectionMatrix(m_camera->GetProjectionMatrix()); + } else + { + float lens = m_camera->GetLens(); + bool orthographic = !m_camera->GetCameraData()->m_perspective; + float nearfrust = m_camera->GetCameraNear(); + float farfrust = m_camera->GetCameraFar(); + float aspect_ratio = 1.0f; + Scene *blenderScene = m_scene->GetBlenderScene(); + + if (orthographic) { + lens *= ortho; + nearfrust = (nearfrust + 1.0)*ortho; + farfrust *= ortho; + } + // compute the aspect ratio from frame blender scene settings so that render to texture + // works the same in Blender and in Blender player + if (blenderScene->r.ysch != 0) + aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch); + + RAS_FramingManager::ComputeDefaultFrustum( + nearfrust, + farfrust, + lens, + aspect_ratio, + frustrum); + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar); + + m_camera->SetProjectionMatrix(projmat); + } -// refresh lights -void ImageRender::refreshLights (void) -{ - // clear lights list - //m_rendertools->RemoveAllLights(); - // set lights - //for (int idx = 0; idx < scene->GetLightList()->GetCount(); ++idx) - // m_rendertools->AddLight(((KX_LightObject*)(scene->GetLightList()->GetValue(idx)))->GetLightData()); -} + MT_Transform camtrans(m_camera->GetWorldToCamera()); + if (!m_camera->GetCameraData()->m_perspective) + camtrans.getOrigin()[2] *= ortho; + MT_Matrix4x4 viewmat(camtrans); + + m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(), + m_camera->GetCameraLocation(), m_camera->GetCameraOrientation()); + m_camera->SetModelviewMatrix(viewmat); + // restore the stereo mode now that the matrix is computed + m_rasterizer->SetStereoMode(stereomode); + + // do not update the mesh, we don't want to do it more than once per frame + //m_scene->UpdateMeshTransformations(); + m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera); + + m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); +} // cast Image pointer to ImageRender @@ -174,26 +316,31 @@ static int ImageRender_init (PyObject * pySelf, PyObject * args, PyObject * kwds // get background color PyObject * getBackground (PyImage * self, void * closure) { - return Py_BuildValue("[BBB]", getImageRender(self)->getBackground()[0], - getImageRender(self)->getBackground()[1], getImageRender(self)->getBackground()[2]); + return Py_BuildValue("[BBBB]", + getImageRender(self)->getBackground(0), + getImageRender(self)->getBackground(1), + getImageRender(self)->getBackground(2), + getImageRender(self)->getBackground(3)); } // set color static int setBackground (PyImage * self, PyObject * value, void * closure) { // check validity of parameter - if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 3 + if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 4 || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 0)) || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 1)) - || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2))) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 2)) + || !PyInt_Check(PySequence_Fast_GET_ITEM(value, 3))) { - PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 3 ints"); + PyErr_SetString(PyExc_TypeError, "The value must be a sequence of 4 integer between 0 and 255"); return -1; } // set background color getImageRender(self)->setBackground((unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 0))), (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1))), - (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2)))); + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 2))), + (unsigned char)(PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 3)))); // success return 0; } @@ -209,6 +356,10 @@ static PyMethodDef imageRenderMethods[] = static PyGetSetDef imageRenderGetSets[] = { {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, // attributes from ImageBase class {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, @@ -263,5 +414,329 @@ PyTypeObject ImageRenderType = Image_allocNew, /* tp_new */ }; +// object initialization +static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds) +{ + // parameters - scene object + PyObject * scene; + // reference object for mirror + PyObject * observer; + // object holding the mirror + PyObject * mirror; + // material of the mirror + short materialID = 0; + // parameter keywords + static char *kwlist[] = {"scene", "observer", "mirror", "material", NULL}; + // get parameters + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|h", kwlist, &scene, &observer, &mirror, &materialID)) + return -1; + try + { + // get scene pointer + KX_Scene * scenePtr (NULL); + if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type)) + scenePtr = static_cast<KX_Scene*>(scene); + else + THRWEXCP(SceneInvalid, S_OK); + + // get observer pointer + KX_GameObject * observerPtr (NULL); + if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type)) + observerPtr = static_cast<KX_GameObject*>(observer); + else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type)) + observerPtr = static_cast<KX_Camera*>(observer); + else + THRWEXCP(ObserverInvalid, S_OK); + + // get mirror pointer + KX_GameObject * mirrorPtr (NULL); + if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type)) + mirrorPtr = static_cast<KX_GameObject*>(mirror); + else + THRWEXCP(MirrorInvalid, S_OK); + + // locate the material in the mirror + RAS_IPolyMaterial * material = getMaterial(mirror, materialID); + if (material == NULL) + THRWEXCP(MaterialNotAvail, S_OK); + + // get pointer to image structure + PyImage * self = reinterpret_cast<PyImage*>(pySelf); + + // create source object + if (self->m_image != NULL) + { + delete self->m_image; + self->m_image = NULL; + } + self->m_image = new ImageRender(scenePtr, observerPtr, mirrorPtr, material); + } + catch (Exception & exp) + { + exp.report(); + return -1; + } + // initialization succeded + return 0; +} + +// get background color +PyObject * getClip (PyImage * self, void * closure) +{ + return PyFloat_FromDouble(getImageRender(self)->getClip()); +} + +// set clip +static int setClip (PyImage * self, PyObject * value, void * closure) +{ + // check validity of parameter + double clip; + if (value == NULL || !PyFloat_Check(value) || (clip = PyFloat_AsDouble(value)) < 0.01 || clip > 5000.0) + { + PyErr_SetString(PyExc_TypeError, "The value must be an float between 0.01 and 5000"); + return -1; + } + // set background color + getImageRender(self)->setClip(float(clip)); + // success + return 0; +} + +// attributes structure +static PyGetSetDef imageMirrorGetSets[] = +{ + {(char*)"clip", (getter)getClip, (setter)setClip, (char*)"clipping distance", NULL}, + // attribute from ImageRender + {(char*)"background", (getter)getBackground, (setter)setBackground, (char*)"background color", NULL}, + // attribute from ImageViewport + {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of render area", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, + {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to render", NULL}, + // attributes from ImageBase class + {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, + {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, + {(char*)"scale", (getter)Image_getScale, (setter)Image_setScale, (char*)"fast scale of image (near neighbour)", NULL}, + {(char*)"flip", (getter)Image_getFlip, (setter)Image_setFlip, (char*)"flip image vertically", NULL}, + {(char*)"filter", (getter)Image_getFilter, (setter)Image_setFilter, (char*)"pixel filter", NULL}, + {NULL} +}; + + +// constructor +ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) : + ImageViewport(), + m_render(false), + m_scene(scene), + m_observer(observer), + m_mirror(mirror), + m_clip(100.f) +{ + // this constructor is used for automatic planar mirror + // create a camera, take all data by default, in any case we will recompute the frustrum on each frame + RAS_CameraData camdata; + vector<RAS_TexVert*> mirrorVerts; + vector<RAS_TexVert*>::iterator it; + float mirrorArea = 0.f; + float mirrorNormal[3] = {0.f, 0.f, 0.f}; + float mirrorUp[3]; + float dist, vec[3], axis[3]; + float zaxis[3] = {0.f, 0.f, 1.f}; + float yaxis[3] = {0.f, 1.f, 0.f}; + float mirrorMat[3][3]; + float left, right, top, bottom, back; + + m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata); + m_camera->SetName("__mirror__cam__"); + // don't add the camera to the scene object list, it doesn't need to be accessible + m_owncamera = true; + // retrieve rendering objects + m_engine = KX_GetActiveEngine(); + m_rasterizer = m_engine->GetRasterizer(); + m_canvas = m_engine->GetCanvas(); + m_rendertools = m_engine->GetRenderTools(); + // locate the vertex assigned to mat and do following calculation in mesh coordinates + for (int meshIndex = 0; meshIndex < mirror->GetMeshCount(); meshIndex++) + { + RAS_MeshObject* mesh = mirror->GetMesh(meshIndex); + int numPolygons = mesh->NumPolygons(); + for (int polygonIndex=0; polygonIndex < numPolygons; polygonIndex++) + { + RAS_Polygon* polygon = mesh->GetPolygon(polygonIndex); + if (polygon->GetMaterial()->GetPolyMaterial() == mat) + { + RAS_TexVert *v1, *v2, *v3, *v4; + float normal[3]; + float area; + // this polygon is part of the mirror, + v1 = polygon->GetVertex(0); + v2 = polygon->GetVertex(1); + v3 = polygon->GetVertex(2); + mirrorVerts.push_back(v1); + mirrorVerts.push_back(v2); + mirrorVerts.push_back(v3); + if (polygon->VertexCount() == 4) + { + v4 = polygon->GetVertex(3); + mirrorVerts.push_back(v4); + area = CalcNormFloat4((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), (float*)v4->getXYZ(), normal); + } else + { + area = CalcNormFloat((float*)v1->getXYZ(), (float*)v2->getXYZ(), (float*)v3->getXYZ(), normal); + } + area = fabs(area); + mirrorArea += area; + VecMulf(normal, area); + VecAddf(mirrorNormal, mirrorNormal, normal); + } + } + } + if (mirrorVerts.size() == 0 || mirrorArea < FLT_EPSILON) + { + // no vertex or zero size mirror + THRWEXCP(MirrorSizeInvalid, S_OK); + } + // compute average normal of mirror faces + VecMulf(mirrorNormal, 1.0f/mirrorArea); + if (Normalize(mirrorNormal) == 0.f) + { + // no normal + THRWEXCP(MirrorNormalInvalid, S_OK); + } + // the mirror plane has an equation of the type ax+by+cz = d where (a,b,c) is the normal vector + // if the mirror is more vertical then horizontal, the Z axis is the up direction. + // otherwise the Y axis is the up direction. + // If the mirror is not perfectly vertical(horizontal), the Z(Y) axis projection on the mirror + // plan by the normal will be the up direction. + if (fabs(mirrorNormal[2]) > fabs(mirrorNormal[1]) && + fabs(mirrorNormal[2]) > fabs(mirrorNormal[0])) + { + // the mirror is more horizontal than vertical + VecCopyf(axis, yaxis); + } + else + { + // the mirror is more vertical than horizontal + VecCopyf(axis, zaxis); + } + dist = Inpf(mirrorNormal, axis); + if (fabs(dist) < FLT_EPSILON) + { + // the mirror is already fully aligned with up axis + VecCopyf(mirrorUp, axis); + } + else + { + // projection of axis to mirror plane through normal + VecCopyf(vec, mirrorNormal); + VecMulf(vec, dist); + VecSubf(mirrorUp, axis, vec); + if (Normalize(mirrorUp) == 0.f) + { + // should not happen + THRWEXCP(MirrorHorizontal, S_OK); + return; + } + } + // compute rotation matrix between local coord and mirror coord + // to match camera orientation, we select mirror z = -normal, y = up, x = y x z + VecCopyf(mirrorMat[2], mirrorNormal); + VecMulf(mirrorMat[2], -1.0f); + VecCopyf(mirrorMat[1], mirrorUp); + Crossf(mirrorMat[0], mirrorMat[1], mirrorMat[2]); + // transpose to make it a orientation matrix from local space to mirror space + Mat3Transp(mirrorMat); + // transform all vertex to plane coordinates and determine mirror position + left = FLT_MAX; + right = -FLT_MAX; + bottom = FLT_MAX; + top = -FLT_MAX; + back = -FLT_MAX; // most backward vertex (=highest Z coord in mirror space) + for (it = mirrorVerts.begin(); it != mirrorVerts.end(); it++) + { + VecCopyf(vec, (float*)(*it)->getXYZ()); + Mat3MulVecfl(mirrorMat, vec); + if (vec[0] < left) + left = vec[0]; + if (vec[0] > right) + right = vec[0]; + if (vec[1] < bottom) + bottom = vec[1]; + if (vec[1] > top) + top = vec[1]; + if (vec[2] > back) + back = vec[2]; + } + // now store this information in the object for later rendering + m_mirrorHalfWidth = (right-left)*0.5f; + m_mirrorHalfHeight = (top-bottom)*0.5f; + if (m_mirrorHalfWidth < 0.01f || m_mirrorHalfHeight < 0.01f) + { + // mirror too small + THRWEXCP(MirrorTooSmall, S_OK); + } + // mirror position in mirror coord + vec[0] = (left+right)*0.5f; + vec[1] = (top+bottom)*0.5f; + vec[2] = back; + // convert it in local space: transpose again the matrix to get back to mirror to local transform + Mat3Transp(mirrorMat); + Mat3MulVecfl(mirrorMat, vec); + // mirror position in local space + m_mirrorPos.setValue(vec[0], vec[1], vec[2]); + // mirror normal vector (pointed towards the back of the mirror) in local space + m_mirrorZ.setValue(-mirrorNormal[0], -mirrorNormal[1], -mirrorNormal[2]); + m_mirrorY.setValue(mirrorUp[0], mirrorUp[1], mirrorUp[2]); + m_mirrorX = m_mirrorY.cross(m_mirrorZ); + m_render = true; + + setBackground(0, 0, 255, 255); +} + + + + +// define python type +PyTypeObject ImageMirrorType = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "VideoTexture.ImageMirror", /*tp_name*/ + sizeof(PyImage), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Image_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "Image source from mirror", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + imageRenderMethods, /* tp_methods */ + 0, /* tp_members */ + imageMirrorGetSets, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)ImageMirror_init, /* tp_init */ + 0, /* tp_alloc */ + Image_allocNew, /* tp_new */ +}; + -#endif // #if 0 diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h index 66255f04d2c..c94e2f1e718 100644 --- a/source/gameengine/VideoTexture/ImageRender.h +++ b/source/gameengine/VideoTexture/ImageRender.h @@ -42,42 +42,56 @@ class ImageRender : public ImageViewport public: /// constructor ImageRender (KX_Scene * scene, KX_Camera * camera); + ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat); /// destructor virtual ~ImageRender (void); /// get background color - unsigned char * getBackground (void) { return m_background; } + int getBackground (int idx) { return (idx < 0 || idx > 3) ? 0 : int(m_background[idx]*255.f); } /// set background color - void setBackground (unsigned char red, unsigned char green, unsigned char blue); + void setBackground (int red, int green, int blue, int alpha); + + /// clipping distance + float getClip (void) { return m_clip; } + /// set whole buffer use + void setClip (float clip) { m_clip = clip; } protected: + /// true if ready to render + bool m_render; /// rendered scene KX_Scene * m_scene; /// camera for render KX_Camera * m_camera; - - /// screen area for rendering - ScrArea m_area; - /// rendering device - RAS_ICanvas * m_canvas; - /// rasterizer - RAS_IRasterizer * m_rasterizer; - /// render tools - RAS_IRenderTools * m_rendertools; + /// do we own the camera? + bool m_owncamera; + /// for mirror operation + KX_GameObject * m_observer; + KX_GameObject * m_mirror; + float m_clip; // clipping distance + float m_mirrorHalfWidth; // mirror width in mirror space + float m_mirrorHalfHeight; // mirror height in mirror space + MT_Point3 m_mirrorPos; // mirror center position in local space + MT_Vector3 m_mirrorZ; // mirror Z axis in local space + MT_Vector3 m_mirrorY; // mirror Y axis in local space + MT_Vector3 m_mirrorX; // mirror X axis in local space + /// canvas + RAS_ICanvas* m_canvas; + /// rasterizer + RAS_IRasterizer* m_rasterizer; + /// render tools + RAS_IRenderTools* m_rendertools; + /// engine + KX_KetsjiEngine* m_engine; /// background colour - unsigned char m_background[3]; + float m_background[4]; /// render 3d scene to image virtual void calcImage (unsigned int texId); - /// refresh lights - void refreshLights (void); - /// methods from KX_KetsjiEngine - bool BeginFrame(); - void EndFrame(); void Render(); void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam); void RenderFrame(KX_Scene* scene, KX_Camera* cam); diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index deb66ffb6ba..4c2c81e2208 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -34,12 +34,12 @@ http://www.gnu.org/copyleft/lesser.txt. // constructor -ImageViewport::ImageViewport (void) : m_texInit(false) +ImageViewport::ImageViewport (void) : m_alpha(false), m_texInit(false) { // get viewport rectangle glGetIntegerv(GL_VIEWPORT, m_viewport); // create buffer for viewport image - m_viewportImage = new BYTE [3 * getViewportSize()[0] * getViewportSize()[1]]; + m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]]; // set attributes setWhole(false); } @@ -62,7 +62,7 @@ void ImageViewport::setWhole (bool whole) m_capSize[idx] = whole ? short(getViewportSize()[idx]) : calcSize(short(getViewportSize()[idx])); // position - m_position[idx] = whole ? 0 : (getViewportSize()[idx] - m_capSize[idx]) >> 1; + m_position[idx] = whole ? 0 : ((getViewportSize()[idx] - m_capSize[idx]) >> 1); } // init image init(m_capSize[0], m_capSize[1]); @@ -123,20 +123,31 @@ void ImageViewport::calcImage (unsigned int texId) && m_capSize[1] == calcSize(m_capSize[1]) && !m_flip) { // just copy current viewport to texture - glBindTexture(GL_TEXTURE_2D, texId); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]); - // image is not available - m_avail = false; + glBindTexture(GL_TEXTURE_2D, texId); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1]); + // image is not available + m_avail = false; } // otherwise copy viewport to buffer, if image is not available else if (!m_avail) { // get frame buffer data - glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB, - GL_UNSIGNED_BYTE, m_viewportImage); - // filter loaded data - FilterRGB24 filt; - filterImage(filt, m_viewportImage, m_capSize); + if (m_alpha) + { + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA, + GL_UNSIGNED_BYTE, m_viewportImage); + // filter loaded data + FilterRGBA32 filt; + filterImage(filt, m_viewportImage, m_capSize); + } + else + { + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB, + GL_UNSIGNED_BYTE, m_viewportImage); + // filter loaded data + FilterRGB24 filt; + filterImage(filt, m_viewportImage, m_capSize); + } } } @@ -151,14 +162,14 @@ inline ImageViewport * getImageViewport (PyImage * self) // get whole -static PyObject * ImageViewport_getWhole (PyImage * self, void * closure) +PyObject * ImageViewport_getWhole (PyImage * self, void * closure) { if (self->m_image != NULL && getImageViewport(self)->getWhole()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } // set whole -static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure) +int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure) { // check parameter, report failure if (value == NULL || !PyBool_Check(value)) @@ -172,6 +183,28 @@ static int ImageViewport_setWhole (PyImage * self, PyObject * value, void * clos return 0; } +// get alpha +PyObject * ImageViewport_getAlpha (PyImage * self, void * closure) +{ + if (self->m_image != NULL && getImageViewport(self)->getAlpha()) Py_RETURN_TRUE; + else Py_RETURN_FALSE; +} + +// set whole +int ImageViewport_setAlpha (PyImage * self, PyObject * value, void * closure) +{ + // check parameter, report failure + if (value == NULL || !PyBool_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "The value must be a bool"); + return -1; + } + // set alpha + if (self->m_image != NULL) getImageViewport(self)->setAlpha(value == Py_True); + // success + return 0; +} + // get position static PyObject * ImageViewport_getPosition (PyImage * self, void * closure) @@ -202,14 +235,14 @@ static int ImageViewport_setPosition (PyImage * self, PyObject * value, void * c } // get capture size -static PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure) +PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure) { return Py_BuildValue("(ii)", getImageViewport(self)->getCaptureSize()[0], getImageViewport(self)->getCaptureSize()[1]); } // set capture size -static int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure) +int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure) { // check validity of parameter if (value == NULL || !PySequence_Check(value) || PySequence_Length(value) != 2 @@ -242,6 +275,7 @@ static PyGetSetDef imageViewportGetSets[] = {(char*)"whole", (getter)ImageViewport_getWhole, (setter)ImageViewport_setWhole, (char*)"use whole viewport to capture", NULL}, {(char*)"position", (getter)ImageViewport_getPosition, (setter)ImageViewport_setPosition, (char*)"upper left corner of captured area", NULL}, {(char*)"capsize", (getter)ImageViewport_getCaptureSize, (setter)ImageViewport_setCaptureSize, (char*)"size of viewport area being captured", NULL}, + {(char*)"alpha", (getter)ImageViewport_getAlpha, (setter)ImageViewport_setAlpha, (char*)"use alpha in texture", NULL}, // attributes from ImageBase class {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, diff --git a/source/gameengine/VideoTexture/ImageViewport.h b/source/gameengine/VideoTexture/ImageViewport.h index 4265906b8f5..0449249cf95 100644 --- a/source/gameengine/VideoTexture/ImageViewport.h +++ b/source/gameengine/VideoTexture/ImageViewport.h @@ -43,6 +43,12 @@ public: bool getWhole (void) { return m_whole; } /// set whole buffer use void setWhole (bool whole); + + /// is alpha channel used + bool getAlpha (void) { return m_alpha; } + /// set whole buffer use + void setAlpha (bool alpha) { m_alpha = alpha; } + /// get capture size in viewport short * getCaptureSize (void) { return m_capSize; } /// set capture size in viewport @@ -61,6 +67,8 @@ protected: short m_capSize[2]; /// use whole viewport bool m_whole; + /// use alpha channel + bool m_alpha; /// position of capture rectangle in viewport GLint m_position[2]; @@ -79,6 +87,12 @@ protected: GLint * getViewportSize (void) { return m_viewport + 2; } }; +PyObject * ImageViewport_getCaptureSize (PyImage * self, void * closure); +int ImageViewport_setCaptureSize (PyImage * self, PyObject * value, void * closure); +PyObject * ImageViewport_getWhole (PyImage * self, void * closure); +int ImageViewport_setWhole (PyImage * self, PyObject * value, void * closure); +PyObject * ImageViewport_getAlpha (PyImage * self, void * closure); +int ImageViewport_setAlpha (PyImage * self, PyObject * value, void * closure); #endif diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index 3c371e51537..1bbef8f0f9e 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -32,6 +32,7 @@ http://www.gnu.org/copyleft/lesser.txt. #include "ImageBase.h" #include "BlendType.h" +#include "Exception.h" // type Texture declaration @@ -82,5 +83,10 @@ RAS_IPolyMaterial * getMaterial (PyObject *obj, short matID); // get material ID short getMaterialID (PyObject * obj, char * name); +// Exceptions +extern ExceptionID MaterialNotAvail; + +// object type +extern BlendType<KX_GameObject> gameObjectType; #endif diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index b38882f8164..ec066811a52 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -132,6 +132,7 @@ extern PyTypeObject FilterBGR24Type; extern PyTypeObject ImageBuffType; extern PyTypeObject ImageMixType; extern PyTypeObject ImageRenderType; +extern PyTypeObject ImageMirrorType; extern PyTypeObject ImageViewportType; extern PyTypeObject ImageViewportType; @@ -144,7 +145,8 @@ static void registerAllTypes(void) #endif pyImageTypes.add(&ImageBuffType, "ImageBuff"); pyImageTypes.add(&ImageMixType, "ImageMix"); - //pyImageTypes.add(&ImageRenderType, "ImageRender"); + pyImageTypes.add(&ImageRenderType, "ImageRender"); + pyImageTypes.add(&ImageMirrorType, "ImageMirror"); pyImageTypes.add(&ImageViewportType, "ImageViewport"); pyFilterTypes.add(&FilterBlueScreenType, "FilterBlueScreen"); diff --git a/source/nan_compile.mk b/source/nan_compile.mk index 4b13ef8f678..19d833b5b0d 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -120,22 +120,34 @@ ifeq ($(OS),freebsd) endif ifeq ($(OS),irix) - CC = cc - CCC = CC - CFLAGS += -n32 -mips3 -Xcpluscomm - CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std -ifdef MIPS73_ISOHEADERS - CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS) -else - CCFLAGS += -LANG:libc_in_namespace_std=off -endif - REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 - REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 + ifeq ($(IRIX_USE_GCC),true) + CC = gcc + CCC = g++ + CFLAGS += -fPIC -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4 + CCFLAGS += -fPIC -fpermissive -funsigned-char -fno-strict-aliasing -mabi=n32 -mips4 + REL_CFLAGS += -O2 + REL_CCFLAGS += -O2 + CPPFLAGS += -DXP_UNIX + DBG_CFLAGS += -g3 -gdwarf-2 -ggdb + DBG_CCFLAGS += -g3 -gdwarf-2 -ggdb + else + CC = cc + CCC = CC + CFLAGS += -n32 -mips3 -Xcpluscomm + CCFLAGS += -n32 -mips3 -Xcpluscomm -LANG:std + ifdef MIPS73_ISOHEADERS + CCFLAGS += -LANG:libc_in_namespace_std=off -I$(MIPS73_ISOHEADERS) + else + CCFLAGS += -LANG:libc_in_namespace_std=off + endif + REL_CFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 + REL_CCFLAGS += -n32 -mips3 -O2 -OPT:Olimit=0 + endif OPENGL_HEADERS = /usr/include NAN_DEPEND = true AR = CC ARFLAGS = -ar -o - ARFLAGSQUIET = -ar -o + ARFLAGSQUIET = -ar -o endif ifeq ($(OS),linux) diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index 424a7c558d7..04a1d107931 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -75,6 +75,7 @@ else export NAN_SOLID ?= $(LCGDIR)/solid export NAN_QHULL ?= $(LCGDIR)/qhull endif + export NAN_USE_BULLET ?= true export NAN_BULLET2 ?= $(LCGDIR)/bullet2 export NAN_SUMO ?= $(SRCHOME)/gameengine/Physics/Sumo export NAN_FUZZICS ?= $(SRCHOME)/gameengine/Physics/Sumo/Fuzzics @@ -83,7 +84,7 @@ endif export NAN_GUARDEDALLOC ?= $(LCGDIR)/guardedalloc export NAN_IKSOLVER ?= $(LCGDIR)/iksolver export NAN_BSP ?= $(LCGDIR)/bsp - export NAN_BOOLOP ?= $(LCGDIR)/boolop + export NAN_BOOLOP ?= $(LCGDIR)/boolop export NAN_SOUNDSYSTEM ?= $(LCGDIR)/SoundSystem export NAN_STRING ?= $(LCGDIR)/string export NAN_MEMUTIL ?= $(LCGDIR)/memutil @@ -116,7 +117,7 @@ endif export WITH_DDS ?= true ifeq ($(OS),windows) - export NAN_WINTAB ?= $(LCGDIR)/wintab + export NAN_WINTAB ?= $(LCGDIR)/wintab ifeq ($(FREE_WINDOWS), true) export NAN_PTHREADS ?= $(LCGDIR)/pthreads export NAN_OPENEXR ?= $(LCGDIR)/gcc/openexr @@ -129,28 +130,34 @@ endif endif else ifeq ($(OS),darwin) - export NAN_OPENEXR ?= $(LCGDIR)/openexr - ifeq ($(CPU),powerpc) - export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a - else - export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a - endif + export NAN_OPENEXR ?= $(LCGDIR)/openexr + ifeq ($(CPU),powerpc) + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a + else + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a + endif else ifeq ($(OS),linux) - ifeq ($(WITH_OPENEXR), true) - NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR ) - NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR ) - NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" ))) - endif + ifeq ($(WITH_OPENEXR), true) + NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR ) + NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR ) + NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" ))) + endif else ifeq ($(OS), solaris) # this only exists at the moment for i386-64 CPU Types at the moment export NAN_OPENEXR ?= $(LCGDIR)/openexr - export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a -lrt else - export NAN_OPENEXR ?= /usr/local - export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a + ifeq ($(OS), irix) + ifeq ($(IRIX_USE_GCC), true) + export NAN_OPENEXR ?= $(LCGDIR)/openexr/gcc + else + export NAN_OPENEXR ?= $(LCGDIR)/openexr + endif + endif + export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a $(NAN_OPENEXR)/lib/libIlmThread.a endif endif endif @@ -331,23 +338,27 @@ endif export NAN_PYTHON ?= $(LCGDIR)/python export NAN_PYTHON_VERSION ?= 2.3 export NAN_PYTHON_BINARY ?= $(NAN_PYTHON)/bin/python$(NAN_PYTHON_VERSION) - export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a + export NAN_PYTHON_LIB ?= $(NAN_PYTHON)/lib/python$(NAN_PYTHON_VERSION)/config/libpython$(NAN_PYTHON_VERSION).a -lpthread export NAN_OPENAL ?= $(LCGDIR)/openal export NAN_FMOD ?= $(LCGDIR)/fmod export NAN_JPEG ?= $(LCGDIR)/jpeg export NAN_PNG ?= $(LCGDIR)/png - export NAN_TIFF ?= /usr/freeware + export NAN_TIFF ?= $(LCGDIR)/tiff export NAN_ODE ?= $(LCGDIR)/ode export NAN_TERRAPLAY ?= $(LCGDIR)/terraplay export NAN_MESA ?= /usr/src/Mesa-3.1 - export NAN_ZLIB ?= /usr/freeware + export NAN_ZLIB ?= $(LCGDIR)/zlib export NAN_NSPR ?= $(LCGDIR)/nspr - export NAN_FREETYPE ?= /usr/freeware - export NAN_GETTEXT ?= /usr/freeware - export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib32/libintl.a + export NAN_FREETYPE ?= $(LCGDIR)/freetype + export NAN_ICONV ?= $(LCGDIR)/iconv + export NAN_GETTEXT ?= $(LCGDIR)/gettext + export NAN_GETTEXT_LIB ?= $(NAN_GETTEXT)/lib/libintl.a $(NAN_ICONV)/lib/libiconv.a export NAN_SDL ?= $(LCGDIR)/sdl - export NAN_SDLLIBS ?= -L$(NAN_SDL)/lib -lSDL + export NAN_SDLLIBS ?= $(NAN_SDL)/lib/libSDL.a export NAN_SDLCFLAGS ?= -I$(NAN_SDL)/include/SDL + export NAN_FFMPEG ?= $(LCGDIR)/ffmpeg + export NAN_FFMPEGLIBS = $(NAN_FFMPEG)/lib/libavformat.a $(NAN_FFMPEG)/lib/libavcodec.a $(NAN_FFMPEG)/lib/libswscale.a $(NAN_FFMPEG)/lib/libavutil.a $(NAN_FFMPEG)/lib/libogg.a $(NAN_FFMPEG)/lib/libfaad.a $(NAN_FFMPEG)/lib/libmp3lame.a $(NAN_FFMPEG)/lib/libvorbis.a $(NAN_FFMPEG)/lib/libx264.a $(NAN_FFMPEG)/lib/libfaac.a $(NAN_ZLIB)/lib/libz.a + export NAN_FFMPEGCFLAGS ?= -I$(NAN_FFMPEG)/include # Uncomment the following line to use Mozilla inplace of netscape # CPPFLAGS +=-DMOZ_NOT_NET diff --git a/source/nan_link.mk b/source/nan_link.mk index 8dda3b8c2df..186fe07e09a 100644 --- a/source/nan_link.mk +++ b/source/nan_link.mk @@ -72,11 +72,19 @@ ifeq ($(OS),freebsd) endif ifeq ($(OS),irix) - LDFLAGS += -mips3 - LLIBS = -lmovieGL -lGLU -lGL -lXmu -lXext -lX11 -lc -lm -ldmedia - LLIBS += -lcl -laudio -ldb -lCio -lz - LLIBS += -lpthread - LLIBS += -woff 84,171 + ifeq ($(IRIX_USE_GCC), true) + LDFLAGS += -mabi=n32 -mips4 + DBG_LDFLAGS += -LD_LAYOUT:lgot_buffer=40 + else + LDFLAGS += -n32 -mips3 + LDFLAGS += -woff 84,171 + endif + LLIBS = -lmovieGL -lGLU -lGL -lXmu -lXext -lXi -lX11 -lc -lm -ldmedia + LLIBS += -lcl -laudio + ifneq ($(IRIX_USE_GCC), true) + LLIBS += -lCio -ldb + endif + LLIBS += -lz -lpthread DYNLDFLAGS = -shared $(LDFLAGS) endif @@ -90,7 +98,7 @@ ifeq ($(OS),linux) ifeq ($(CPU),$(findstring $(CPU), "i386 x86_64 ia64 parisc64 powerpc sparc64")) COMMENT = "MESA 3.1" LLIBS = -L$(NAN_MESA)/lib -L/usr/X11R6/lib -lXmu -lXext -lX11 -lXi - LLIBS += -lutil -lc -lm -ldl -lpthread + LLIBS += -lutil -lc -lm -ldl -lpthread # LLIBS += -L$(NAN_ODE)/lib -lode LOPTS = -export-dynamic DADD = -lGL -lGLU diff --git a/tools/Blender.py b/tools/Blender.py index 240534d4437..c52bbaa0613 100644 --- a/tools/Blender.py +++ b/tools/Blender.py @@ -190,7 +190,7 @@ def setup_syslibs(lenv): if lenv['OURPLATFORM'] in ('win32-vc', 'win32-mingw','linuxcross'): syslibs += Split(lenv['BF_PTHREADS_LIB']) - syslibs += Split(lenv['LLIBS']) + syslibs += lenv['LLIBS'] return syslibs @@ -476,7 +476,7 @@ class BlenderEnvironment(SConsEnvironment): lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS']) lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS']) if lenv['BF_PROFILE']: - lenv.Append(LINKFLAGS = lenv['BF_PROFILE_FLAGS']) + lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS']) lenv.Append(CPPPATH=includes) if root_build_dir[0]==os.sep or root_build_dir[1]==':': lenv.Append(LIBPATH=root_build_dir + '/lib') diff --git a/tools/btools.py b/tools/btools.py index 66d5ecc6b9a..21ab547b11a 100755 --- a/tools/btools.py +++ b/tools/btools.py @@ -19,13 +19,15 @@ BoolVariable = SCons.Variables.BoolVariable def print_arguments(args, bc): if len(args): for k,v in args.iteritems(): + if type(v)==list: + v = ' '.join(v) print '\t'+bc.OKBLUE+k+bc.ENDC+' = '+bc.OKGREEN + v + bc.ENDC else: print '\t'+bc.WARNING+'No command-line arguments given'+bc.ENDC def validate_arguments(args, bc): opts_list = [ - 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'BF_PYTHON_LINKFLAGS', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', + 'WITH_BF_PYTHON', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', '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_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH', @@ -47,17 +49,11 @@ def validate_arguments(args, bc): 'WITH_BF_YAFRAY', 'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', - 'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'BF_OPENGL_LINKFLAGS', + 'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC', 'WITH_BF_FTGL', 'BF_FTGL', 'BF_FTGL_INC', 'BF_FTGL_LIB', 'WITH_BF_PLAYER', 'WITH_BF_NOBLENDER', 'WITH_BF_BINRELOC', - 'CFLAGS', 'CCFLAGS', 'CXXFLAGS', 'CPPFLAGS', - 'REL_CFLAGS', 'REL_CCFLAGS', 'REL_CXXFLAGS', - 'BF_PROFILE_FLAGS', 'BF_PROFILE_FLAGS', 'BF_PROFILE_CXXFLAGS', - 'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS', - 'C_WARN', 'CC_WARN', 'CXX_WARN', - 'LLIBS', 'PLATFORM_LINKFLAGS', 'LCGDIR', 'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC', 'WITH_BF_VERSE', 'BF_VERSE_INCLUDE', @@ -72,7 +68,20 @@ def validate_arguments(args, bc): 'WITH_BF_DOCS', 'BF_NUMJOBS', ] - + + # Have options here that scons expects to be lists + opts_list_split = [ + 'BF_PYTHON_LINKFLAGS', + 'BF_OPENGL_LINKFLAGS', + 'CFLAGS', 'CCFLAGS', 'CXXFLAGS', 'CPPFLAGS', + 'REL_CFLAGS', 'REL_CCFLAGS', 'REL_CXXFLAGS', + 'BF_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS', + 'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS', + 'C_WARN', 'CC_WARN', 'CXX_WARN', + 'LLIBS', 'PLATFORM_LINKFLAGS', + ] + + arg_list = ['BF_DEBUG', 'BF_QUIET', 'BF_CROSS', 'BF_UPDATE', 'BF_INSTALLDIR', 'BF_TOOLSET', 'BF_BINNAME', 'BF_BUILDDIR', 'BF_FANCY', 'BF_QUICK', 'BF_PROFILE', @@ -81,12 +90,13 @@ def validate_arguments(args, bc): 'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG', 'BF_DOCDIR'] - all_list = opts_list + arg_list okdict = {} for k,v in args.iteritems(): - if k in all_list: + if (k in opts_list) or (k in arg_list): okdict[k] = v + elif k in opts_list_split: + okdict[k] = v.split() # "" have alredy been stripped else: print '\t'+bc.WARNING+'Invalid argument: '+bc.ENDC+k+'='+v @@ -340,6 +350,7 @@ def read_opts(cfg, args): ('BF_PROFILE_CFLAGS', 'C only profiling flags', ''), ('BF_PROFILE_CCFLAGS', 'C and C++ profiling flags', ''), ('BF_PROFILE_CXXFLAGS', 'C++ only profiling flags', ''), + ('BF_PROFILE_LINKFLAGS', 'Profile linkflags', ''), (BoolVariable('BF_DEBUG', 'Add debug flags if true', False)), ('BF_DEBUG_CFLAGS', 'C only debug flags', ''), @@ -544,8 +555,10 @@ def NSIS_Installer(target=None, source=None, env=None): new_nsis = open(tmpnsi, 'w') new_nsis.write(ns_cnt) new_nsis.close() + print "Preparing nsis file looks ok\n" os.chdir(start_dir) + print "try to launch 'makensis' ...make sure it is on the path \n" cmdline = "makensis " + "\""+tmpnsi+"\"" diff --git a/tools/crossmingw.py b/tools/crossmingw.py index 1c8924ca7f6..299bfca929d 100755 --- a/tools/crossmingw.py +++ b/tools/crossmingw.py @@ -109,7 +109,7 @@ def shlib_emitter(target, source, env): #JB """ I'm blindly susbstuting lines from the mingw.py #JB file becase these lines cause python errors here. """ #JB shlib_action = SCons.Action.Action(shlib_generator,generator=1) -shlib_action = SCons.Action.CommandGenerator(shlib_generator) +shlib_action = SCons.Action.CommandGeneratorAction(shlib_generator) res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') |