2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r17434...
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 14 Dec 2008 17:32:24 +0000 (17:32 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 14 Dec 2008 17:32:24 +0000 (17:32 +0000)
82 files changed:
1  2 
SConstruct
config/darwin-config.py
config/irix6-config.py
config/linux2-config.py
config/linuxcross-config.py
config/openbsd3-config.py
config/sunos5-config.py
config/win32-mingw-config.py
config/win32-vc-config.py
extern/Makefile
intern/SoundSystem/Makefile
intern/elbeem/intern/utilities.h
projectfiles_vc9/blender/blender.sln
projectfiles_vc9/blender/nodes/nodes.vcproj
projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
release/Makefile
release/scripts/bpymodules/BPyImage.py
release/scripts/bpymodules/BPyMathutils.py
release/scripts/bpymodules/BPySys.py
release/scripts/export_fbx.py
release/scripts/import_dxf.py
release/scripts/import_web3d.py
source/Makefile
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/node.c
source/blender/blenlib/BLI_linklist.h
source/blender/blenlib/BLI_memarena.h
source/blender/blenlib/SConscript
source/blender/blenlib/intern/BLI_linklist.c
source/blender/blenlib/intern/BLI_memarena.c
source/blender/blenlib/intern/arithb.c
source/blender/blenlib/intern/storage.c
source/blender/blenlib/intern/threads.c
source/blender/blenloader/intern/readfile.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/imageprocess.c
source/blender/makesdna/DNA_customdata_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_scriptlink_types.h
source/blender/makesdna/intern/SConscript
source/blender/nodes/CMakeLists.txt
source/blender/nodes/TEX_node.h
source/blender/nodes/intern/TEX_nodes/TEX_coord.c
source/blender/nodes/intern/TEX_nodes/TEX_distance.c
source/blender/nodes/intern/TEX_util.c
source/creator/creator.c
source/gameengine/BlenderRoutines/Makefile
source/gameengine/GamePlayer/common/unix/Makefile
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_Camera.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/PyDoc/KX_GameObject.py
source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
source/gameengine/Rasterizer/RAS_2DFilterManager.h
source/gameengine/Rasterizer/RAS_FramingManager.h
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
source/gameengine/VideoTexture/Exception.cpp
source/gameengine/VideoTexture/Exception.h
source/gameengine/VideoTexture/ImageRender.cpp
source/gameengine/VideoTexture/ImageRender.h
source/gameengine/VideoTexture/ImageViewport.cpp
source/gameengine/VideoTexture/ImageViewport.h
source/gameengine/VideoTexture/Texture.h
source/gameengine/VideoTexture/blendVideoTex.cpp
source/nan_compile.mk
source/nan_definitions.mk
source/nan_link.mk
tools/Blender.py
tools/btools.py
tools/crossmingw.py

diff --cc SConstruct
@@@ -249,7 -249,7 +249,7 @@@ if len(B.quickdebug) > 0 and printdebu
  # 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 -421,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 = []
                        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':
                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 = []
@@@ -216,14 -216,14 +216,14 @@@ CXXFLAGS = [ '-pipe','-fPIC','-funsigne
  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,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
index 0000000,0000000..b643aff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
@@@ -193,12 -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']
@@@ -1,4 -1,4 +1,4 @@@
--LCGDIR = '../lib/windows'
++LCGDIR = '#../lib/windows'
  LIBDIR = '${LCGDIR}'
  
  WITH_BF_VERSE = False
@@@ -101,6 -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 -146,6 +149,10 @@@ LLIBS = [ '-ldxguid', '-lgdi32', '-lmsv
  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'
@@@ -151,12 -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']
@@@ -165,11 -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
@@@ -164,8 -164,7 +164,9 @@@ LLIBS = ['-lshell32', '-lshfolder', '-l
  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
  
  BF_BUILDDIR = '..\\build\\win32-mingw'
@@@ -181,10 -181,22 +181,15 @@@ C_WARN = [
  CC_WARN = []
  CXX_WARN = []
  
--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
 -                   '''
++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 --cc extern/Makefile
@@@ -57,10 -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
@@@ -47,6 -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
@@@ -154,12 -154,12 +154,18 @@@ int writePng(const char *fileName, unsi
   */
  
  /* 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 )
@@@ -154,6 -151,6 +154,7 @@@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C
                {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292}\r
                {670EC17A-0548-4BBF-A27B-636C7C188139} = {670EC17A-0548-4BBF-A27B-636C7C188139}\r
                {4C3AB78A-52CA-4276-A041-39776E52D8C8} = {4C3AB78A-52CA-4276-A041-39776E52D8C8}\r
++              {E784098D-3ED8-433A-9353-9679415DDDC5} = {E784098D-3ED8-433A-9353-9679415DDDC5}\r
                {6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC}\r
                {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}\r
                {76D90B92-ECC7-409C-9F98-A8814B90F3C0} = {76D90B92-ECC7-409C-9F98-A8814B90F3C0}\r
                {E90C7BC2-CF30-4A60-A8F2-0050D592E358} = {E90C7BC2-CF30-4A60-A8F2-0050D592E358}\r
                {8B8D4FC3-3234-4E54-8376-5AB83D00D164} = {8B8D4FC3-3234-4E54-8376-5AB83D00D164}\r
                {4B6AFCC5-968C-424A-8F20-76E41B3BEF74} = {4B6AFCC5-968C-424A-8F20-76E41B3BEF74}\r
++              {0112CAD5-3584-412A-A2E5-1315A00437B4} = {0112CAD5-3584-412A-A2E5-1315A00437B4}\r
                {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA} = {5A2EA6DC-1A53-4E87-9166-52870CE3B4EA}\r
                {E86B7BDE-C33C-4E55-9433-E74C141D7538} = {E86B7BDE-C33C-4E55-9433-E74C141D7538}\r
                {32CC75E2-EE85-45E6-8E3D-513F58464F43} = {32CC75E2-EE85-45E6-8E3D-513F58464F43}\r
                {9A307EE5-CD77-47BC-BD87-62508C7E19D8} = {9A307EE5-CD77-47BC-BD87-62508C7E19D8}\r
                {AB590CED-F71F-4A17-A89B-18583ECD633D} = {AB590CED-F71F-4A17-A89B-18583ECD633D}\r
++              {B83C6BED-11EC-46C8-AFFA-121EEDE94373} = {B83C6BED-11EC-46C8-AFFA-121EEDE94373}\r
                {1CC733F1-6AB5-4904-8F63-C08C46B79DD9} = {1CC733F1-6AB5-4904-8F63-C08C46B79DD9}\r
                {B789C2F3-279E-4A85-8F0A-7F7AC068E598} = {B789C2F3-279E-4A85-8F0A-7F7AC068E598}\r
++              {524264F4-DF21-4B79-847F-E7CA643ECD0B} = {524264F4-DF21-4B79-847F-E7CA643ECD0B}\r
        EndProjectSection\r
  EndProject\r
  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KX_blenderhook", "..\gameengine\blenderhook\KX_blenderhook.vcproj", "{8154A59A-CAED-403D-AB94-BC4E7C032666}"\r
@@@ -944,43 -621,19 +948,49 @@@ Globa
                {0112CAD5-3584-412A-A2E5-1315A00437B4}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {0112CAD5-3584-412A-A2E5-1315A00437B4}.Blender Release|Win32.Build.0 = Blender Release|Win32\r
                {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32\r
++              {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32\r
                {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32\r
++              {0112CAD5-3584-412A-A2E5-1315A00437B4}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32\r
 +              {0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {0112CAD5-3584-412A-A2E5-1315A00437B4}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {0112CAD5-3584-412A-A2E5-1315A00437B4}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {0112CAD5-3584-412A-A2E5-1315A00437B4}.Release|Win32.Build.0 = 3D Plugin Release|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.3D Plugin Release|Win32.Build.0 = 3D Plugin Release|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Debug|Win32.Build.0 = Blender Debug|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Blender Release|Win32.Build.0 = Blender Release|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32\r
++              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32\r
                {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32\r
++              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {B83C6BED-11EC-46C8-AFFA-121EEDE94373}.Release|Win32.Build.0 = 3D Plugin Release|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.3D Plugin Release|Win32.Build.0 = 3D Plugin Release|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Debug|Win32.Build.0 = Blender Debug|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Blender Release|Win32.Build.0 = Blender Release|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32\r
++              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32\r
                {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32\r
++              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {524264F4-DF21-4B79-847F-E7CA643ECD0B}.Release|Win32.Build.0 = 3D Plugin Release|Win32\r
 +              {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.3D Plugin Release|Win32.Build.0 = 3D Plugin Release|Win32\r
                {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32\r
                {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Blender Debug|Win32.Build.0 = Blender Debug|Win32\r
                {D696C86B-0B53-4471-A50D-5B983A6FA4AD}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Blender Release|Win32.Build.0 = Blender Release|Win32\r
                {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32\r
++              {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32\r
                {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32\r
                {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32\r
 +              {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Debug|Win32.ActiveCfg = 3D Plugin Debug|Win32\r
 +              {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Debug|Win32.Build.0 = 3D Plugin Debug|Win32\r
 +              {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Release|Win32.ActiveCfg = 3D Plugin Release|Win32\r
 +              {6461F05D-4698-47AB-A8E8-1CA2ACC9948B}.Release|Win32.Build.0 = 3D Plugin Release|Win32\r
 +              {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.3D Plugin Debug|Win32.ActiveCfg = Blender Release|Win32\r
 +              {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.3D Plugin Debug|Win32.Build.0 = Blender Release|Win32\r
 +              {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.3D Plugin Release|Win32.ActiveCfg = Blender Release|Win32\r
 +              {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.3D Plugin Release|Win32.Build.0 = Blender Release|Win32\r
                {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32\r
                {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.Blender Debug|Win32.Build.0 = Blender Debug|Win32\r
                {531D4862-D0E7-4B9B-A0B6-B3A6A25B547A}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {E784098D-3ED8-433A-9353-9679415DDDC5}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                {E784098D-3ED8-433A-9353-9679415DDDC5}.Blender Release|Win32.Build.0 = Blender Release|Win32\r
                {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Debug|Win32.ActiveCfg = Blender Debug|Win32\r
++              {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Debug|Win32.Build.0 = Blender Debug|Win32\r
                {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Release|Win32.ActiveCfg = Blender Release|Win32\r
++              {E784098D-3ED8-433A-9353-9679415DDDC5}.BlenderPlayer Release|Win32.Build.0 = Blender Release|Win32\r
 +              {E784098D-3ED8-433A-9353-9679415DDDC5}.Debug|Win32.ActiveCfg = 3DPlugin Debug|Win32\r
 +              {E784098D-3ED8-433A-9353-9679415DDDC5}.Debug|Win32.Build.0 = 3DPlugin Debug|Win32\r
 +              {E784098D-3ED8-433A-9353-9679415DDDC5}.Release|Win32.ActiveCfg = 3DPlugin Release|Win32\r
 +              {E784098D-3ED8-433A-9353-9679415DDDC5}.Release|Win32.Build.0 = 3DPlugin Release|Win32\r
 +              {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.3D Plugin Debug|Win32.ActiveCfg = 3DPlugin Debug|Win32\r
 +              {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.3D Plugin Debug|Win32.Build.0 = 3DPlugin Debug|Win32\r
 +              {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.3D Plugin Release|Win32.ActiveCfg = 3DPlugin Debug|Win32\r
 +              {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.3D Plugin Release|Win32.Build.0 = 3DPlugin Debug|Win32\r
                {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.Blender Debug|Win32.ActiveCfg = Blender Debug|Win32\r
                {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.Blender Debug|Win32.Build.0 = Blender Debug|Win32\r
                {EB75F4D6-2970-4A3A-8D99-2BAD7201C0E9}.Blender Release|Win32.ActiveCfg = Blender Release|Win32\r
                                        RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_checker.c"\r
                                        >\r
                                </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_coord.c"\r
++                                      >\r
++                              </File>\r
                                <File\r
                                        RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_curves.c"\r
                                        >\r
                                </File>\r
++                              <File\r
++                                      RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_distance.c"\r
++                                      >\r
++                              </File>\r
                                <File\r
                                        RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_hueSatVal.c"\r
                                        >\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;"\r
--                              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"\r
++                              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"\r
                                ShowProgress="0"\r
                                OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"\r
                                LinkIncremental="2"\r
                                SuppressStartupBanner="true"\r
--                              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"\r
++                              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"\r
                                IgnoreDefaultLibraryNames="libc.lib;libcmt.lib;msvcrt.lib;libcd.lib;msvcrtd.lib"\r
                                GenerateDebugInformation="true"\r
                                ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\debug\blenderplayer.pdb"\r
                        <Tool\r
                                Name="VCLinkerTool"\r
                                AdditionalOptions="/MACHINE:I386"\r
--                              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"\r
++                              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"\r
                                OutputFile="..\..\..\..\bin\blenderplayer.exe"\r
                                LinkIncremental="1"\r
                                SuppressStartupBanner="true"\r
--                              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"\r
++                              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"\r
                                IgnoreDefaultLibraryNames="libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib"\r
                                ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\blenderplayer.pdb"\r
                                SubSystem="1"\r
@@@ -57,6 -57,6 +57,12 @@@ ifeq ($(OS),$(findstring $(OS), "freebs
         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)
@@@ -79,7 -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.
        
        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
@@@ -225,15 -225,15 +225,5 @@@ from math import pi, sin, cos, sqr
  
  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));
@@@ -12,3 -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.
@@@ -66,8 -66,8 +66,6 @@@ import BPyMes
  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 -184,7 +182,19 @@@ def sane_texname(data):           return sane_na
  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 -342,6 +352,8 @@@ def write(filename, batch_objects = Non
        
        # end batch support
        
++      # Use this for working out paths relative to the export location
++      basepath = Blender.sys.dirname(filename)
        
        # ----------------------------------------------
        # storage classes
                        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)
                
                
                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}')
  
        
                }''')
                
                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 -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
@@@ -7,7 -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,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
  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 -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()
                psyco.profile(0.2)
                #print 'psyco imported'
  except ImportError:
--      #print 'psyco not imported'
++      print 'psyco not imported'
        pass
  
  #try: Curve.orderU
@@@ -346,7 -346,7 +349,7 @@@ THIN_RESOLUTION = 8   #(4-64) thin_cyli
  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 -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 -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:
                                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:
                                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
                                        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 #-----
                                        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
  
  
  
                                                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 #---------
                                                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
                                                        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] #----------
                                        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 -2177,9 +2196,10 @@@ DXF: X value; APP: 3D point, Y and Z va
                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 -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)
                                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 -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 -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
                                        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 -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 -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:
                #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 -5190,6 +5215,7 @@@ def drawCurveCircle(circle):  #--- no m
        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 -5231,6 +5257,7 @@@ def drawCurveArc(self):  #---- only fo
        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 -5270,12 +5297,12 @@@ GUI_B = {}  # GUI-buttons dictionary fo
  # 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 -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
                                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 -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."
@@@ -48,6 -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 -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
        
        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#')
        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 -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
                
                # 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
                        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
                except:
                        return None
        
++      def getPrefix(self):
++              if self.id:
++                      return self.id[0]
++              return None
++      
        def getDefName(self):
                self_real = self.getRealNode()
                
                
                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)
                                        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
                # We requested a flat array
                if group == 0:
                        return flat_array
--                      
--                      
                
                new_array = []
                sub_array = []
                
                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
                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]
                
                # 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(): 
                                        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
                                                        
                                                        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
                                        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 -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, [])
        # Parse recursively
        root.parse(0)
        
--      # print root
++      # This prints a load of text
++      '''
++      print root
++      '''
++      
        return root, ''
  
++
  # ====================== END VRML 
  
  
@@@ -996,6 -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 -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 -1343,7 +1521,8 @@@ def importMesh_IndexedFaceSet(geom, bpy
                                        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 -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'
                        
                        
                        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')
                                                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
                                # 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 -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 -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 -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):
        
                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 -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 --cc source/Makefile
@@@ -194,7 -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 -395,9 +417,16 @@@ els
          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
@@@ -53,6 -53,6 +53,7 @@@ int brush_clone_image_delete(struct Bru
  
  /* 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);
@@@ -198,8 -198,8 +198,12 @@@ int CustomData_get_layer_index(const st
  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 -227,10 +231,14 @@@ void *CustomData_set_layer_n(const stru
  /* 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);
@@@ -401,6 -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
@@@ -328,6 -328,6 +328,23 @@@ float brush_sample_falloff(Brush *brush
                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];
@@@ -833,7 -833,7 +833,6 @@@ void makeNurbcurve(Nurb *nu, float *coo
        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 -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);
@@@ -606,7 -606,7 +606,7 @@@ void CustomData_merge(const struct Cust
  {
        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];
                        number = 0;
                        lastactive = layer->active;
                        lastrender = layer->active_rnd;
++                      lastclone = layer->active_clone;
++                      lastmask = layer->active_mask;
                        lasttype = type;
                }
                else
                if(newlayer) {
                        newlayer->active = lastactive;
                        newlayer->active_rnd = lastrender;
++                      newlayer->active_clone = lastclone;
++                      newlayer->active_mask = lastmask;
                }
        }
  }
@@@ -736,6 -736,6 +740,28 @@@ int CustomData_get_render_layer_index(c
        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 -758,6 +784,27 @@@ int CustomData_get_render_layer(const C
        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 -777,6 +824,24 @@@ void CustomData_set_layer_render(Custom
                        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 -796,6 +861,23 @@@ void CustomData_set_layer_render_index(
                        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 -882,9 +964,13 @@@ static CustomDataLayer *customData_add_
        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 -944,6 +1030,8 @@@ int CustomData_free_layer(CustomData *d
                        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--;
                        }
        }
  
@@@ -890,7 -887,7 +890,6 @@@ static void curve_to_displist(Curve *cu
                        }
                        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 -1381,7 +1383,7 @@@ void makeDispListSurf(Object *ob, ListB
        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");
@@@ -2886,6 -2886,6 +2886,8 @@@ static void registerTextureNodes(ListBa
        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);
@@@ -45,6 -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);
  
@@@ -50,6 -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);
@@@ -23,7 -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 )
@@@ -50,6 -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;
        
@@@ -60,6 -60,6 +60,10 @@@ void BLI_memarena_use_calloc(MemArena *
        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);
@@@ -1351,8 -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)
@@@ -47,9 -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 +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;
        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
@@@ -42,7 -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>
@@@ -8258,14 -8006,6 +8258,24 @@@ static void do_versions(FileData *fd, L
                        }
                }
        }
 +
++      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;
 +              
 +              for(screen= main->screen.first; screen; screen= screen->id.next)
 +                      do_versions_windowmanager_2_50(screen);
 +      }
 +      
        
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
@@@ -403,9 -403,9 +403,14 @@@ void IMB_convert_rgba_to_abgr(struct Im
   *
   * @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.
@@@ -80,6 -80,6 +80,17 @@@ void IMB_convert_rgba_to_abgr(struct Im
                }
        }
  }
++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 
  /*  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));
                                        /* 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;
                        }
                }
        }
--      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;
        }
  }
  
++
++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);
        // 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;
                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;
        }
  }
  
++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;
                }
        } 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];
                }
        }       
  }
++
++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);
++}
@@@ -37,6 -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 */
@@@ -344,7 -345,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 -799,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 */
@@@ -65,10 -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
@@@ -18,9 -18,9 +18,15 @@@ makesdna_tool.Append (CPPPATH = ['#/int
                                                                 '../../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 -30,7 +36,7 @@@ if not (root_build_dir[0]==os.sep or ro
        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,8 -43,8 +49,11 @@@ 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'
 +obj = ['intern/dna.c', 'intern/dna_genfile.c']
  Return ('obj')
  #
  # ***** 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 ../include ../blenlib ../makesdna
 +  . ../../../intern/guardedalloc ../editors/include ../blenlib ../makesdna
    ../python ../render/extern/include ../../../intern/decimation/extern
    ../imbuf ../avi ../../../intern/elbeem/extern
    ../../../intern/iksolver/extern ../blenloader ../quicktime
@@@ -52,6 -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;
index 0000000,0000000..da487c1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++};
++
index 0000000,0000000..ff9ec4d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++};
++
++
@@@ -46,25 -46,25 +46,32 @@@ void tex_call_delegate(TexDelegate *dg
        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 -83,8 +90,8 @@@ float tex_input_value(bNodeStack *in, f
  
  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;
  #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 -201,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");
@@@ -35,6 -35,6 +35,7 @@@ include nan_compile.m
  
  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    
@@@ -35,6 -35,6 +35,7 @@@ include nan_compile.m
  
  CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
  
++CPPFLAGS += -I$(NAN_GLEW)/include
  CPPFLAGS += -I$(OPENGL_HEADERS)
  CPPFLAGS += -I$(NAN_STRING)/include    
  
@@@ -185,7 -185,7 +185,8 @@@ void       KX_BulletPhysicsController::Suspen
                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 -204,7 +205,7 @@@ void       KX_BulletPhysicsController::Restor
                        m_savedCollisionFlags,
                        m_savedCollisionFilterGroup,
                        m_savedCollisionFilterMask);
--              GetRigidBody()->forceActivationState(ACTIVE_TAG);
++              GetRigidBody()->forceActivationState(m_savedActivationState);
        }
  }
  
@@@ -9,6 -9,6 +9,7 @@@ class KX_BulletPhysicsController : publ
  {
  private:
        int m_savedCollisionFlags;
++      int m_savedActivationState;
        short int m_savedCollisionFilterGroup;
        short int m_savedCollisionFilterMask;
        MT_Scalar m_savedMass;
@@@ -259,10 -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;
        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()]);
@@@ -615,6 -615,6 +615,7 @@@ void KX_GameObject::setAngularVelocity(
                m_pPhysicsController1->SetAngularVelocity(ang_vel,local);
  }
  
++
  void KX_GameObject::ResolveCombinedVelocities(
        const MT_Vector3 & lin_vel,
        const MT_Vector3 & ang_vel,
@@@ -969,6 -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 -1261,6 +1266,65 @@@ int KX_GameObject::_setattr(const STR_S
        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)
  {
@@@ -772,6 -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);
@@@ -184,7 -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:
        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);
        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();
@@@ -1249,7 -1249,7 +1249,7 @@@ void KX_Scene::MarkVisible(RAS_IRasteri
        // 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.
@@@ -123,6 -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.
                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
                """
                Sets the game object's angular velocity.
                
++              This requires a dynamic object.
++              
                @type velocity: 3d vector.
                @param velocity: angular velocity vector.
                @type local: boolean
@@@ -58,7 -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 +217,50 @@@ void RAS_2DFilterManager::StartShaderPr
        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 +332,20 @@@ void RAS_2DFilterManager::UpdateOffsetM
        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;
        }
  }
  
++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;
        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);
  
                        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 -454,7 +474,7 @@@ void RAS_2DFilterManager::EnableFilter(
                return;
        if(pass<0 || pass>=MAX_RENDER_PASS)
                return;
--
++      need_tex_update = true;
        if(mode == RAS_2DFILTER_DISABLED)
        {
                m_enabled[pass] = 0;
@@@ -44,7 -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 -60,6 +62,7 @@@
  
        bool                    isshadersupported;
        bool                    errorprinted;
++      bool                    need_tex_update;
  
        unsigned int    m_filters[MAX_RENDER_PASS];
        short           m_enabled[MAX_RENDER_PASS];
@@@ -212,9 -212,9 +212,6 @@@ public 
                RAS_FrameFrustum &frustum
        );
  
--
--private :
--
        static
                void
        ComputeDefaultFrustum(
                RAS_FrameFrustum & frustum
        );      
  
++private :
++
        static
                void
        ComputeBestFitViewRect(
@@@ -200,6 -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.
@@@ -406,14 -406,14 +406,16 @@@ void RAS_OpenGLRasterizer::SetRenderAre
                        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 -775,7 +777,7 @@@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetF
        float frustnear,
        float frustfar,
        float focallength,
--      bool
++      bool 
  ){
        MT_Matrix4x4 result;
        double mat[16];
@@@ -137,6 -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);
@@@ -204,6 -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();
  }
@@@ -202,6 -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;
  
@@@ -24,96 -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 -174,26 +316,31 @@@ static int ImageRender_init (PyObject 
  // 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 -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 -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
@@@ -42,42 -42,42 +42,56 @@@ class ImageRender : public ImageViewpor
  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);
@@@ -34,12 -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 +62,7 @@@ void ImageViewport::setWhole (bool whol
                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,20 +123,31 @@@ void ImageViewport::calcImage (unsigne
                && 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 -151,14 +162,14 @@@ inline ImageViewport * getImageViewpor
  
  
  // 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))
        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 -202,14 +235,14 @@@ static int ImageViewport_setPosition (P
  }
  
  // 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 -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},
@@@ -43,6 -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 -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];
        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
  
@@@ -32,6 -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 -82,5 +83,10 @@@ RAS_IPolyMaterial * getMaterial (PyObje
  // get material ID
  short getMaterialID (PyObject * obj, char * name);
  
++// Exceptions
++extern ExceptionID MaterialNotAvail;
++
++// object type
++extern BlendType<KX_GameObject> gameObjectType;
  
  #endif
@@@ -132,6 -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 -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");
@@@ -120,22 -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)